Skip to content

Instantly share code, notes, and snippets.

@omgmog
Last active August 4, 2018 10:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omgmog/ac487b3ef04109b7762629f4a99a62f1 to your computer and use it in GitHub Desktop.
Save omgmog/ac487b3ef04109b7762629f4a99a62f1 to your computer and use it in GitHub Desktop.
Arkanoid (wip) - following the Pico-8 Hero video series
pico-8 cartridge // http://www.pico-8.com
version 16
__lua__
function center(width)
return (screen_width / 2) - (width / 2)
end
function _init()
cls()
screen_width = 127
x_zero = 0
y_zero = 8
pad = {
sl = 1,
sc = 2,
sr = 1,
len = 5, -- change this dynamically during update
x = screen_width / 2, -- set this dynamically during update
y = screen_width - 16,
h = 8,
dx = 0,
}
pad.x = center(pad.len * 8)
pad.w = pad.len * 8
ball = {
x = center(0),
y = pad.y - 2,
dx = 1,
dy = -1,
r = 2,
c = 7,
}
bricks = {}
game = {
state = 1,
lives = 3,
points = 0,
hiscore = 0,
}
states = {
splash = 1,
game = 2,
gameover = 3,
}
end
colors = {8,9,10,11,12,14}
numblocks = 0
function buildbricks()
for row=1,#colors do
for col=1,8 do
local _b = {
v = true,
w = 12,
h = 4,
c = colors[row],
}
_b.y = (_b.h+2) * (row + 2)
_b.x = (_b.w+2) * (col - .5)
-- increment numblocks count
numblocks += 1
add(bricks,_b)
end
end
end
function collide(box, projx, projy)
if projy - ball.r > box.y + box.h
or projy + ball.r < box.y
or projx - ball.r > box.x + box.w
or projx + ball.r < box.x
then return false end
return true
end
function collide_side(box)
local slope = ball.dy / ball.dx
local cx, cy
if ball.dx == 0 then
return false
else
if ball.dy == 0 then
return true
elseif slope > 0 and ball.dx > 0 then
cx = box.x - ball.x
cy = box.y - ball.y
return cx > 0 and cy/cx < slope
elseif slope < 0 and ball.dx > 0 then
cx = box.x - ball.x
cy = box.y + box.h - ball.y
return cx > 0 and cy/cx >= slope
elseif slope > 0 and ball.dx < 0 then
cx = box.x + box.w - ball.x
cy = box.x + box.h - ball.y
return cx < 0 and cy/cx <= slope
else
cx = box.x + box.w - ball.x
cy = box.y - ball.y
return cx < 0 and cy/cx >= slope
end
end
end
function update_splash()
if btnp(5) then
startgame()
end
end
function update_gameover()
if btnp(5) then
startgame()
end
end
function startgame()
-- reset stuff
game.state = states.game
game.lives = 3
game.points = 0
pad.x = center(pad.len * 8)
buildbricks()
end
function update_game()
local projx, projy
if btn(0) then
pad.dx = -2.5
end
if btn(1) then
pad.dx = 2.5
end
if not btn(0) or btn(1) then
pad.dx /= 1.4
end
pad.x += pad.dx
pad.x = mid(0, pad.x, screen_width - pad.w)
projx = ball.x + ball.dx
projy = ball.y + ball.dy
if projx > (screen_width - ball.r) or projx < (x_zero + ball.r) then
projx = mid( (x_zero + ball.r), projx, screen_width - ball.r)
ball.dx = -ball.dx
sfx(0)
end
-- if projy > (screen_width - ball.r) or projy < (y_zero + (ball.r*2)) then
if projy < (y_zero + (ball.r*2)) then
projy = mid(y_zero + ball.r, projy, screen_width - ball.r)
ball.dy = -ball.dy
sfx(0)
end
-- handle collision with pad
if collide(pad,projx,projy) then
game.points += 1
if collide_side(pad) then
ball.dx = -ball.dx
else
ball.dy = -ball.dy
local padmid = pad.x + (pad.len * 4)
-- if left side of paddle, x-
if ball.x < padmid then
ball.dx = -1
end
-- if right side of paddle, x+
if ball.x > padmid then
ball.dx = 1
end
end
sfx(1)
end
-- handle collision with brick
for b=1,#bricks do
local _b = bricks[b]
if _b.v and collide(_b,projx,projy) then
if collide_side(_b) then
ball.dx = -ball.dx
else
ball.dy = -ball.dy
end
sfx(2)
game.points += 10
_b.v = false
numblocks -= 1
end
end
-- update position
ball.x = projx
ball.y = projy
if projy > (screen_width - ball.r) then
-- off bottom, lose life
game.lives -= 1
if game.lives < 0 then
-- game over!
game.state = 3
sfx(3)
if game.points > game.hiscore then
game.hiscore = game.points
end
else
new_ball()
end
end
end
function new_ball()
-- stuff
ball.x = pad.x + (pad.w/2)
ball.y = pad.y - 2
ball.dx = 1
ball.dy = -1
end
function draw_splash()
cls(5)
local str = "press ❎ to start"
print(str, center(#str * 4), 64, 7)
end
function draw_gameover()
-- cls(8)
local str
rectfill(0, 60, 128, 68, 0)
str = "game over!"
print(str, center(#str * 4), 62, 10)
str = "press ❎ to try again"
print(str, center(#str * 4), 72, 7)
str = "hi-score: "..game.hiscore
print(str, center(#str * 4), 82, 11)
end
function draw_game()
cls(1)
-- top bar
rectfill(0, 0, screen_width, y_zero, 0)
print("lives: "..game.lives, 1, 2, 7)
local score_txt = "score: "..game.points
print(score_txt, screen_width - (#score_txt * 4), 2, 7)
-- paddle
-- left
spr(pad.sl, pad.x, pad.y, 1, 1)
-- center
for i=1,pad.len - 2 do
spr(pad.sc, pad.x+(i*8), pad.y)
end
-- right
spr(pad.sr, pad.x+((pad.len-1)*8), pad.y, 1, 1, true) -- flipped
-- ball
circfill(ball.x + ball.r, ball.y + ball.r, ball.r, 0) -- shadow
circfill(ball.x,ball.y,ball.r,ball.c) -- fg
-- bricks
for b=1,#bricks do
local _b = bricks[b]
if _b.v then
rectfill(_b.x + 2, _b.y + 2, _b.x + _b.w + 2, _b.y + _b.h + 2, 0) -- shadow
rectfill(_b.x, _b.y, _b.x + _b.w, _b.y + _b.h, _b.c)
end
end
end
function _update60()
if game.state == states.splash then
update_splash()
elseif game.state == states.game then
update_game()
else
update_gameover()
end
end
function _draw()
if game.state == states.splash then
draw_splash()
elseif game.state == states.game then
draw_game()
else
draw_gameover()
end
end
__gfx__
00000000000888856666666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000008e77757777777700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0070070078e777757777777700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0007700068e77ee57676767600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0007700068e7e8856767676700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700008e88856666666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000888856666666600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__sfx__
000100001505000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000100001b05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000100002a32031320013000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00100000127500e7500b750087500675005750047500375002750027300272002720027200f7000d7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment