Annotated code


-- initialization

--shorthand for the rnd() function, which I'll use a couple times
e=rnd
--kitty x position on screen...initialized to 8 for no particular reason
x=8

--constants for the left and right x positions of the kitty for the above variable to swap between
v=0
w=120

--f for "leFt," naturally...as in, "is the kitty on the left side of the screen"
f=true

--z for "lineZ"--this is a timer for when the kitty is moving and producing a line across the screen
z=0

--l for "lives," nine of them of course
l=9

--score
s=0

--an empty table that will hold the oBstacles
b={}

--c for "Color," we'll use this to do some fun color effects when hitting an obstacle
c=12

--u for "timUr," this global timer will increment every frame
u=0

--p for "Playing," this will become false when the game is over
p=true

--r for "Random," this will be used as a camera offset for screenshake
r=0

--y for "sixtY-four," a number I used a bunch of times, helped save a few characters
y=64

--main loop

--update

::_::

--increment timer each frame
u+=1

--Decrement the "linez" counter. When this is positive the kitty will be considered "in motion" and therefore susceptible to being struck. I realize I didnt clamp this to zero...I guess this is only a problem if you leave the game running long enough for it to underflow!
z-=1

--if "leFt" is true, draw kitty at min x value, otherwise max x value
if(f) x=v else x=w

--Here's where the button action takes place. If you press button 5 (the "X" button) *and* you aren't in a game over state, then do the following:
--the print statement control code plays a single beep (I went with a lower octave, so more of a boop i guess)
--negate the current value of "leFt," swapping the kitty position
--set "lineZ" counter to 4, which sets the kitty "in motion" for 4 frames, thus rendering them susceptible to hitting an obstacle
--add a single obstacle to the "b" table, with the following attributes:
--random "x" position
--"y" position initialized to zero, though this will be updated to something else right away
--random offset value "o," which will determin the phase of its sinusoidal vertical position
--store the current value of the global timer as "t"--this will be used to ensure that newly created obstacles will not immediately collide with the player if they spawn along their path
--increment score counter by one
if(btnp(5) and p) print"⁷c3" f=not f z=4 add(b,{x=e(96)+16, y=0, o=e(48), t=u}) s+=1

--Update the y position of each obstacle using a sine function with the global timer and each unique offset value as inputs
for o in all(b) do o.y=sin((u+o.o)%y/y)*y+y

--Here's where we handle collision logic.
--The conditions are as follows:
--if z is positive, then the kitty is considered "in motion" and can be hit
--any obstacle with y coordinate between 64 and 66 can hit the player
--at least 6 frames must have elapsed since any given obstacle was created for it to register a hit
--If all conditions are met, the following logic occurs
--print a control code that plays a descending three-note tone
--decrement life counter by one
--decrement score counter by one
--set c to 6--this "Color" variable will be used to draw the kitty and obstacles and is therefore responsible for the color cycling following a hit
--delete the obstacle(s) that registered a hit from their table
if(z>0 and o.y<66 and o.y>y and u>o.t+6) print"⁷gec" l-=1 s-=1 c=6 del(b,o) end

--The following handle coloration of the kitty and obstacles. After a hit, this will increment the "c" variable back up to the "normal" coloration and then clamp it at that value
c+=1
if(c>12) c=12

--The "Color" value is also used to generate the random offset "r" for camera shake, which will become zero when "c" is clamped
r=e(12-c)

--Game over condition. If lives dip below 1, the button no longer registers input and the game is over. I originally had this as "if(l==0)" but that would break if multiple final hits were registered. This notation also saves a character! Bonus!
if(l<1) p=false

--draw
--clear the screen each frame
cls()
--Apply camera offset using above calculated random values. If I had more space to work with I might have used independent x and y offsets, but I felt like the diagonal shake this provided was sufficiently jarring!
camera(r,r)
--Draw the obstacles. Only interesting bit here is the "c" variable for color, detailed above, which will cycle through several values after a hit before it returns to and is clamped at light blue
for o in all(b) do print("✽",o.x,o.y,c) end

--Draw the kitty. As above, "c" is used for color cycling after a hit.
?"🐱",x,62,c+2

--I was *determined* to have some sort of "instructions" at the start of the game...well, here ya go! When the score is zero, the "X" key prompt is printed below the kitty (since its the last character printed on the screen).
if(s==0)?"❎"

--Here's where we draw the "motion line" when the kitty is moving. I use a sparse "zig-zag" fill pattern in the last frame it is visible to give the sense of it dissipating. I do not specify a color, so it inherits the color of the kitty, the last thing drawn to the screen.
if(z==1) fillp(∧)
if(z>0) line(16,y,112,y)
fillp()
--Draw hearts across the top of the screen to signify how many lives remain. I took advantage of the conveniently adjacent red-orange-yellow-green colors in the pico 8 palette to vary the heart color as a function of the number of lives remaining.
for i=1,l do print("♥",8+i*10,8,8+l/3) end

--Print the score. By leaving this until the very end and not specifying coordinates, the score will naturally be printed below the right-most remaining heart and, at the game over state, below the player, which felt pretty natural!
?s

--repeat main loop
flip()goto _

Files

tweetcat_zip_commented.p8 22 kB
29 days ago

Get #TWEETCAT.zip

Leave a comment

Log in with itch.io to leave a comment.