I've been doing a lot of writing games in Löve. Writing games usually involves a lot of code that deals with positions and directions and velocities. To make this easier to write, I made a little library to represent a point in a two-dimensional coordinate space.
This is a little different for posts here because I'm not going to go into the code too much; I'm just going to show some examples of how to use it. Really, the motivation here is that I want to make other posts with code examples that use this, and so I should document it. Next up, my "map" class.
If you just want the code, the canonical repository is here.
First, the library is in one file, that I call point.lua. You can require it like any other module:
local point = require('point')
To create a point, you can call point.new:
p = point.new(2, 3)
Or use the shorthand of just calling the module:
p = point(2, 3)
Getting the components of the point is easy enough:
p = point(2, 3)
assert(p.x == 2)
assert(p.y == 3)
It also intelligently handles equality:
p = point(2, 3)
p2 = point(2, 3)
assert(p == p2)
And can be converted to a string:
p = point(2, 3)
assert( tostring(p) == "(2, 3)" )
print(p) -- prints (2, 3)
Points can be added and subtracted:
p = point(2, 3)
p2 = point(1, 1)
assert( p + p2 == point(3, 4) )
assert( p2 - p == point(-1, -2) )
They can also be multiplied, by points or numbers:
p = point(2, 3)
assert( p * point(-1, 0) == point(-2, 0) )
assert( p * 2 == point(4, 6) )
Points whose components are both integers, like coordinates on a tile map, have some useful methods:
Returns whether two points are next to each other, not counting diagonals:
p = point(2, 3)
assert( p:adjacent(point(2, 2)) )
assert( not p:adjacent(p) )
Returns whether two points are on the same row or column:
p = point(2, 3)
assert( p:ortho(point(2, 2)) )
assert( not p:ortho(point(0, 0)) )
If two points are on the same row or column, returns a new point representing the direction you have to move to get closer to the second one. For example, for these three points:
..........
..........
...A...B..
..........
..........
..........
...C......
..........
..........
a:toward(b) -- returns point(1, 0)
b:toward(a) -- returns point(-1, 0)
a:toward(c) -- returns point(0, 1) assuming +y is downward
b:toward(c) -- raises an error!
Comparing two points means comparing both components:
p = point(2, 3)
p2 = point(5, 6)
p3 = point(2, 4)
assert( p < p2 )
assert( p <= p3 )
assert( p2 > p3 )
There are a few constants defined:
assert( point.up == point(0, -1) )
assert( point.east == point(1, 0) )
Up, down, left, right, north, south, east, and west are all there, and they assume that going downward means an increase in Y (which is how Löve coordinates work).
I'll probably be making changes and additions to the class periodically as I need things. The canonical repository is here and I'll try to update this post when I add stuff.