collision:
Color Detection
One of the simplest forms of collision detection is simply color detection. You just check what color pixel is on the screen ahead of where the player or game object is about to move to, and do something based on what color that is.
No Collision
PICO-8 Collision Function
function color_collision(x,y,c)
return pget(x,y) == c
end
Preparing Coordinates
First, we need an easy way to store the coordinates of a point for the player or other game object that is moving. We can do that with a table that stores X, and Y, variables. The above function expects to get coordinates X and Y, and a color C. It will then check what color pixel is at those coordinates and compare it with the color given.
The player, as a point, could be created like this:
--create object table
p = { x=10, y=20 }
To get the values out of that table, we use p.x
(See Table Shorthand).
--get values out of object table
print( p.x ) --prints 10
Understanding PGET( )
PICO-8 has a built-in function for getting the color of a pixel on the screen.
pget( x, y )
x | the distance from the left side of the screen. |
y | the distance from the top side of the screen. |
This function will return the color number (0-15) of a single pixel currently drawn at the (x,y) coordinates specified. If you request a pixel that is outside of the screen, then pget
will return 0 (zero).
We can compare the pget(x,y)
color with any color number to know if the color we choose matches the pixel on the screen.
c = pget(x,y)
if c == 8 then print("it is red") end

Understanding an Expanded Version
We can write the same tiny function at the top of the page in a way where we break down each step:
function color_collision(x,y,c)
local target = pget(x,y)
if target == c then
return true
else
return false
end
end
This function has parameters (x,y,c)
and it is expecting those to be numbers. X and Y should be somewhere on screen (0 -127) and the C should be one of the color numbers (0-15).
Step 1: get the target pixel's color with pget
.
Step 2: compare the target pixel's color with the color number given to this function as c
.
Step 3: if the colors match, then return true, otherwise, return false.

Understanding the Simplified Version
We can simplify and condense the expanded version down to just one line:
function color_collision(x,y,c)
return pget(x,y) == c
end
This works the exact same way as the expanded version because all the steps of getting the target's color, comparing it to a specific color, and returning true or false all happen in this one line.
The first way we condensed the code is to skip saving the target's color in a local variable. We immediately compare the color returned by pget
with the color given in c
.
pget(x,y) == c
The second trick to condense it is to simply return the result of the comparison. It will get the color with pget
first, then compare those results with the color given c
, then return
the comparison's result of true
or false
.
return pget(x,y) == c
How to use it?
Honestly, it's so simple you don't even need the function to do this type of color detection. You could just place the comparison right in an if statement. It's up to you to decide and customize it to make it easier to use in your specific game and with your style of writing.
Here's how we could use it to check multiple colors by using the function:
if color_collision(p.x,p.y,8) then
print("red")
elseif color_collision(p.x,p.y,12) then
print("blue")
end
Here's how we could do the same thing without the function:
if pget(p.x,p.y) == 8 then
print("red")
elseif pget(p.x,p.y) == 12 then
print("blue")
end
The real benefit of using color detection as a function (which you can rename shorter) is that it is easier to read and understand what the code is doing instead of seeing the comparison of pget
with a number and have to remember what that means.

Collision through color detection can be used in very simple games and works well in the ultra low resolution arcade classics such as Pong, Frogger, and Adventure.
Here is a good idea for one of the first games you make in PICO-8, a maze. Simply learn how to control a player as a single pixel, navigating through a hand drawn maze and use the colors of the floor and walls to allow or not allow the player to move there.
--init
player = { x=64, y=64 }
wall = 3 --dark green
--update
if color_collision( player.x, player.y, wall ) then
--cannot move here
end
Sometimes you can simplify a larger sprite down to a single point near its center. A classic example is the Light Cycle minigame from Tron. The cycles can be sprites and single pixels of a certain color are placed behind them. All you need to do for collision in this game is to detect the color of the pixel in front of your light cycle and check if it is either of the trail colors, in which case you explode.
--init
player = { x=64, y=64 }
enemy = { x=64, y=64 }
floor = 0 --black
wall = 1 --dark blue
player_trail = 12 --blue
enemy_trail = 10 --yellow
--update
if color_collision( player.x, player.y, floor ) then
--can move here
elseif color_colision( player.x, player.y, player_trail )
or color_colision( player.x, player.y, enemy_trail ) then
--crash
end

43
21 Apr 2025