Created
September 21, 2022 22:19
-
-
Save Powersaurus/3a30cf19134327742804f5ca1239674f to your computer and use it in GitHub Desktop.
BEARS STOLE YOUR PICNIC, but with comments
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
-- set nearly my "usual" palette, ready for drawing the sprites | |
cls()pal(split"1,141,3,4,5,6,7,137,9,10,138,12,13,131,133",1) | |
-- draw 4 trees, 4 items and a bear. A lot of overdraw here, the 150 | |
-- is chosen because it is a number I duplicate later to appease | |
-- the compressor, and because it ensures scattering foliage | |
-- gives the impression of a bushy tree | |
for i=0,150do | |
-- draw the trunks using a mix of symbols and p8scii control codes | |
-- every sprite is created by using the ? print shorthand to draw | |
-- to the screen | |
?"\^t\f5✽\-6\ff ✽\b\^w\f1\|e𝘷",rnd(i%5)+i%4*32+8,24+i/9 | |
-- vertically scatter the foliage in a triangular pattern | |
-- as y increases, the x range increases too | |
y=rnd(26) | |
?"\^t\f3★\-b★\b\fe░\-9\f1ˇ",i%4*32+rnd(y)+6-y/4,y | |
-- p8scii for the items. Each item uses two symbols laid on top of | |
-- each other to add 'detail', the bear is a bit more complicated. | |
-- Moving the cursor is a pain | |
?"\f3●\b\|f\fb●\b /\f8█\b\f9ˇ\fb█\b\f7⧗\f4█\fa\-9▒\f4\-a█\f1█1\b\b\b\f4m🐱",1,54 | |
end | |
-- copy screen mem to sprite sheet mem | |
memcpy(0,0x6000,0x2000) | |
-- set 'restart' label, used for win and lose conditions and | |
-- (re)initialise a load of variables | |
::x::t,h,j,c,n,a,m,l={},8,8,0,0,0,split"apple,crisps,lemonade,sandwich" | |
-- scatter 80 trees in the 16x16 environment. Every object lives | |
-- in the t array and has a type, an optional colour, x,y,z coords and | |
-- a width and height. Some objects have more info | |
for i=0,80do | |
add(t,{t=0,c=rnd(3)\1,x=rnd(16),y=160,z=rnd(16),w=23,h=33}) | |
end | |
-- scatter 80 shrunk trees to act as 'fallen leaves on the ground' | |
-- note the tiny width+height values | |
for i=0,80do | |
add(t,{t=0,c=rnd(3)\1,x=rnd(16),y=-30,z=rnd(16),w=.5,h=.5}) | |
end | |
-- create borders for the game environment - too uniform, but | |
-- no space left! | |
for i=0,16,16do | |
for v=0,16do | |
add(t,{t=0,c=rnd(3)\1,x=i,y=160,z=v,w=23,h=33}) | |
add(t,{t=0,c=rnd(3)\1,x=v,y=160,z=i,w=23,h=33}) | |
end | |
end | |
-- scatter the 4 collectible objects. These objects have | |
-- spritesheet info (i = width/height, p = spritesheet x, | |
-- s = spritesheet y) | |
for i=0,3do | |
add(t,{t=1+i,x=1+rnd(14),y=-30,z=1+rnd(14),w=2,h=2,i=8,p=8*i,s=51}) | |
end | |
-- p8scii to play a sad trombone sound at the start of the | |
-- game | |
?"\asfe1.a#0" | |
-- game loop label and | |
-- initialising the player's x + z values - this is to save | |
-- space, only initialised the 'new position variables'. | |
-- A lot of stuff happens in an odd order in this game for space | |
-- reasons. It is not update - draw, it is update - draw - update! | |
::i::x,z=h,j | |
-- read input, left and right rotation, followed by forward and | |
-- backwards | |
if(btn(0))a-=.007 | |
if(btn(1))a+=.007 | |
-- h and j store the new position, and are used to update if the | |
-- move does not leave the play area | |
if(btn(2))h,j=x+cos(a)*.05,z+sin(a)*.05 | |
if(btn(3))h,j=x-cos(a)*.05,z-sin(a)*.05 | |
-- if the game is over (c has been set to less than zero) | |
-- then check if the player pressed x to restart the game - use | |
-- goto to jump to the initialise step just after the sprite creation | |
if(btn(5)and c<0)goto x | |
-- check x and z boundaries for the player's new position. Update | |
-- each of these values if the move is within the boundaries | |
if(h<1or h>15)h=x | |
if(j<1or j>15)j=z | |
-- clear the screen with the light grey/blue colour for a daytime | |
-- sky | |
cls(13) | |
-- draw the floor in green, followed by some dithering for a | |
distance effect | |
fillp()rectfill(0,40,128,128,3) | |
fillp(0x4010)rectfill(0,83,128,90,83) | |
-- overlap both the sky and the ground with this dither, works | |
-- with both | |
fillp(▒)rectfill(0,32,128,82,5) | |
fillp(0x5a5a)rectfill(0,56,128,68,19) | |
-- rotate every object into '3d' space. Note the use of i | |
-- as the loop variable everywhere - the duplication saves | |
-- space | |
for i in all(t)do | |
u,v=i.x-x,i.z-z i.u,i.v=sin(a)*u-cos(a)*v,cos(a)*u+sin(a)*v | |
end | |
-- i love/hate this. Using lua's scoping / heinous name | |
-- shadowing to save space, since I don't actually need | |
-- the loop variable from the outer loop. Double i! | |
-- the loops are repeating a bubble sort for depth | |
for i=0,3do | |
for i=1,#t-1do | |
-- test two items depths from the player | |
if(t[i].v<=t[i+1].v)t[i],t[i+1]=t[i+1],t[i] | |
end | |
end | |
-- originally this loop was just for drawing objects, | |
-- but now does several different things | |
for i in all(t)do | |
-- bears (t==5) change to a new random direction | |
-- every 3 seconds | |
if(i.t==5and c%90==0)i.f=rnd()-.5i.g=rnd()-.5 | |
-- bears move based on their velocity f (x vel) and g (z vel) | |
if(i.t==5)i.x+=i.f or 0i.z+=i.g or 0 | |
-- check whether the player collided with a bear, and | |
-- if so, go to the start of the game (x label) | |
if(i.t==5and abs(i.x-x)<1and abs(i.z-z)<1)goto x | |
-- check all other object collisions. If it is a collision | |
-- then remove the object, increase the 'score', set the | |
-- hud message for which item the player got, and play a little | |
-- sound effect | |
if(i.t>0and abs(i.x-x)<1and abs(i.z-z)<1)del(t,i)n+=1l=m[i.t]?"\ace-g" | |
-- draw objects. This has to handle trees, items and bears, so has | |
-- a lot of 'this object might not have this value, so we need a | |
-- default'. i.v is the screen depth value for an object, so objects | |
-- behind the player/camera | |
-- the palette for the dark green colour is switched - this is only | |
-- used for trees, everything | |
if(i.v>0)pal(3,1+(i.c or 0))sspr(i.p or i.c*32,i.s or 0,i.i or 32,i.i or 48,64+i.u*64/i.v,64-i.y/i.v,i.w*6/i.v,i.h*6/i.v) | |
end | |
-- every 3 seconds add a bear at random location | |
if(c%90==0)add(t,{t=5,x=rnd(16),y=40,z=rnd(16),w=30,h=30,i=12,p=36,s=51}) | |
-- reset the dark green colour for drawing things the next time round | |
pal(3,3) | |
-- if any item has been collected, draw the hud message | |
if(l)?"\f7found "..l | |
-- if the player finds all 4 items, save the time it took them, | |
-- set c to a negative number to indicate 'game end' and play a | |
-- tune by printing some p8scii control codes | |
if(n==4)n,c=c,-999?"\a..d..d..d..ccc..ddd" | |
-- title screen for three seconds when the game starts | |
-- note: the game is running in the background and this causes | |
-- problems if the player spawns at the same location as the bear | |
-- game restarts immediately and screen flickers | |
if(c<90)cls()?"bears stole your picnic",20,60 | |
-- game end screen - shows time player took to win, and a prompt | |
-- to return to the start of the game. c < 0 == game is over | |
if(c<0)cls()?"found your picnic\nin "..(n\30).." secs!\npress ❎",20,60 | |
-- increase c, the game timer, flip the screen buffers and then goto | |
-- the i label. Using i for the label since it is used as a loop | |
-- variable elsewhere so it is slightly cheaper. | |
c+=1flip()goto i |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment