UNDER CONSTRUCTION
PICO-8
Let's continue from where we left off with a bouncing ball and add a paddle you can move. First draw yourself up a paddle using Sprite 002
and 018
.
Next, let's add some code to draw and move our paddle up and down.
-- ball properties
ball_x = 0 -- x position
ball_y = 0 -- y position
x_speed = 2 -- x speed
y_speed = 1.5 -- y speed
-- player paddle properties
paddle_x = 0
paddle_y = 60
paddle_speed = 3
-- update function
function _update()
-- update ball position
ball_x = ball_x + x_speed
ball_y = ball_y + y_speed
-- left or right side
if ball_x < 0 or ball_x > 119 then
-- reverse x direction
x_speed = x_speed * -1
end
-- top or bottom side
if ball_y < 0 or ball_y > 119 then
-- reverse y direction
y_speed = y_speed * -1
end
-- move paddle up and down
if btn(2) then
paddle_y = paddle_y - paddle_speed
end
if btn(3) then
paddle_y = paddle_y + paddle_speed
end
end
-- draw function
function _draw()
-- clear the screen
cls()
-- draw the ball
spr(1, ball_x, ball_y)
-- draw the paddle
spr(2, paddle_x, paddle_y)
spr(18, paddle_x, paddle_y + 8)
end
Now you can move the paddle up and down using the arrow keys!
The ball just passes through the paddle. We will have to check when they are touching to have the ball bounce off the paddle.
-- update function
function _update()
-- update ball position
ball_x = ball_x + x_speed
ball_y = ball_y + y_speed
-- left or right side
if ball_x < 0 or ball_x > 119 then
-- reverse x direction
x_speed = x_speed * -1
end
-- top or bottom side
if ball_y < 0 or ball_y > 119 then
-- reverse y direction
y_speed = y_speed * -1
end
-- move player paddle up and down
if btn(0) then
paddle_y = paddle_y - paddle_speed
end
if btn(1) then
paddle_y = paddle_y + paddle_speed
end
-- player paddle collision
if ball_x < paddle_x + 8 and
ball_x > paddle_x and
ball_y > paddle_y and
ball_y < paddle_y + 16 then
x_speed = -x_speed
ball_x = ball_x + x_speed
end
end
Next, we'll add an enemy paddle on the right side of the screen that moves slower than the player's paddle. The enemy paddle will be composed of sprites 4 and 5 stacked vertically.
-- ball properties
ball_x = 0 -- x position
ball_y = 0 -- y position
x_speed = 2 -- x speed
y_speed = 1.5 -- y speed
-- player paddle properties
paddle_x = 10
paddle_y = 60
paddle_speed = 3
-- enemy paddle properties
enemy_paddle_x = 110
enemy_paddle_y = 60
enemy_paddle_speed = 1.5
-- update function
function _update()
-- update ball position
ball_x = ball_x + x_speed
ball_y = ball_y + y_speed
-- left or right side
if ball_x < 0 or ball_x > 119 then
-- reverse x direction
x_speed = x_speed * -1
end
-- top or bottom side
if ball_y < 0 or ball_y > 119 then
-- reverse y direction
y_speed = y_speed * -1
end
-- move player paddle up and down
if btn(0) then
paddle_y = paddle_y - paddle_speed
end
if btn(1) then
paddle_y = paddle_y + paddle_speed
end
-- move enemy paddle
if ball_y > enemy_paddle_y + 7 then
enemy_paddle_y = enemy_paddle_y + enemy_paddle_speed
elseif ball_y < enemy_paddle_y then
enemy_paddle_y = enemy_paddle_y - enemy_paddle_speed
end
-- player paddle collision
if ball_x < paddle_x + 8 and ball_y > paddle_y and ball_y < paddle_y + 16 then
x_speed = -x_speed
end
-- enemy paddle collision
if ball_x > enemy_paddle_x - 8 and ball_y > enemy_paddle_y and ball_y < enemy_paddle_y + 16 then
x_speed = -x_speed
end
end
-- draw function
function _draw()
-- clear the screen
cls()
-- draw the ball
spr(1, ball_x, ball_y)
-- draw the player paddle
spr(2, paddle_x, paddle_y)
spr(3, paddle_x, paddle_y + 8)
-- draw the enemy paddle
spr(4, enemy_paddle_x, enemy_paddle_y)
spr(5, enemy_paddle_x, enemy_paddle_y + 8)
end
Now you have an enemy paddle that moves slower than the player's paddle!
In this step, we'll add a start screen and a game over screen that lets you play again.
-- ball properties
ball_x = 0 -- x position
ball_y = 0 -- y position
x_speed = 2 -- x speed
y_speed = 1.5 -- y speed
-- player paddle properties
paddle_x = 10
paddle_y = 60
paddle_speed = 3
-- enemy paddle properties
enemy_paddle_x = 110
enemy_paddle_y = 60
enemy_paddle_speed = 1.5
-- game state
game_state = "start"
-- update function
function _update()
if game_state == "start" then
if btn(4) then -- X button
game_state = "play"
end
elseif game_state == "play" then
-- update ball position
ball_x = ball_x + x_speed
ball_y = ball_y + y_speed
-- left or right side
if ball_x < 0 or ball_x > 119 then
-- reverse x direction
x_speed = x_speed * -1
end
-- top or bottom side
if ball_y < 0 or ball_y > 119 then
-- reverse y direction
y_speed = y_speed * -1
end
-- move player paddle up and down
if btn(0) then
paddle_y = paddle_y - paddle_speed
end
if btn(1) then
paddle_y = paddle_y + paddle_speed
end
-- move enemy paddle
if ball_y > enemy_paddle_y + 7 then
enemy_paddle_y = enemy_paddle_y + enemy_paddle_speed
elseif ball_y < enemy_paddle_y then
enemy_paddle_y = enemy_paddle_y - enemy_paddle_speed
end
-- player paddle collision
if ball_x < paddle_x + 8 and ball_y > paddle_y and ball_y < paddle_y + 16 then
x_speed = -x_speed
end
-- enemy paddle collision
if ball_x > enemy_paddle_x - 8 and ball_y > enemy_paddle_y and ball_y < enemy_paddle_y + 16 then
x_speed = -x_speed
end
elseif game_state == "gameover" then
if btn(4) then -- X button
game_state = "play"
ball_x = 0
ball_y = 0
x_speed = 2
y_speed = 1.5
end
end
end
-- draw function
function _draw()
-- clear the screen
cls()
if game_state == "start" then
print("Press X to Start", 40, 60, 7)
elseif game_state == "play" then
-- draw the ball
spr(1, ball_x, ball_y)
-- draw the player paddle
spr(2, paddle_x, paddle_y)
spr(3, paddle_x, paddle_y + 8)
-- draw the enemy paddle
spr(4, enemy_paddle_x, enemy_paddle_y)
spr(5, enemy_paddle_x, enemy_paddle_y + 8)
elseif game_state == "gameover" then
print("Game Over!", 50, 50, 7)
print("Press X to Restart", 35, 60, 7)
end
end
Now you have a start screen and a game over screen that lets you play again!
In this step, we'll add a score and a winning condition where the first player to get 3 points wins.
-- ball properties
ball_x = 0 -- x position
ball_y = 0 -- y position
x_speed = 2 -- x speed
y_speed = 1.5 -- y speed
-- player paddle properties
paddle_x = 10
paddle_y = 60
paddle_speed = 3
-- enemy paddle properties
enemy_paddle_x = 110
enemy_paddle_y = 60
enemy_paddle_speed = 1.5
-- scores
player_score = 0
enemy_score = 0
-- game state
game_state = "start"
-- update function
function _update()
if game_state == "start" then
if btn(4) then -- X button
game_state = "play"
end
elseif game_state == "play" then
-- update ball position
ball_x = ball_x + x_speed
ball_y = ball_y + y_speed
-- left or right side
if ball_x < 0 then
player_score += 1
reset_ball()
elseif ball_x > 127 then
enemy_score += 1
reset_ball()
end
-- top or bottom side
if ball_y < 0 or ball_y > 127 then
-- reverse y direction
y_speed = y_speed * -1
end
-- move player paddle up and down
if btn(0) then
paddle_y = paddle_y - paddle_speed
end
if btn(1) then
paddle_y = paddle_y + paddle_speed
end
-- move enemy paddle
if ball_y > enemy_paddle_y + 7 then
enemy_paddle_y = enemy_paddle_y + enemy_paddle_speed
elseif ball_y < enemy_paddle_y then
enemy_paddle_y = enemy_paddle_y - enemy_paddle_speed
end
-- player paddle collision
if ball_x < paddle_x + 8 and ball_y > paddle_y and ball_y < paddle_y + 16 then
x_speed = -x_speed
end
-- enemy paddle collision
if ball_x > enemy_paddle_x - 8 and ball_y > enemy_paddle_y and ball_y < enemy_paddle_y + 16 then
x_speed = -x_speed
end
-- check for winning condition
if player_score == 3 then
game_state = "player_wins"
elseif enemy_score == 3 then
game_state = "enemy_wins"
end
elseif game_state == "gameover" then
if btn(4) then -- X button
game_state = "play"
player_score = 0
enemy_score = 0
reset_ball()
end
elseif game_state == "player_wins" or game_state == "enemy_wins" then
if btn(4) then -- X button
game_state = "start"
player_score = 0
enemy_score = 0
reset_ball()
end
end
end
-- draw function
function _draw()
-- clear the screen
cls()
if game_state == "start" then
print("Press X to Start", 40, 60, 7)
elseif game_state == "play" then
-- draw the ball
spr(1, ball_x, ball_y)
-- draw the player paddle
spr(2, paddle_x, paddle_y)
spr(3, paddle_x, paddle_y + 8)
-- draw the enemy paddle
spr(4, enemy_paddle_x, enemy_paddle_y)
spr(5, enemy_paddle_x, enemy_paddle_y + 8)
-- draw the scores
print("Player: " .. player_score, 10, 5, 7)
print("Enemy: " .. enemy_score, 90, 5, 8)
elseif game_state == "gameover" then
print("Game Over!", 50, 50, 7)
print("Press X to Restart", 35, 60, 7)
elseif game_state == "player_wins" then
print("You Win!", 50, 50, 7)
print("Press X to Restart", 35, 60, 7)
elseif game_state == "enemy_wins" then
print("You Lose!", 50, 50, 7)
print("Press X to Restart", 35, 60, 7)
end
end
function reset_ball()
ball_x = 64
ball_y = 64
x_speed = 2
y_speed = 1.5
end
Now the game has a score and a winning condition where the first player to get 3 points wins!
By following these steps, you've built a simple Pong game in Pico-8 with a player paddle, an enemy paddle, start and game over screens, and a scoring system. This tutorial helps new programmers understand how to implement game logic, handle user input, and manage game states in Pico-8.