Saturday, 29 February 2020

Let it Snow!

After designing Level 9 (The Log Cabin) a few weeks ago (read here...), I've been looking for ways to improve the on-screen look as the level has been looking rather plain - currently, there is quite a lot of background moment (animated chars) used in the levels before and after Level 9.

I did ask on various forums for ideas because I was fresh out of them and a couple of people suggested perhaps animating (glowing) eyes, or wisps of smoke coming out of the log cabin chimney.  I did try these and, although they looked quite nice, I was still disappointed with the amount of animation on-screen compared to Levels 8 and 10.

Yesterday, I had a brain-wave!  I already have rain in some levels, so why not have some snow?

Today, I loaded up the Xmas demo level that was completed for FREEZE64 fanzine (see here...) to see how I made the Level 1 forest look all icy and Christmassy, took ideas from that and incorporated them into Level 9.  Then I had to make it snow.

I started quite simple.  The log cabin background was plastered with a single 'snow' char that depicted a few pixels and that char was then slide repeatedly downwards using a simple bit of code.  That was quite effective, but I wanted more.  I added a little more code to slide the snow char left after the downwards movement and now there was quite the little blizzard blowing, with snow falling diagonally down/across the screen.

To cut a long story short, I spent most of the rest of today experimenting with variations of snowfall - the snow char itself, the speed of 'fall', patterns of fall (including zig-zag patterns) and so on.

In the end, I decided on one of my simple patterns that, although (a lot) less complex than some of the other patterns, works well in the context of the level - there is lot's of movement on screen, but it's not too distracting; some of those more complex patterns drew the eye away from the player sprite and enemies!  Also, it saves me some chars since only 2 are used for the effect!  At present it looks a little like this...


It's quite a subtle pattern that may not even be noticed.  If you look closely, the snow is actually falling in 2 alternating strips (each strip made of one char), perhaps best highlighted in the static image below...


As mentioned, there are only 2 chars being used, each drawn in downwards strips, alternating across the screen - the first char strip is highlighted using a red line in the image above, the second char strip is highlighted in pink.

For this level, the code then animates (slides) the 2 chars downwards, but not at the same time.  Every time the snow routine is called, only one of the char strips is slid downwards, with the other char strip being slid the next time the routine is called.  As a result, you end up with a slight 'jutter' that breaks up the snowfall a little in an attempt to make it look more natural.

The code was quite simple in the end.  I have a variable that remembers whether strip 1 or strip 2 should be moved each time the subroutine is called, the appropriate char is then 'slid' downwards and to finish the strip variable is changed to make sure the alternate strip is slide next run through.  Finally, there is a jump to a small piece of code that resets the background animation timer - as with the majority of the background animations in the game, the snow doesn't fall every 'frame' and on this occasion the snow slides down every fourth frame.


; snowfall anim subroutine  
   
 snow_anim  
           lda snowstrip                 ; which snow strip should move?  
           cmp #$01                      ; strip 2?  
           beq snow_fall2                ; yes? do strip 2 then!  
                                         ; no? then do strip 1!  
 ; move snow strip 1...  
 ; shift snow char 196 a pixel down!  
 ; (char location $2620 to $2627)            
   
 snow_fall1                              ; move strip 1                 
           lda $2627                     ; load up the last byte of the char  
           sta chardown_temp             ; put it in a temporary byte store  
   
 snow_move1  
           lda $2620-$01,x               ; now shift each byte down  
           sta $2620,x                   ; until 7 of the bytes are done  
           dex  
           bpl snow_move1  
        
           lda chardown_temp             ; now put the byte that was originally  
           sta $2620                     ; last into in the first byte of the char  
             
           lda #$01                      ; next time, do snow strip 2!  
           sta snowstrip  
             
           jmp reset_bkgrd_anim_tmr            
   
 ; move snow strip 2...  
 ; shift snow char 197 a pixel down!  
 ; (char location $2628 to $262f)       
   
 snow_fall2                              ; as above, but for snow strip 2!  
           lda $262f  
           sta chardown_temp  
             
 snow_move2  
           lda $2628-$01,x  
           sta $2628,x  
           dex  
           bpl snow_move2  
             
           lda chardown_temp  
           sta $2628  
             
           lda #$00                      ; next time, do snow strip 1!  
           sta snowstrip  
   
           jmp reset_bkgrd_anim_tmr
  

This code can be compacted by using only one slide routine for both strips, inserting the appropriate memory locations for each char as necessary, but as written above, it's nice and easy to read!

Next diary entry...

No comments:

Post a Comment