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




40

21 Apr 2025

Font