collision:
Point to Point
The simplest form of collision detection. Two points collide only when they occupy the exact same space. Their positions are known by their X and Y coordinates and we know they occupy the same space when their x's are equal and their y's are equal at the same time.
No Collision
PICO-8 Collision Function
function point_point_collision( p1, p2 )
return p1.x==p2.x and p1.y==p2.y
end
Comparing Coordinates
First, we need an easy way to store the coordinates of 2 points on the screen. We can do that with 4 different variables, or even better as 2 tables that store separate X and Y variables. Those tables, named p1
and p2
are what the above function expects.
They would be created like this:
--create 2 points as object tables
p1 = { x=10, y=20 }
p2 = { x=30, y=40 }
Now that we have 2 points, each with coordinates X
and Y
, we can compare them. To get the value of point 1's x
, we use p1.x
. (See Table Shorthand)
--get value out of point table
print( p1.x ) --prints 10
We want to compare point 1's X with point 2's X, and point 1's Y with point 2's Y. In expanded form, this check can be written as:
--compare x
if p1.x == p2.x then print("same x") end
--compare y
if p1.y == p2.y then print("same y") end
We can do both of those checks at the same time using the and operator:
--compare x and y
if p1.x == p2.x
and p1.y == p2.y then
print("same position")
end

Understanding an Expanded Version
Now that we have 2 points, with coordinates, and we know how to compare them, we can put it all together into an expanded function like this:
--expanded example
function point_point_collision(p1,p2)
if p1.x == p2.x
and p1.y == p2.y then
return true
else
return false
end
end
This function has parameters (p1,p2)
and it is expecting those to be objects with X and Y keys.
The function has 1 if statement that compares the first point's X with the second point's X to check if they are exactly equal. It does the same, comparing the first point's Y with the second point's Y. The and
is used to make sure that both of those checks are true before running the code inside: return true
, which will send the value true
back to where this function was called.
If one or both of those checks are false
, then the code after else
will run, which will return the value false
instead.
You can call this function in two ways to catch the returned true or false result:
--catch result in variable
is_colliding = point_point_collision( p1, p2 )
if is_colliding then
print("collided!")
end
--directly inside of if statement
if point_point_collision( p1, p2 ) then
print("collided!")
end
Note that these examples use the same argument names as parameter names just for the convenience of this tutorial, but to make the difference clear, this is how the parameters of the function still uses (p1,p2)
but the arguments when calling the function could be any object table such as:
player = { x=10, y=20 }
enemy = { x=30, y=40 }
if point_point_collision( player, enemy ) then
print("collided!")
end
(See more examples below in When to Use this?)

Understanding the Simplified Version
We can simplify and condense the expanded version down to a single line:
function point_point_collision(p1, p2)
return p1.x==p2.x and p1.y==p2.y
end
This works the exact same way because the comparisons of p1.x==p2.x and p1.y==p2.y
will result in either true or false the same way it does in an if statement. So we don't need the if statement at all.
The expanded function boils down to "if both true, return true, and if either false, return false" which is an unnecessary step to explicitly return true or false since what we want to return is the same as the result of the comparisons.
So we can just return
the result of the comparisons immediately in a single step and it does the same thing. Compare the Xs and the Ys, then just return the result.

Point to Point Collision can be used in low graphics games where the game objects are represented by single pixels. Classic arcade games such as Snake is a good example where you only care about the head of the snake colliding with either the food pellet or the body.
snake = { x=10, y=20 }
food = { x=50, y=70 }
if point_point_collision( snake, food ) then
score+=1
end
Another example could be a more complicated game visually, but still very simple in terms of where game objects are placed on the screen. Tactical games where everything is placed always on a grid means that you can check collision of the coordinates where the objects are placed instead of checking for overlapping rectangles.
Here is a mockup of a tactical tank game. Each tank and city is drawn with 16x16 sprites but their placement is always on the grid of tiles over top of and after drawing the grassy map. Their sprites are drawn starting from the top left corner of the sprite, which is a single point. We can therefore check if two tanks are overlapping or if a tank occupies a city by comparing only those two points.
blue_1 = { x=10, y=20 }
red_1 = { x=50, y=70 }
city_1 = { x=20, y=80 }
if point_point_collision( blue_1, city_1 ) then
--blue captures city
end

46
7 Apr 2025