This part of the “Basic Marathon Game” will educate you on how to detect a sprite to background collision. This detection is important since by default the Commodore Rom does not contain any really effective way to do this. Our goal here will be to align the sprite’s X (horizontal) and Y (vertical) position to be aligned with that of the characters on the screen.

Normally this would be pretty straight forward, however make note that the sprite can leave the screen and position zero begins behind the screen borders. The starting data for our character screen will be within the screen and not behind the black border. Therefore we need to start the position as soon as the screen appears on the screen from the top border to the far left border. This is known as detecting a “sprite to background collision”.

As a recap the video discusses how the Commodore 64 (6510 chip) can really only under machine language. Basic programming is actually a lot of machine language subroutines that allow you to write your own programs reading tokens (commands) from a table, storing them in memory, and setting up calls to handle the tasks, errors that are common when writing a program.

This tutorial attempts to mix both Basic and Machine language to achieve a somewhat decent game. It will be obvious later as we further develop this series, that machine language will be our primary objective since Basic runs much slow when trying to complete tasks, such as moving characters, sprites, and reading data to a screen.

Basic Marathon Game Part 5

The game collision detection is not perfect for this example. As I explained in the video that the sprite seems to get “stuck” when an impact with a background character occurs.

When it is successful, the border color will briefly flash yellow and the sprite position is reset back to the left side again.

A better way to detect the collisions though is to use something known as a “bounding box”. What this does is create an invisible box around the sprite that will read any character data that enters that area (by pixels) and check if an overlap of the sprite and background area have taken place.

Basic to Background Collisions

Another way that the video examines the detection is utilizing a simple Basic program example that allows a purple sprite box to be moved around the screen. The program “waits” for contact to occur and then a routine is called to signal that a collision took place.

The Basic program example works better than the machine language example, which is demonstrated when the sprite collides into a background character and is prevented from passing through.

A second example is demonstrated that allows you to move a sprite and a set of background characters are placed evenly on the sprite (grey box) and move along at the same pace as the sprite. This one does not look for a collision, but instead is seen here to compare the examples so you can see how a collision would be taking place otherwise.

Basic Program Explained

Lines 20-30 setup the sprite and make it active.Then the variables
are used to track our sprite’s location, and a variable is created
that manages our background character data.

10 REM SPRITE ASCII COLIS
12 REM 5/25/19
15 :
20 POKE53269,1:POKE53287,12
30 POKE53275,1:POKE2040,255

Draw the screen data

Next we set a variable for the sprite’s horizontal (X) and vertical
(Y) positions, clear the screen, and draw the character pattern
from top to bottom on the screen (known as the “playfield”).

Note: A random variable (RN) is used to spread out the character
data (“AA”,”BB”,”CC”,”DD”) to make it more interesting.

40 X=80:Y=80:NM=0
45 AX=.08:AY=.08
50 A$=”AABBCCDD”
55 PRINTCHR$(147)
60 POKE646,3:POKE53280,2:POKE53281,0
70 FORH=1TO19STEP3
72 RN=1+RND(0)*35
75 POKE214,H:PRINT:POKE211,RN
78 PRINTA$
80 NEXT

Joystick Controls

The joystick movement for left, right, down, and up is read in
lines 100-155 and keeps the sprite on the screen, also allowing for
the pass point (more than half center) as the sprite travels
completely from left to right. We make sure to return back to line
100 to keep in a loop with the running program.

100 JY=PEEK(56320)
109
115 IFJY=123THENX=X-4:DX=-3:DY=0:GOSUB400:GOSUB710
120 IFJY=119THENX=X+4:DX=-1:DY=1:GOSUB400:GOSUB720
130 IFJY=125THENY=Y+4:DX=0:DY=2:GOSUB400:GOSUB730
140 IFJY=126THENY=Y-4:DX=-1:DY=1:GOSUB400:GOSUB700
150 IFX>=252THENPOKE53264,1:X=1:POKE53280,3
155 IFX<=0THENPOKE53264,0:X=252:POKE53280,9
156 PRINT”S”,X,Y
270 :
290 GOTO100

Important Variables

The variable declarations contained in lines 400-417 manage thedetection position of the sprite to the background characters onthe screen as it makes contact.

Line 410 is a variable that reads the screen as the sprite movesaround. So 1024 represents the upper left corner of the screenmemory and the XC an YC handles the sprite position.

Upon closer examination of these lines notice the X-24 and Y-21. These are subtracting the size of the sprite’s X and Y position tobe equal to an 8×8 matrix which is the single size of a character taking into relevance the entire size of the sprite, which extendsit to 8 x 3 = 24 (width of sprite).

Keep in mind that the sprite is 3 characters in width and height in our example. The total pixels on our sprite is calculated as 21 x21 = 504.

On the other hand the total occupied area of pixels for any single character (such as “A”, etc) is 8 x 8 = 64.

400 OX=X:OY=Y
402 XC=((X-24)/8)+3.2):REM +INT(DX)
406 YC=((Y-21)/8)-3.2):REM +int(DY)
410 VL=1024+INT(XC)+(40*INT(YC))
412 UL=VL-1:UR=VL+1:V0=(VL)-3
413 V1=(VL)-3:V2=(VL)-2:V3=(VL)-1
416 V4=(VL+40)-3:V6=(VL+40)-1:V7=(VL+40*2)-3
417 V8=(VL+40*2)-2:V9=(VL+40*2)-1

The main action detection actually begins at line 430 managing the sprite position (X,Y) up to line 600 and checks boundaires and then we return from here.

430 POKE532848,X:POKE53249,Y
500 REM CHECK BOUNDARIES
502 SA=PEEK(VL)
505 S3=PEEK(V3):S4=PEEK(VL):S5=PEEK(UR):S6=PEEK(H1):S7=PEEK(H2)
600 RETURN

The rest of the lines from 700-1000 are called as the joystick is moved around which aligns the character data to the sprite box.

695 REM UP
700 POKEV0,1:POKEV0+54272,12:POKEV2,2:POKEV2+54272,5
702 POKEV3,3:POKEV3+54272,2
705 RETURN
708 REM LEFT
710 POKEV1,1:POKEV1+54272,1:POKEV4,4:POKEV4+54272,4
712 POKEV7,7:POKEV7+54272,7
714 RETURN
715 REM RIGHT
720 POKEV3,3:POKEV3+54272,13:POKEV6,6:POKEV6+54272,6
722 POKEV9,9:POKEV9+54272,9
723 RETURN
725 REM DOWN
730 POKEV7,7:POKEV7+54272,1:POKEV8,8:POKEV8+54272,8
732 POKEV9,9:POKEV9+54272,9
1000 POKE53269,0

Assembly Language Sprite

Finally we present the code for the original sprite movement (yellow man character) that moved around and would stop when colliding with the background characters on the screen.

This was also noticeable when the program was listed in memory and the sprite could slightly move as the program scrolled down. Then after the listing was finished, the screen had to be scrolled up a little where there was no collision detection, and the interrupt call which moved the sprite had free access again.