Lesson 7 of 10
Vectors with metatables
- 13 min
- 6 checks
- 3 hints
- Go to task
Goal
Write pos + vel * dt just like in math
Explanation
Position, velocity and force in a 2D game are all x, y pairs, and when you write them as separate numbers, you end up writing every line twice: x = x + vx * dt, and then the same again for y. A metatable teaches a table how to handle arithmetic. If you define __add in it, a + b becomes a call to that function, and you can write pos = pos + vel * dt just like in math. That's how Vector2 works in Roblox and vector2 in FiveM.
__mul is called whichever side the number is on: for v * 2 it receives (v, 2), and for 2 * v it receives (2, v), so check which operand is the number. Every operation returns a new vector and leaves both operands untouched. Otherwise the original position would move every time you computed a point from it.
Watch out in normalize. Dividing the zero vector by its length is 0 / 0, which in Lua doesn't throw an error but gives NaN. The NaN spreads into the position, every comparison with it is false, and the entity vanishes from the map and never collides with anything. So check the length, and if it's zero, return a zero vector.
Your task
Complete Vector2 with the __add and __sub operations, a __mul operation that multiplies a vector by a number on either side, and the functions length(), normalize() and Vector2.distance(a, b). normalize() returns a vector of length one, or a zero vector if the original is the zero vector. Every function that returns a vector returns a new one with the same metatable.
Checks
6 checks- Addition with + and subtraction with - work on x and y separately
- Multiplying by a number works from both sides
- The result is a new vector and the original doesn't change
- The length and distance functions give the right results
- The result of normalize has length one and the same direction
- The normalize function returns a zero vector for the zero vector, not NaN