Last active
August 4, 2018 10:37
-
-
Save omgmog/ac487b3ef04109b7762629f4a99a62f1 to your computer and use it in GitHub Desktop.
Arkanoid (wip) - following the Pico-8 Hero video series
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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