pico-8 apple game

function _init()
 x=63
 y=85
 score=1
 reset_apple()
end

function _update()
 if btn(⬅️) then
  x=x-1
 elseif btn(➡️) then
  x=x+1
 end
 
 ay=ay+1
 
 --catch the apple
 if abs(x-ax)<4 and abs(y-ay)<4 then
  reset_apple()
  score=score+1
 elseif abs(ay)>120 then
  reset_apple() 
 end

function _draw()
 cls()
 map(1)
 spr(1,x,y)
 spr(2,ax,ay)
 print (score)
end

function reset_apple()
 ax= rnd(120)
 ay=-8
end

I’m back at trying to learn pico-8. I’m working on a simple apple-catching game inspired by a tutorial by Spacecat. So far, I have a red apple that falls, resets above the top of the screen if it is caught or hits the bottom, and earns a point if caught. :red_apple:

I’d like to also add a yellow apple (Sprite 3, already made) that appears about 1/4 as often as the red apple, falls about twice as fast, and earns 2 points. What’s the easiest way to do that without rewriting or rearranging my existing code any more than strictly necessary?

1 Like

Okay, I’m going to caveat this by saying I’m going to try and teach you to be a programmer, rather than doing it myself. So please take it with meaning that I’m wanting to help you.

90% of programming is problem solving, and trying to figure out things. Your code is clean, and there isn’t much of it, and it wouldn’t be much work to rewrite it. So to take your last question:-

“What’s the easiest way to do that without rewriting or rearranging my existing code any more than strictly necessary?”

It won’t take too much work to rewrite it from scratch, or rearrange it. Also sometimes the easiest way to fix a problem is to rewrite or rearrange code - it’s a common thing for code :)

With that said, I’d break down your task into smaller tasks:-

  1. Add a Yellow Apple
  2. Make it appear randomly about a quarter of the time
  3. Falls twice as fast
  4. Earns 5 points if collected

I’ll talk you through the first one. You should have enough commands in your code to do the rest :)

To add a yellow apple, the way I’d approach it is to change a lot of the constants into variables, that way you can change variables easily without having to refactor the code. You can add a variable for the sprite number.

So for the spr command, instead of referencing individual sprites, you can reference variables. I’ve looked at your reset_coin function and added some code so that makes the apple randomly split between the yellow and the red apples.

function _init()
 x=63
 y=85
 score=1
 reset_coin()
end

function _update()
 if btn(⬅️) then
  x=x-1
 elseif btn(➡️) then
  x=x+1
 end
 
 ay=ay+1
 
 --catch the coin
 if abs(x-ax)<4 and abs(y-ay)<4 then
  reset_coin()
  score=score+1
 elseif abs(ay)>120 then
  reset_coin() 
 end
end

function _draw()
 cls()
 map(1)
 spr(1,x,y)
 spr(as,ax,ay) -- display the variable apple sprite
 print (score)
end

function reset_coin()
 local randomapple -- "local" is new, and is a variable you can only use in this function. it helps keep code clean
 
 ax= rnd(120)
 ay=-8
 
 randomapple = rnd(2) -- pick a random number between 0 and 2

	if randomapple>1 then
		as=3
	else
		as=2
	end

end

Now with that done, I think you should be able to figure out some of the other elements. Begin with task 2. How could you change it so that instead of appearing 1/2 of the time, the yellow apple appears 1/4 of the time? Lines 40-47 should help you.

Hope that is a start for you!

1 Like

Done! I made the yellow apples fall less frequently by changing randomapple>1 to randomapple>1.5.

Next step: to make the yellow apple fall a bit faster than the red. Maybe not twice as fast, but about 1.25 times as fast?

Also to make it gain 2 points rather than one. I know it’ll be score=score+2 if you catch the apple when as>1.5, but I’m unsure where that goes in relation to all the other code.

Also, I’ve replaced the word “coin” with “apple”. The tutorial I borrowed from had coins.

And this is why programming is great :) - I had a different solution (I was going to change rnd(2) to rnd(4) and randomapple>3, yours is more efficient!

Yes :) - the thing is with this is you can try twice, and then tweak it if it’s too fast!

You will have to change the order of two lines. But now you have the apple sprite stored in a variable you should be able to check it’s values at various locations. So before you set values, you can check them first and then check based on what that value is.

Hope that helps a bit!

if abs(x-ax)<4 and abs(y-ay)<4 and randomapple<1.5 then
reset_apple()
score=score+1
elseif abs(x-ax)<4 and abs(y-ay)<4 and randomapple>1.5 then
reset_apple()
score=score+2
end

if abs(ay)>120 then
reset_apple()
end

Here’s how I made the yellow apple earn 2 points. It may not be very concise, but it’s what I was able to figure out.

Next step: make the yellow apple fall just a tiny bit faster than the red one. Not sure how to even start that step.

An interesting solution that works! I was thinking of using as, but yours would work just as well.

I think you can find a solution doing something very similar to what you have got there for speed :slight_smile:

if randomapple>1.5 then
ay=ay+1.10
end

I got it to work by adding this to update. Next step: add a timer to display on the top right, and have it count seconds.

2 Likes

Okay. I’ve made a variable, time=0, in init.

I draw it in the top right with print.

In update, I call time=time+1, and it counts really fast. How do I get it to actually count seconds?

So update runs 30 frames per seconds, how would you use that to count seconds?

I’d need to get it to count +1 every 30 frames. But my brain just isn’t getting how to format that. Could I have a small hint?

I wouldn’t count every 30 frames…I would count all the individual frames.

What simple maths function (that you learned in school) could you do that would turn:-

30 into 1
60 into 2
90 into 3
120 into 4
150 into 5

Could I take (Time= time+1) and divide it all by 30? Or is there a new variable I need to put in Init?

1 Like

Could I take (Time= time+1) and divide it all by 30?

Yep :slight_smile: - you may need to use flr() when displaying it so you get the integer, but that should do it.

Can you show me what this will actually look like? Still figuring out how to write Lua.

Something like

print('Time: ' .. flr( time/30 ), 32, 60, 7) 

Where 32, 60, and 7 are x, y and colour variables should do it

1 Like

Done. I’ve also added a little clock (sprite 7) that falls slightly more rarely than the yellow apple. It’s supposed to take 15 seconds off the time when you catch it, but catching it doesn’t seem to be affecting the time at all.

function _init()
x=63
y=85
score=0
time=0
reset_apple()
end

function _update()
if btn(:left_arrow:) then
x=x-1
elseif btn(:right_arrow:) then
x=x+1
end

ay=ay+1

time=time+1

–catch the apple
if abs(x-ax)<4 and abs(y-ay)<4 and randomapple<1.5 then
reset_apple()
score=score+1
elseif abs(x-ax)<4 and abs(y-ay)<4 and randomapple>1.5 and randomapple<1.85 then
reset_apple()
score=score+2
end

if abs(x-ax)<4 and abs(y-ay)<4 and randomapple>1.85 then
reset_apple()
time=time-15
end

if randomapple>1.5 then
ay=ay+1.08
end

if abs(ay)>120 then
reset_apple()
end
end

function _draw()
cls()
map(1)
spr(1,x,y)
spr(as,ax,ay)
print (score,3,2)
print (flr(time/30),118,2)
end

function reset_apple()
ax= rnd(120)
ay=-8

randomapple = rnd(2)

if randomapple>1.5 and randomapple<1.85 then
as=3
elseif randomapple>1.85 then
as=7
else
as=2
end
end

Remember time increments 30 frames per second, so 15 takes off half a second…

1 Like

I’m brainstorming a feature to add to my game:

a fox that can randomly appear at x=0 and walk across the screen. If it touches the bucket, you can lose points. But you can hold B to make the bucket hover temporarily so the fox can’t get it.

I guess the first step is to make two fox sprites that can alternate to make it look like it is walking.

This might be pretty tough. If it’s too hard, I guess I could make a sitting fox appear randomly on the same line as the bucket. Sort of like the apples but horizontal.

I’ve got the fox moving across the screen and resetting. Now I need to animate it by shifting between sprites so it looks like it’s walking.

2 Likes

Quick question:

I want the score to flash green for 1 second (30fps) every time the player earns points for catching an apple, then go back to white. How can I do this?