Skip to content

Instantly share code, notes, and snippets.

@rostok
Created September 7, 2023 18:01
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 rostok/bf4beda2d92c217f6e12ee230aae1676 to your computer and use it in GitHub Desktop.
Save rostok/bf4beda2d92c217f6e12ee230aae1676 to your computer and use it in GitHub Desktop.
source code for the wall builder - a pico8 game under 1kb
pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
-- The Wall Builder - a Pico1k 2023 jam entry by https://rostok.itch.io/ @von_rostock
pal({2,-8,8,14},1) -- sets the palette gradient for bricks
local x,y,l,P,Q,T,X,Y,c=61,72.5,0,0,0,0,0 -- variables
-- x,y person position on screen
-- l if 1 then person holds brick 0 doesn't
-- P,Q coordinates of current area, start area is 0,0
-- T 1/4th brick counter, if equals N wall is raised
-- X,Y local temp vars
-- c collision
-- -1 no collision
-- 0 collision with place for brick
-- 1,2,3,4 collision with wall of specified height
local R,bw,bh=36,8,4 -- R wall radius, bw/bh brick width, brick height
local N=(R*6.3)\bw -- N number of bricks at peremeter
local W,OW={} -- W "WALL" table with brick places, OW start screen wall
for i=1,N+N do -- initialize bricks, there are total of N*4 bricks
X=cos(i/N)*R+64 --
Y=sin(i/N)*R/2+64 -- X/Y are coords of brick place
B={} -- B is temp table to hold brick place
B.h=0 -- .h place height 0..4
B.a=-i/N -- .a angle
B.s=1 -- .s if 1 then should be shifted (wall), 0 not (brick stack)
if(i>N)B.a=.25B.s=0Y=70-(i-N)\4B.h=4X=85-(i-N)%4*bw -- initialize brick stack (horizontal, not shifted, stacked)
B.x=X -- save brick place position
B.y=Y --
B.U=cos(-B.a) -- save brick direction
B.V=sin(-B.a)/2 --
I=1 while I<=#W and Y>W[I].y do I+=1 end add(W,B,I) -- brick places are sorted according to y coord ascending
end --
OW=W -- save Original Wall
::__:: -- loop to randomize screens with ruins
srand(P*64+Q) -- each is unique but should be the same if player returns
local O,M={},"" -- O is other wall, table for structures in other arease, M is a string with win/loose message
-- set O "otherwall" copy brick places and modify height lowering it if further from the start area
for b in all(W)do add(O,{x=b.x,y=b.y,U=b.U,V=b.V,h=min(4,rnd(8/sqrt(P*P+Q*Q)))\1,s=b.s}) end
W=P|Q==0 and OW or O -- current wall W is either original wall or O
::_:: -- main loop
print("\^1\^c6") -- flip() cls(grey)
local u,v=(@24396&2)-@24396%2*2,@24396\8%2-@24396\4%2 -- read keys and set u,v direction vectors
local d=1==1 -- d is clear to go (no collision), 1==1 compresses better
for b in all(W)do -- draw ground
fillp(23130) -- init dither patter for shadow
for i=1,b.h*4 do -- for each brick place that has height draw ovals to the right
ovalfill(b.x+i,b.y-5,b.x+i+8,b.y,109) -- shadow uses 6*13+6 color
end --
fillp() -- reset fill pattern
if(b.s>0)pset(b.x,b.y,13) -- draw single pixels at places where bricks can be laid
end --
for j=0,1do -- draw wall and person
for b in all(W)do -- two iterations 0) bricks above + person 2) bricks below
if(b.h>0and ((j<1and b.y<y)or(j>0and b.y>=y)))then -- draw only if brick place has positive height (some bricks are actually there)
for h=0,b.h*bh-bh,bh do -- draw each brick layer up to b.h, but jump from 0 to b.h*bh with bh step which is brick height
local U,V,K,L=-b.V*bw,b.U*bw/4,0,0 -- set some local vars U,V are brick direction vector, K,L are brick shift default to no shifting
if(h\bh%2<b.s)K,L=U,V -- if brick should be shifted copy U,V to K,L
for f=-sgn(b.V),sgn(b.V)/2+.5,sgn(b.V) do -- loop to draw brick depth, however this draws depending on the angle of the brick
-- which is taken from b.V which is a sine
-- so 2 possible for-loops here for f=-1,0,1 or f=0,1,1
X,Y=b.x+K+f*b.U,b.y+L+f*b.V -- X,Y holds brick center and is shifted and translated by depth
for g=0,bh do -- draw bh brick lines
line(X-U,Y-V-h-g,X+U,Y+V-h-g,g%bh==0and 1 or 3) -- first and last lines have color 1 (dark red) the ones in middle are normal (red)
end --
line(X-U,Y-V-h-bh-1,X+U,Y+V-h-bh-1,4) -- draw top of the brick with lighter color
line(X-U,Y-V-h,X-U,Y-V-h-bh,1) -- draw two left and right side od the brick with dark red
line(X+U,Y+V-h,X+U,Y+V-h-bh) --
end --
end --
end --
c = -1 -- assume no collision at all
if(abs(x+u-b.x)*.9+abs(y+v-b.y)*2<6)c=b.h -- check for collision and if so set c to collding brick place b.h
if(c>0and b.s==0and l==0 and P|Q==0)l=1 b.h-=1print("\as1xzc0") -- if there is collision, and it is stack, and person hold nothing, and it is start area
-- then hold brick, lower brick place height and play sound
if(c>=0and b.s==1and b.h<4 and l==1)l=0 b.h+=1print("\as1xzc1") T+=.25 -- if this is brick place of possible wall place it here and increase T counter
if(j<1)rect(x-1,y-4,x+1,y-9,0)line(x,y-4,x,y-11)for i=-1,1,2do line(x+i,y-3,x+i+u*i*sin(t()*3),y+2*v*i*sin(t()*3))end
-- if it is our 0 iteration then draw the person torso, head, legs
if(l>0and j<1)rectfill(x,y-8,x+bw,y-8+bh,3)rect(x,y-8,x+bw,y-8+bh,1) -- and if person holds brick draw it as well
d=d and c<1 -- make sure person collided with nothing
end --
end --
print(M,64,16,10) -- print win/loose message
if(d)x+=u y+=v -- if there is no collision move the person
-- if person wanders far off the screen change P,Q area coordinates and initialize current area
if(abs(x-64)>320or abs(y-64)>320)P+=(x-64+320)\640Q+=(y-64+320)\640x%=128y%=128goto __
if(T>=N)M="\-1\-1\-1wall built, enjoy safety" -- if T total blick places counter hits N then wall is built so person can live in peace
if(abs(P)>7or abs(Q)>7)then -- exploring far enough will trigger second ending
M="\-8\n\n\f0|\+ci#\+ckm" -- here it is
if(abs(x-64)+abs(y-40)<8)M="\-8hello\n\n\f0|\+ci#\+ckm" -- and a message if one comes close enough
end --
goto _ -- loop ends, like most things
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment