Writing A Game About Catching Fruit On Ancient Technology


This is a repost from an article originally posted on my blog.

https://hawkuarine.wordpress.com/2022/09/13/writing-a-game-about-catching-fruit-...

Writing a Game About Catching Fruit On Ancient Technology

It was fun, but I don’t think I ever want to do something like this again.

Apple Catcher’s GitHub is located here: https://github.com/bunniico/Apple-Catcher

  1. Inspiration
  2.  Concept
  3. Difficulties
  4. Choosing an Emulator
  5. Choosing a Code Editor
  6. The Code
  7. Conclusion

Inspiration

My inspiration for this project came entirely from this YouTube video.

Concept

The concept for this game wasn’t too grand. Essentially, I just took what I know to be a pretty common kind of mini-game and then wrote it on to an [emulator for] Apple II.

Picture of Basket

Basically, you control, what’s referred to in the code as, the “basket”. You control it using the left, down, and right arrow keys.

There is a single falling “apple” that will always spawn at the top center of the screen the first time, and then every time after it will fall in a different position. The apple will continue to fall faster and faster each time until hitting a set speed limit.

Picture of Apple

The player’s goal is to make sure that their basket is always lined up to where the apple will land, before the apple hits the bottom of the screen.

If the apple hits the bottom of the screen, and the basket does not catch it, the player will lose a life. The player has 3 lives, once they lose all 3 lives the game is over.

If the apple falls into the basket, the player gains 100 points towards their score. At the end of the game, if their score is higher than their high-score, they will have a new high-score and a flashing banner will appear at the top.

Difficulties

Originally, I was setting out to make “Snake” from the video I was inspired by. However, after a bit of thinking, I decided that I wanted to make something without a tutorial. So, this is what I decided I would make.

The first difficulty was obviously that I had to learn the *basics* of how to code in Applesoft BASIC (Sorry). The video that originally inspired me was a massive help in that area, it was impressive to me how quickly I caught on to how the language worked and some of its – strange – quirks.

BASIC requires you to manually type your line numbers, which was something I was *not* used to. So, I had to learn how to properly number my code.

This is also technically the first time I’ve ever finished a game without the use of a game engine. Which is kind of weird to say, because BASIC – at times – feels like a game engine.

Choosing an Emulator

Choosing an emulator was pretty simple, because there were basically two options.

One of which I didn’t even know how to use. The other being essentially a text box where I can paste my code and run it. So, I chose the text box.

Choosing a Code Editor

So, and don’t crucify me for this, I did use a code editor.

However, it didn’t do much but syntax highlighting and give me a dark background to work on. Notepad++ does not come with a syntax setting for Applesoft BASIC built in, and I wanted to try a different code editor anyway, so I decided to download Sublime Text for the first time.

Sublime Text was pretty simple to set up, all I needed to do was download a package from the code palette, and then select Applesoft Basic as my syntax, and everything was basically done.

The Code

So, the next thing I needed to do was to actually code the game itself.

BASIC lives up to its name in the way that it consists of relatively few and very simple to understand commands. Thankfully, the internet exists now so I don’t need a paper manual to tell me everything I can do, but that wasn’t even entirely necessary either because the initial tutorial I watched was so good.

The first parts of the code are the most important.

The code starts off with a few initializing commands, HOME, SPEED, and NORMAL.

HOME clears the screen (most of the time), and NORMAL sets the text mode to.. normal.
SPEED doesn’t seem to actually do anything but I kept it in there anyway because I thought it would maybe slow down the program to a useable state – like a turbo mode.

0000 HOME0001 SPEED = 10002 NORMAL0003 GOTO 220000010 GOSUB 10000020 GOSUB 20000030 GOSUB 3000

After those three commands, we go to the tutorial code.

22000 REM ---- TUTORIAL ----22005 HTAB 15 : VTAB 4 : PRINT ("Apple Catcher")22007 HTAB 1 : VTAB 5 : PRINT ("----------------------------------------")22010 FLASH : HTAB 12 : VTAB 8 : PRINT ("ARROW KEYS TO MOVE") : NORMAL22015 HTAB 13 : VTAB 12 : PRINT ("CATCH THE APPLES") : NORMAL22020 INPUT "";C$22030 GOTO 0010

HTAB sets the horizontal cursor position, and VTAB sets the vertical cursor position. PRINT, obviously, prints to the screen.

Something interesting to note here are the different text modes, being NORMAL and FLASH. The FLASH text mode does exactly what it sounds like it does, it makes the text flashy. You should be careful with this though, because if you clear the screen in FLASH mode you have a seizure.

Lazily, I admit, I did use the INPUT command to pause the game until the player pressed enter because for some reason I could not get it to pause using the normal methods.

Next, the initialization.

This part is pretty boring.

1000 REM ---- INITIALIZE ---- 1010 NORMAL : HOME 1020 LET W = 64 : LET H = 32 1030 LET S = 0 1040 LET T = 1024 1050 LET HI = 0 1060 LET L = 3 1999 RETURN

Basically, all we do in this SUBCALL is make sure the text mode is NORMAL and that the screen is cleared with HOME… again. Now, I’m not sure if its the emulator or if BASIC is just glitchy, but for some reason these commands just don’t work sometimes, no matter how many times you run them.

What follows are a bunch of variable declarations:

W Width (Unused)
H Height (Unused)
S Score
T Time
HI High-score
L Lives

Let’s make an apple!

Again, pretty simple initialization of some variables for our Apple.

2000 REM ---- INITIALIZE APPLE ---- 2010 LET AX = 20 : LET AY = 1 2020 LET ALY = AY 2999 RETURN
AX Apple – X position
AY Apple – Y position
ALY Apple – Last Y position

Let’s make our basket!

One more variable.

3000 REM ---- INITIALIZE BASKET ---- 3010 LET X = 20 3999 RETURN
X X position of the Basket

We’re done initializing! Now, let’s start the game!

The Game Loop!

Finally, the good stuff.

This code block contains all of the building blocks of the game.

0099 REM ---- START ----0100 GOSUB 40000110 GOSUB 60000120 GOSUB 70000130 GOSUB 80000140 GOSUB 90000996 IF L < 1 THEN GOTO 100000997 GOSUB 50000998 GOSUB 40000999 GOTO 0100

Input

Handling input is both complicated and simple.

4000 REM ---- INPUT ----4010 LET K = PEEK(49152)4020 IF K = 136 THEN X = 104030 IF K = 138 THEN X = 204040 IF K = 149 THEN X = 304050 RETURN

So, to get input on the Apple II, you have to actually read the place in memory where the last keyboard input was stored. To do this, you need to know where that value is actually stored. Thankfully, the internet exists, so we know that the keyboard can be accessed using the command PEEK(49152).

Using PEEK(49152) will then return to us an integer code for the key we pressed. You’re also just going to have to figure out the codes for each of the keys you want to use for your game. In this case, we have three inputs.

136 Left Arrow
138 Down Arrow
149 Right Arrow

Now that we know what key the player is pressing, we can move the basket accordingly. To do this, we literally set the basket’s (X) position to one of three values – 10, 20, and 30. These three values use the screen space pretty nicely and spread everything out so the game isn’t played in a tiny box.

Rendering: The Apple

Rendering the apple is very simple!

First, we need to clear the last place where the apple was so that we don’t fill the entire screen with apples. To do that, we use our apple’s last Y position and its current X position (a blunder, you’ll see later) to position the cursor, and then type an empty space to set it to nothing.

Then, we position the cursor where the apple is, and write an “O”.. and that’s it!

6000 REM ---- RENDER APPLE ----6010 HTAB AX : VTAB ALY6020 PRINT (" ")6030 HTAB AX : VTAB AY6040 PRINT ("O")6999 RETURN

Rendering: The Basket

Rendering the basket is also very simple!

7000 REM ---- RENDER BASKET ---- 7010 IF X >< 10 THEN HTAB 10 : VTAB 23 : PRINT(" ") 7020 IF X >< 20 THEN HTAB 20 : VTAB 23 : PRINT(" ") 7030 IF X >< 30 THEN HTAB 30 : VTAB 23 : PRINT(" ") 7080 HTAB X : VTAB 23 7090 PRINT("U") 7999 RETURN

Remember that blunder I was talking about in that last heading? Yeah, because I don’t save the last X position of the apple, when the apple hits the bottom of the screen and changes X positions the character spot that is cleared is instead the area below where the new apple is falling instead of where the old apple fell.

So, to get around this, I put a band-aid on it and instead check every render cycle if the apple is in the X position of the three places the apple can fall from. If the apple isn’t at that X position, it will clear the area right above the player. Therefore, no icky apple residue.

Gravity! – Like Newton!

Apple Catcher(tm) features state-of-the-art physics simulations.

8000 REM ---- GRAVITY ----8010 ALY = AY8020 AY = AY + 18999 RETURN

…I add 1 to the apple’s position every render cycle and save the last Y position to ALY.

Collision

Slightly more complicated stuff.

9000 rem ---- COLLISION ---- 9010 IF AY >< 23 THEN RETURN 9030 IF AX = X THEN S = S + 100 : NORMAL 9035 IF AX >< X THEN L = L - 1 9040 AY = 1 9045 T = T - 64 : IF T < 128 THEN T = 128 9050 LET RX = RND(1) : RX = RX * 10 9055 HOME 9060 HTAB 1 : VTAB 1 : PRINT("SCORE") : HTAB 7 : VTAB 1 : PRINT (S) 9065 HTAB 34 : VTAB 1 : PRINT("LIVES") : HTAB 40 : VTAB 1 : PRINT (L) 9070 IF RX < 3 THEN AX = 10 : RETURN 9080 IF RX >= 3 AND RX < 7 THEN AX = 20 : RETURN 9090 IF RX >= 7 THEN AX = 30 : RETURN 9999 RETURN

Alright, so this code is an absolute mess and can be improved on a lot.

So first, we check if the apple is at the bottom of the screen or not, if it isn’t then we don’t do anything.

Then, we check if the apple and baskets X positions matchIf they match, give the player 100 points. Else, if the positions don’t match, subtract one from the player’s lives.Put the apple back to the top of the screen.Next, we speed up the game by subtracting from the variable that controls our delaying routine. We also limit to a minimum of 128.

Now, we get a random number to get a coordinate to put the apple at. Multiply it by 10 to make it usable as an integer.

Clear the screen so we can update all of the UI and make sure there are no ghosts.Print the score to the screen!Print the lives to the screen!Determine where the apple will be placed horizontally by using the randomly generated number we made earlier.

Death.

It happens eventually.

10000 REM ---- END GAME ----10010 NORMAL10015 HOME10017 IF S <= HI THEN HTAB 16 : VTAB 2 : FLASH : PRINT ("TRY AGAIN") : NORMAL 10020 IF S > HI THEN HI = S : HTAB 14 : VTAB 2 : FLASH : PRINT ("NEW HIGHSCORE") : NORMAL10030 HTAB 13 : VTAB 23 : PRINT ("MADE BY ELLIE :)")10040 HTAB 14 : VTAB 8 : PRINT ("SCORE ") : HTAB 24 : VTAB 8 : PRINT (S)10050 HTAB 14 : VTAB 12 : PRINT ("HIGHS ") : HTAB 24 : VTAB 12 : PRINT (HI)10060 INVERSE : HTAB 16 : VTAB 20 : INPUT "CONTINUE?";C$10070 NORMAL10080 GOTO 21000

Most of this stuff is just pretty simple printing to the screen.

We check if the highscore is a number lower than the player’s score, if it is then we update the highscore.

21000 REM ---- RESET ----21010 S = 021020 T = 102421030 L = 321040 HOME21050 GOTO 0099

When the player presses enter, it will run this code which just resets some of the variables back to their default values so that the game can be reset.

So, how do you slow it down?

There is no wait or delay or really any kind of time-tracking built-in.

5000 REM ---- FRAME ----5010 FOR N = 1 TO T : NEXT N5015 NORMAL5020 RETURN

Basically, we just make a FOR loop that does a bunch of nothing for a couple hundred milliseconds, and also redundantly set the text mode back to NORMAL. The variable T is changed by the collision code, every time the apple hits the bottom of the screen, T is reduced – making the game faster.

Conclusion

It was fun, but I don’t think I ever want to do something like this again.

Files

Emulator
External
Sep 13, 2022
Source Code (Type into Apple II computer) 2 kB
Sep 13, 2022

Get Apple Catcher (Apple ][)

Leave a comment

Log in with itch.io to leave a comment.