A$$emble IT -
Project Housekeeping and Additional Game Programming
Project Housekeeping / Custom sprite movement / Directional Detection Movement / Game 9: Granny's Teeth (Craptastic version) / Recorded Path Movement / Timed Control Movement
the most boring subject in the Assemble It feature, but it can be a
good option for you to learn from. Although there is nothing to
download from this little chapter. There are some example games which
also use the housekeeping method anyway. So how helpful is this part of
the chapter supposed to be for you?. Let us put things this way. If you
were to create a bigger game project, and use just one assembly file to
program your game. There could be very long strings of code, and you
can easily get yourself lost. (Like you probably are already in this
part of the chapter).
Let us say for example, you are writing a
new C64 game, it has a title screen, the main game, and fully animated
end sequence. You should create SEPARATE assembly files in which should
be linked to your project. Let us take for example, Missile Blasta
(from the previous chapter) for example. The game should be split into
separate assembly files: The main project code (to assemble to should
be MISSILEBLASTA.ASM TITLESCREEN.ASM, GAMECODE.ASM, ENDING.ASM. (To
create your own assembly source code, simply do the same as you did
before when you created a new project. (ADD, NEW ASSEMBLY FILE, enter
name of your assembly code). It will be placed in the project.
Now what if you wanted to link the entire source together, which you already done - placed into separate files?
You enter !source "assemblyfile.asm"
An example for setting a Missile Blasta V2, project with additional ASM files would sort of look something like this:
;Missile Blasta - Remastered V2
;by Richard Bayliss
;For Assemble It 2018
;setup basic / sys start address (since nothing
;is overlapping memory $0801)
;insert the sprites
;insert the status screen (pre-built from older build)
;insert the game binary charset
;insert the game screen binary (made from charpad)
;insert the game screen matrix (made from charpad)
;Insert the title screen matrix (made from charpad)
;Main game code
;Insert title screen code
;Insert end sequence code
;insert the music (,,2 prg)
;goat tracker custom sound effects table
remember, any time you create a new C64 project (Which you will
discover in the next few chapters on this page), always organize your
project into separate parts. It isn't all that hard.
BACK TO TOP
Custom Sprite Movement lda objpos+4
are several different ways in which you can make a custom based
movement of an object. Let us say for example rather than a sprite
going one specific direction, you can alter directions for each sprite.
The directional detection movement
Example: Honey Bee
is also another method to sprite movement. Let us take for example you
are writing a game, such as Honey Bee, Balloonacy or any sort of single
screen dodge, collect and platform game. You would want to have objects
moving in a fixed direction, then flip from one direction to another.
This is probably the most simplest approach to custom sprite movement.
A subroutine is called to first check the value of a pointer, for
example ObjDir is set as the object direction. If the value of ObjDir
is set to a specific value, called, for example 0 = Up, 1 = Down, 2 =
Left, 3 = Right then the code should call the sprite object to move
that specific direction. That is of course until it reaches the set
limited position, from either a fixed value, or a value from a
custom pointer. Then the code forces the object to change direction.
The code snipped below shows an example of how to move a single sprite
object using that specific method.
;Move sprite, according to direction snippet
;Move sprite UP, then once set at limited position,
;switch the direction to DOWN.
lda ObjPos+1 ;Grab position of object Y
sbc #2 ;Movement speed backwards
cmp #$32 ;Stopping position
bcs UpdateUp ;Not reached destination yet
lda #DOWN ;Force DOWN to pointer ObjDir
UpdateUp ;Store new position to object Y
;Move sprite DOWN, then once set at limited position,
;switch the direction to UP.
lda Objpos+1 ;As before, grab position of object Y
adc #2 ;Movement speed forwards
cmp #$f2 ;Has sprite reached the bottom?
bcc UpdateDown ;Not reached destination yet
lda #UP ;Force UP to pointer ObjDir
UpdateDown ;Store new position to object Y
;Move sprite LEFT, then once set at limited position,
;switch the direction to RIGHT.
lda ObjPos ;This time we are using X
sbc #1 ;Movement speed backwards
cmp #$0c ;Has sprite reached left most limit
bcs UpdateLeft ;Not reached destination yet
lda #RIGHT ;Force RIGHT to pointer ObjDir
UpdateLeft ;Store new position to object X
;Move sprite RIGHT, then once set at limited position
;set the direction to LEFT.
lda ObjPos ;Grab current position of sprite
adc #1 ;Movement speed forwards
cmp #$a2 ;Has the sprite reached right most limit?
bcc UpdateRight ;Not reached destination yet
lda #LEFT ;Force direction LEFT to pointer ObjDir
UpdateRight ;Store now position to object X
code snippet above shows only an example of moving one sprite back and
forth, depending on which direction you have set the pointers. But what
if you wanted to do this to ALL 8 sprites? Well, it is possible to move
each sprite individually using multiple routines and macros. Simply
define some pointers for direction for each sprite, also define macros
correctly and call a few subroutines to test each sprite movement. Also
have a play around with the example source snippet and see what you can
make from it.
View source code
BACK TO TOP
GAME 9: Granny's Teeth (The original 4K Craptastic Compo version)
I have showed you an example of the code above to allow all 8 sprites
move according to path/direction. We are going to show you an example
game, which uses a similar approach, although it is quite an old game.
Back in 2016 I entered the C64 craptastic game making compo, which was
to create and develop a game that squeezed into 4K (after compression
through the ALZ64 compressor). It was a platform game, inspired by one
of those games creator games, from back in the early-mid 1980's. This
game was made to look a bit like one of those Games Creator/Creations
games, only just for fun. However, to prove that this game was NOT made
with the games creator. A complete project binary+source has been
provided to accompany this chapter on fixed sprite movement and
So what's this game all about?. You play
the role of Granny, who has tucked her grandchildren into bed. Locked
all of the doors, and placed her teeth safely into her room and went to
sleep. The next morning, Granny wakes up to find her teeth had gone
missing. Also, she finds that her house has been ransacked. The
floorboard had collapsed revealing that her house was built over a
swimming pool. Her cat and dog are on the loose, a bird has flown in,
and who the heck let that spider in?. If all was that bad? Her teeth
had gone missing. The kids were playing with her teeth and thrown them
into the fishbowl. It is now up to you to try and fish your teeth out.
must jump from platform, to platform, avoiding contact with any tacks
strewn on the floor. She cannot swim either. She has to avoid any
moving objects or pets in sight and pick up her teeth. You will score
bonus points and move on to the next level for every time teeth have
been picked up.
This game also features an implementation of Achim Volker's useful Sprite/Background collision which
calculates the X, Y position of the player sprite, and checks whether
or not the lower part of the sprite is touching the pixel of the
background (When using software sprite/background based collision, X
and Y position of the player sprite must be accurately set to the pixel
which the player object lands. This game also uses the directional
control of the sprite movement, similar to very first example in this
category. A software sprite/sprite collision detection is used. The
project also uses the project housekeeping method which helps organize
the program files and code. The active assembly file is of course
Granny.asm. So this file should be marked as active source when
compiling the binary data and code.
Download the full C64 Studio binary + source code to Granny's Teeth
BACK TO TOP
You are writing a space
shoot 'em up. You have a player which is controlled by a joystick. The
player can fire, but there are also enemies that can move around. There
are two different ways in which you could create an attack movement
pattern for an enemy sprite. They are as follows:
Recorded Path Movement
recorded path movement is simply created utility based. The utility
based path movement, is where you record and create the movement,
according to the position of a sprite you set it. A maximum of 256
units is used for making your own alien path movement. One
particular tool which can produce custom object movements, based on
sprite position is the TND Alien Movement Maker V1.0+ (Available
in the utilities section). This tool allows you set a starting position
to a sprite and then record its movement. Be very careful when using
this. You'll need to remember the screen size which you plan your game
project. I first created my own source code to do this for the
game X-Force (pictured above). A small code example for moving an
object based on table movement would look something like this:
;Example path movement code (based on reading the table)
ldx Enemy1MovePointer ;Pointer to set position of enemy
lda PositionTable,x ;Read PositionTableX to grab a X position
sta EnemySpritePosX ;Write the position to the sprite X position
lda PositionTable+$100,x ;Read PositionTableY to grab a Y position
sta EnemySpritePosY ;Write the position to the sprite Y position
;Increment value of
pointer loop for moving object
beq RemoveEnemy1 ;Until all 256 byts are read
inc Enemy1MovePointer ;Increment EnemySpritePos X+Y table by 1 byte
256 bytes from X+Y position table complete.
;Reset the pointer of the enemy
jsr SetNextTable ;Call a subroutine to move the next table.
;Example binary file (inside project)
*=$7000 ;Or where to put the movement data
show you how it is done properly, when we do GAME 9. Using
C64Studio. Please also note that this method uses slightly more memory.
Alternatively, if you cannot wait all that long .... You can check out
issue 27 of Scene World, and check out the source code for Zap Zone
or alternatively, if you want to learn an even bigger/advanced phase in game programming. You could always try Star Toast
issue 28 of Scene World magazine. Please note that both games were
coded in 64ASM, which means that you will need to alter some of the
pseudo commands, should you wish to port those games to C64STUDIO, and
tweak the code for fun. (Or make your own game from it).
BACK TO TOP
The Timed Control Movement
is also another example, which is slightly trickier, compared to the
option (above). Especially if you want to have objects using timed
movement, based on behaviour patterns. This is because you need to use
MORE pointers, although it does use less memory. The trick does work a
treat. You first set the starting X, Y position of a sprite. Set the
pointer/delay and then another pointer read, to read the table
position, also your read the speed table of the sprite. After the time
of one position has expired, the table read pointer increments to the
next position on the table, recording the next X,Y speed (direction) of
the object. Then store it to the sprite position. Sometimes this can
result into awkward consequences, but eventually you can get some great
enemy movement patterns - and not just going one straight direction.
;Example timed speed object movement
;Calculate flip properties - So that
;the movement can be triggered to change
;Actual flip test for alien 1
lda Alien1FlipDelay ;Alien flip delay test ... Counter
beq Alien1SwitchToNextMotion ;Switch to next motion from table
;Switch alien motion
;Reset alien flip delay
ldx Alien1FlipPointer ;Read pointer
lda Alien1_XSpeed,x ;Read selected X direction/speed from table
sta Alien1XSpeedStore ;Store it to alien speed X (Alien1SpeedStore)
lda Alien1_YSpeed,x ;Read selected Y direction/speed from table
sta Alien1YSpeedStore ;Store it to alien speed Y (Alien1SpeedStore)
;Has the table reached the last
byte on each speed table?
beq Alien1SpeedReset ;Yes ... Reset the speed table.
inc Alien1FlipPointer ;Then move to next table setup (To be Self-modified)
;Reset flip table and delay for alien 1
;Time alien 1's movement. Has it reach its movement deadline
;if so. Switch over to the next set of properties for the next
;alien. Then spawn the next alien object.
BACK TO TOP
COMING SOON: Charset Animation, Horizontal map scrolling and GAME 10: BLASTOPIA