I still need to calculate coordinate locations for crosses on many levels and seem to be putting this off at the moment, mainly down to the fact I find it rather boring...
However, I'm putting this task off by actually tweaking and/or adding code to other sections! Honest!
The girl finally became 'properly' selectable/playable the other day and until now has shared characteristics with the boy. But no longer! I've altered certain variables so that when the girl or boy are selected they handle slightly differently.
The boy is slightly 'stronger' than the girl - he can be in contact with enemies or dangerous parts of the scenery for just a few milliseconds longer before experiencing an energy drain.
The girl is slightly 'lighter' than the boy - although she can jump no higher, she can stay in the air just a few milliseconds longer than the boy, making it a tiny bit easier to successfully make the longer jumps between platforms on some levels.
Those differences above are only subtle, but does give the player some choice as to how to play - do you choose easier jumps or more strength? No doubt the variables will be altered further once play testers get their hands on the game and maul my efforts to death, but it will be easy for me to change in the code now since it's all handled by a couple of labels.
I've also finally got round to moving my screen splits slightly to accommodate the fact that on two of the levels (Level 3 - The Apartments and Level 7 - The Park, if you're interested!) I've used a blue background.
I wanted to 'extend' the blue sky background into the upper border, an easy task since the top border is open, but not-to-hot looking because the split was in the wrong place, therefore the blue colour 'bled' too far down the screen. Also, the blue was appearing on levels where the background and top border should have been black.
It was simple fix in the end - the two levels needing a blue top border set a flag telling my top border split to colour itself blue, otherwise colour itself black. The result on Level 3 looks like this...
Next diary entry...
Showing posts with label enemies. Show all posts
Showing posts with label enemies. Show all posts
Wednesday, 4 March 2020
Saturday, 22 February 2020
Level 10 Design
To wrap up my short break from work, late last night I completed the design for Level 10, set down in a basement. As ever, the design is likely to change slightly once proper testing begins, but it already look and 'feels' good to me!
The level includes some pipework and conduit; anyone who knows me knows my love of 8-bit pipes in games! The pipes pump out some green slime which drains your energy on contact. Also new to the scenery are some wooden boxes and some wall chains. I may well add some extra detail later on, depending on whether I have many chars left.
The basement looks a little like this at present...
Although I still need to work out the cross locations for Level 4 onwards, I've have now added all the enemy paths and pattens for all the levels, including Level 10. Here is Level 6 (The Cinema) with it's enemies inserted...
Next diary entry...
The level includes some pipework and conduit; anyone who knows me knows my love of 8-bit pipes in games! The pipes pump out some green slime which drains your energy on contact. Also new to the scenery are some wooden boxes and some wall chains. I may well add some extra detail later on, depending on whether I have many chars left.
The basement looks a little like this at present...
Although I still need to work out the cross locations for Level 4 onwards, I've have now added all the enemy paths and pattens for all the levels, including Level 10. Here is Level 6 (The Cinema) with it's enemies inserted...
Next diary entry...
Monday, 13 January 2020
Level 3 Insertion
A fair few months ago, I started to design Level 3 for the game (see blog post here). Up until yesterday, it only existed in my screen editor, but I've finally exported the screen and colour ram data and inserted it into the game, along with the code to set-up and call the level.
Since this level has been languishing for a while, I thought it deserved some habitation, so I've also added some data to the enemy table for this level and there are now various baddies crawling and flying around. I still need to add some x and y data for the cross locations; currently the data table contains my stand-by data that only contains 2 locations that strobe back and forth.
Once it was all up and running, I wanted more screen action, but in a subtle way. I've seen a couple of games recently that have rain in the background (it seems fashionable to have rain in your game at present and, at time of writing, appropriate given the weather outside) so I decided this level shall have rain!
I must also admit to having watched Simon Jameson's Twitch channel the other night where he demonstrated how he had implemented rain in his game and this also provided the idea and motivation for me to include rain in Chiller 2. However, I wanted a much simpler solution for my game compared to Simon's code, so decided to go with the 'copying char data around' route rather than the pixel plotting through a char route he demonstrated.
So, to start I set aside 5 sequential chars that will be used for the rainfall and plotted a 1,2,3,4,5 repeating sequence in columns using these chars. In the editor to begin with, the rain looked a little like this...
I did my very best to ensure it looked 'random', with columns of chars that were near or adjacent to each other not having identical numbers that were in-line (1's in line with other 1's, 2's next to other 2's and so on) - not doing this would have resulted in very unnatural looking rainfall methinks! Once I was happy with the layout, I cleared the chars themselves of the numbers, knowing the chars were still actually in place on the screen.
I then designed a simple raindrop, not in the editor, but on a scrap piece of paper which I then turned into a table of hex bytes. If you're interested, that table of data looks a little like this within my code...
And then it was time to code a very simple rainfall by copy my raindrop pattern above into each char sequentially. The code I came up with looks a little like this (please note, this is wholly unoptimised at present but was written this way to ensure it could be followed in the future by me!):
What's happening? Well, when this routine is called, first of all I'm clearing all five rain chars to erase any previously drawn chars (this could be optimised to clear only the last previously drawn char!). Then, using a 'variable' that stores which raindrop we're on (it starts with '0'), the code determines which char should be drawn to next and jumps to the drawing code for that char and copies the raindrop pattern data pattern into that char's memory location. The code then jumps to a label called 'draw_rain_dun' which increases the raindrop variable and then checks to see if all five chars have been drawn to in sequence. If they have all been drawn to sequentially over the course of the routine being called a few times (i.e. the fifth raindrop char was last drawn to), the code resets the raindrop variable to '0' so next run through the raindrop pattern is drawn to the first char again.
Hopefully that makes sense?! Of course, this code is also inside a timer that executes it (at present) once every 4th frame. Without the timer that rain would, er, rain too fast!
To be honest, if this code was applied to the whole screen and not just the top of the buildings as in my level, it would probably look pretty jerky. However, in the context of my level and game, it has a nice cartoony feel that I'm very happy with! What does it look like? Something like this...
Next diary entry...
Since this level has been languishing for a while, I thought it deserved some habitation, so I've also added some data to the enemy table for this level and there are now various baddies crawling and flying around. I still need to add some x and y data for the cross locations; currently the data table contains my stand-by data that only contains 2 locations that strobe back and forth.
Once it was all up and running, I wanted more screen action, but in a subtle way. I've seen a couple of games recently that have rain in the background (it seems fashionable to have rain in your game at present and, at time of writing, appropriate given the weather outside) so I decided this level shall have rain!
I must also admit to having watched Simon Jameson's Twitch channel the other night where he demonstrated how he had implemented rain in his game and this also provided the idea and motivation for me to include rain in Chiller 2. However, I wanted a much simpler solution for my game compared to Simon's code, so decided to go with the 'copying char data around' route rather than the pixel plotting through a char route he demonstrated.
So, to start I set aside 5 sequential chars that will be used for the rainfall and plotted a 1,2,3,4,5 repeating sequence in columns using these chars. In the editor to begin with, the rain looked a little like this...
I did my very best to ensure it looked 'random', with columns of chars that were near or adjacent to each other not having identical numbers that were in-line (1's in line with other 1's, 2's next to other 2's and so on) - not doing this would have resulted in very unnatural looking rainfall methinks! Once I was happy with the layout, I cleared the chars themselves of the numbers, knowing the chars were still actually in place on the screen.
I then designed a simple raindrop, not in the editor, but on a scrap piece of paper which I then turned into a table of hex bytes. If you're interested, that table of data looks a little like this within my code...
; raindrop pattern
rain_patt !byte $ff,$ef,$ff,$ff,$ef,$ff,$ef,$ff
And then it was time to code a very simple rainfall by copy my raindrop pattern above into each char sequentially. The code I came up with looks a little like this (please note, this is wholly unoptimised at present but was written this way to ensure it could be followed in the future by me!):
l3_bkgrd_anim ; level 3 rain
; clear all raindrops first
ldx #$00
lda #$ff ; char needs to be solid!
clear_rain
sta $2400,x ; raindrop 1
sta $2408,x ; raindrop 2
sta $2410,x ; etc
sta $2418,x
sta $2420,x
inx
cpx #$08 ; all 8 bytes of each char cleared?
bne clear_rain ; no? branch back
; now check which raindrop should be drawn!
lda raindrop ; which raindrop are we on?
cmp #$00 ; drop '0'?
bne *+$05 ; no? go and check drop '1'
jmp draw_rain0 ; yes? go draw rain0!
cmp #$01
bne *+$05
jmp draw_rain1
cmp #$02
bne *+$05
jmp draw_rain2
cmp #$03
bne *+$05
jmp draw_rain3
cmp #$04
bne *+$05
jmp draw_rain4
draw_rain0
ldx #$00
rain0_loop
lda rain_patt,x
sta $2400,x
inx
cpx #$08
bne rain0_loop
jmp draw_rain_dun
draw_rain1
ldx #$00
rain1_loop
lda rain_patt,x
sta $2408,x
inx
cpx #$08
bne rain1_loop
jmp draw_rain_dun
draw_rain2
ldx #$00
rain2_loop
lda rain_patt,x
sta $2410,x
inx
cpx #$08
bne rain2_loop
jmp draw_rain_dun
draw_rain3
ldx #$00
rain3_loop
lda rain_patt,x
sta $2418,x
inx
cpx #$08
bne rain3_loop
jmp draw_rain_dun
draw_rain4
ldx #$00
rain4_loop
lda rain_patt,x
sta $2420,x
inx
cpx #$08
bne rain4_loop
draw_rain_dun
lda raindrop
inc raindrop
cmp #$04
bne reset_bkgrd_anim_tmr
lda #$00
sta raindrop
What's happening? Well, when this routine is called, first of all I'm clearing all five rain chars to erase any previously drawn chars (this could be optimised to clear only the last previously drawn char!). Then, using a 'variable' that stores which raindrop we're on (it starts with '0'), the code determines which char should be drawn to next and jumps to the drawing code for that char and copies the raindrop pattern data pattern into that char's memory location. The code then jumps to a label called 'draw_rain_dun' which increases the raindrop variable and then checks to see if all five chars have been drawn to in sequence. If they have all been drawn to sequentially over the course of the routine being called a few times (i.e. the fifth raindrop char was last drawn to), the code resets the raindrop variable to '0' so next run through the raindrop pattern is drawn to the first char again.
Hopefully that makes sense?! Of course, this code is also inside a timer that executes it (at present) once every 4th frame. Without the timer that rain would, er, rain too fast!
To be honest, if this code was applied to the whole screen and not just the top of the buildings as in my level, it would probably look pretty jerky. However, in the context of my level and game, it has a nice cartoony feel that I'm very happy with! What does it look like? Something like this...
Next diary entry...
Sunday, 12 January 2020
Level 2 Enemies
Late last night, I finally got round to 'plugging' some data into the movement table for the enemies on Level 2 (The Church).
On this level, the platforms extend quite high, so for the first time the player is able to 'jump' up into the top open border. Therefore, it makes sense to have an enemy 'patrolling' this upper border making it more difficult to collect any crosses that appear there. In conjunction with this top border enemy, there is another enemy patrolling the platform just below, so this should mean the player has to carefully time their jumps between the two enemies, while avoiding floor mushrooms (which zap the players energy) and any floor openings.
I can see quite a few crosses being placed up there to collect!
Next diary entry...
On this level, the platforms extend quite high, so for the first time the player is able to 'jump' up into the top open border. Therefore, it makes sense to have an enemy 'patrolling' this upper border making it more difficult to collect any crosses that appear there. In conjunction with this top border enemy, there is another enemy patrolling the platform just below, so this should mean the player has to carefully time their jumps between the two enemies, while avoiding floor mushrooms (which zap the players energy) and any floor openings.
I can see quite a few crosses being placed up there to collect!
Next diary entry...
Wednesday, 1 January 2020
Enemy Movement Delay
A small diary entry to celebrate the New Year!
In my haste when coding the the enemy movement code (see previous diary entry), I didn't think to include a timer to 'activate' the code. Basically, when the enemy movement routine was called every enemy sprite position was updated *every* frame. This had the effect of every enemy only being able to move 1 or 2 pixels (set by the sprite speed table) because any bigger movement made the sprite move too fast, which looked rather silly on screen. Also, because there were only 2 speed choices, the movement looked a little 'unnatural', with too many enemies moving in-sync because of their same speeds.
I've now enclosed the enemy movement routine within a timer, so it only activates every so many frames set within the code. Currently, the routine now runs every other frame, which means I can now have sprites that move 3 pixels without looking ridiculously fast. This means that the screen now looks much more 'natural' with enemies moving seemingly at their own pace.
As the game progresses, I'll play more with the timer and enemy speeds to see if I can introduce even more natural looking movements.
Next diary entry...
In my haste when coding the the enemy movement code (see previous diary entry), I didn't think to include a timer to 'activate' the code. Basically, when the enemy movement routine was called every enemy sprite position was updated *every* frame. This had the effect of every enemy only being able to move 1 or 2 pixels (set by the sprite speed table) because any bigger movement made the sprite move too fast, which looked rather silly on screen. Also, because there were only 2 speed choices, the movement looked a little 'unnatural', with too many enemies moving in-sync because of their same speeds.
I've now enclosed the enemy movement routine within a timer, so it only activates every so many frames set within the code. Currently, the routine now runs every other frame, which means I can now have sprites that move 3 pixels without looking ridiculously fast. This means that the screen now looks much more 'natural' with enemies moving seemingly at their own pace.
As the game progresses, I'll play more with the timer and enemy speeds to see if I can introduce even more natural looking movements.
Next diary entry...
Friday, 27 December 2019
Enemy Movement
After coding some (very) simple enemy movement patterns for the Freeze64 Xmas Demo a couple of weeks ago, I finally decided to get down to coding the *actual* enemy paths for the game.
This actually began on Christmas Day (who else was coding then??!) when I finally got round to noting down the locations in hex of the enemy sprites in the sprite bank. This was done using good old fashioned pen and paper while sat in my comfy reclining chair, sipping a nice red Tempranillo! Here's what my scrappy notes looked like:
Once these hex locations were noted, I got to thinking what information was needed to set up, display and move an enemy sprite. Obviously, a sprite 'x' and 'y' screen location was needed, but I also need to know colours, the default (start) sprite definition, animation start/end definitions, sprite direction and speed and finally the maximum and minimum screen locations travelled to by the sprite enemy. To keep things simple, sprites in this game move in straight line paths for now! The set-up table for level 1 ended up looking like this...
At first, I was going to have a separate bit of code to handle each enemy, but once I realised that the enemies only move up/down or left/right, I realised I could handle the sprites in a single loop; well two loops actually, one handling vertical movement and the other horizontal. This could be rationalised further into one loop by having another table setting whether each enemy is vertical or horizontal moving, but since the code would be roughly the same, with skips in the loop to handle vertical/horizontal, I decided to keep it simple and have two loops - hopefully this will be easier to read and remember for the future.
I did need to create some more tables holding the sprite animation definitions for each enemy when moving left or right, but I was now ready for some code. It ended up looking a little like this (note, this is for the horizontally moving enemies only):
Basically all that's happening is the code first checks which direction the sprite should be moving (in my game '0' means down or right and '1' means up or left) and then adds or subtracts from the sprites 'x' position on the screen. The addition or subtraction can be altered, thus altering the 'speed' of the sprite, by changing the values in the 'speed_spd' table, which the code references in the loop.
Also referenced is each enemies 'max' and 'min' values which determines the end point of the movement path on screen. Once the max or min is reached, the code switches the 'sprite_dir' so the sprite moves the other way, along with the animation definitions for that direction.
The code for vertical movement is almost identical, save for the sprites 'y' screen value is altered instead.
Once this code is called in the game and the set-up table for level 1 referenced, the enemies ended up doing this (and believe it or not it worked first time!):
I'd call that a successful couple of days and a Merry Christmas indeed!
Next diary entry...
This actually began on Christmas Day (who else was coding then??!) when I finally got round to noting down the locations in hex of the enemy sprites in the sprite bank. This was done using good old fashioned pen and paper while sat in my comfy reclining chair, sipping a nice red Tempranillo! Here's what my scrappy notes looked like:
Once these hex locations were noted, I got to thinking what information was needed to set up, display and move an enemy sprite. Obviously, a sprite 'x' and 'y' screen location was needed, but I also need to know colours, the default (start) sprite definition, animation start/end definitions, sprite direction and speed and finally the maximum and minimum screen locations travelled to by the sprite enemy. To keep things simple, sprites in this game move in straight line paths for now! The set-up table for level 1 ended up looking like this...
l1_sprite_x !byte $19,$20,$4c,$94,$90,$6f,$5a,$0d
l1_sprite_y !byte $cd,$9e,$4f,$a4,$cd,$a8,$54,$85
l1_sprite_col !byte $0a,$07,$0c,$05,$0c,$0c,$0c,$0c
l1_sprite_def !byte $ab,$bf,$ee,$ec,$cf,$c7,$d3,$e8
l1_sprite_anims !byte $ab,$bf,$ee,$ec,$cf,$c7,$d3,$e8
l1_sprite_anime !byte $ac,$c0,$f0,$ee,$d3,$cb,$d7,$eb
l1_sprite_dir !byte $00,$00,$00,$01,$01,$01,$00,$00
l1_sprite_spd !byte $00,$00,$01,$02,$01,$01,$01,$01
l1_sprite_min !byte $00,$00,$53,$53,$19,$5a,$5a,$0d
l1_sprite_max !byte $00,$00,$b8,$a7,$90,$85,$85,$3a
At first, I was going to have a separate bit of code to handle each enemy, but once I realised that the enemies only move up/down or left/right, I realised I could handle the sprites in a single loop; well two loops actually, one handling vertical movement and the other horizontal. This could be rationalised further into one loop by having another table setting whether each enemy is vertical or horizontal moving, but since the code would be roughly the same, with skips in the loop to handle vertical/horizontal, I decided to keep it simple and have two loops - hopefully this will be easier to read and remember for the future.
I did need to create some more tables holding the sprite animation definitions for each enemy when moving left or right, but I was now ready for some code. It ended up looking a little like this (note, this is for the horizontally moving enemies only):
; now deal with the horizontal moving enemies
; zombie, ghost, bat, witch (sprites 4 - 7)
enemy_hori_check
lda sprite_dir,x
cmp #$01
beq enemy_hori1
lda sprite_x,x
clc
adc sprite_spd,x
sta sprite_x,x
cmp sprite_max,x
bcc next_hori_enemy
lda #$01
sta sprite_dir,x
lda left_enm_def,x
sta sprite_def,x
sta sprite_anims,x
lda left_enm_anime,x
sta sprite_anime,x
jmp next_hori_enemy
enemy_hori1
lda sprite_x,x
sec
sbc sprite_spd,x
sta sprite_x,x
cmp sprite_min,x
bcs next_hori_enemy
lda #$00
sta sprite_dir,x
lda rite_enm_def,x
sta sprite_def,x
sta sprite_anims,x
lda rite_enm_anime,x
sta sprite_anime,x
next_hori_enemy
inx
cpx #$08
bne enemy_hori_check
Basically all that's happening is the code first checks which direction the sprite should be moving (in my game '0' means down or right and '1' means up or left) and then adds or subtracts from the sprites 'x' position on the screen. The addition or subtraction can be altered, thus altering the 'speed' of the sprite, by changing the values in the 'speed_spd' table, which the code references in the loop.
Also referenced is each enemies 'max' and 'min' values which determines the end point of the movement path on screen. Once the max or min is reached, the code switches the 'sprite_dir' so the sprite moves the other way, along with the animation definitions for that direction.
The code for vertical movement is almost identical, save for the sprites 'y' screen value is altered instead.
Once this code is called in the game and the set-up table for level 1 referenced, the enemies ended up doing this (and believe it or not it worked first time!):
I'd call that a successful couple of days and a Merry Christmas indeed!
Next diary entry...
Subscribe to:
Posts (Atom)







