top of page
Search
  • Writer's pictureTom Grove

Flying Shark : Object Logic

Every object has a type field ( 0x5 ) that selects a tick routine. The tick routine for a bomb power-up is shown below (link to video). This object simply moves down the screen. If it collides with the player, the player receives an additional bomb unless they are already at the max.

TickBombPU                                         
          LD         A,(IY +0xd )	; ycoord LSB
          ADD        A,0x20             ; i.e. 1 in in 8.5 fixed point
          LD         (IY +0xd ),A
          JR         NC,LAB_ram_c327    ; no overflow, otherwise ..
          INC        (IY +0xe )         ; inc MSB
LAB_ram_c327                                    
	  BIT        0x7 ,(IY +0x14 )   ; check for player collision 
          JR         Z,LAB_ram_c347	; jp there's no collision ...
          LD         IX ,(CurrentPlayerPtr)  ; get player state ptr
          LD         A,(IX +0x9 )       ; get the number of bombs 
          CP         0x7                ; >= 7 ?
          JR         NC,LAB_ram_c34d  	; ... then player has max bombs
          INC        (IX +0x9 )		; inc the player's bombs
          LD         HL ,DirtyFlags     ; set "status" dirty flag
          SET        0x2 ,( HL => DirtyFlags )						
          LD         A,0x5 		; index 5 into score table 
          CALL       AwardPoints        ; add to score
          JR         LAB_ram_c34d	; .. and done
LAB_ram_c347                                      
          LD         A,(IY +0xe )       ; didn't collide - get ycoord
          CP         0x1b               ; check off screen
          RET        C		        ; if less still visible return
LAB_ram_c34d                                     
          LD         HL ,BombPUSpawned   ; ... dec bomb spawned flag
          DEC        (HL => BombPUSpawned )
          LD         HL ,FreeObjectCount ; inc number of free objects				
          INC        (HL => FreeObjectCount )
          CALL       DecWaveNumberNoAward   ; remove the object												
          RET

The routine is quite compact; this is due to keeping the collision logic outside of the object tick functions and deferring the score updates via dirty flags that are read outside the ISR. Note that we are working in 8.5 fixed point, which leads to the confusing addition of 32 ( 0x20 ) to increment the y position by 1. Anyone who was looked at lots of zx spectrum assembly is pretty much hard-wired to think that an addition of 32 "must" be advancing by one character row, which is not the case here.


The object is removed by the code below LAB_ram_c34d. This updates a bomb spawned flag, which is used along with other flags in logic that chooses what power-up the player should be supplied with next. The object is then returned to the free list in DecWaveNumberNoAward. For objects which are part of waves, this would also update the wave instance, but would not generate a power-up award. This is normally called when an object is removed for reasons ( e.g. leaving the screen ) other than the player destroying it.


For objects with more complex behaviour, flying shark uses a simple script/pattern system. Each object in a wave can be assigned a pattern id which drives its behaviour. The planes that appear at the start ( and throughout ) stage 1 use this system.


EnemyPlane0
	db         22h  ;   Orientation =  OrientFlag  ? 16 : 16     
			;   AddVelocity
        db         83h	;   Repeat 3
        db         28h	;   	SteerTowardsPlayer
			; 	AddVelocity
        db         90h	;   Repeat 16
        db         10h	;	AddVelocity
        db         38h	;   OrientFlag = CoinFlip
        db         81h	;   Repeat = Random(32)
        db         10h	; 	Add Velocity
        db         86h	;   Repeat 6
        db         5Bh	;       Orientation += OrientFlag ?  3 : -3
			;	AddVelocity
        db         C0h	;   Repeat 64
        db         10h	;	Add Velocity
        db         20h	;   Set Finished
        db         0h	;   ZeroVelocity

The planes initially point down the screen. Orientations are in the range 0-63, with 0 degrees facing along the positive x-axis. A value of 16 is a rotation of 90 degrees They then steer towards the player for 3 frames, then travel in a straight line for 16 frames. The orientation flag is then set to a random value. The planes travel straight for a further random number of frames, then rotate nearly 90 degrees to either the left or right ( determined by the randomly set orientation flag ) and fly straight for a further 64 frames. The objects are then removed.


This script covers most of the 13 opcodes. Many scripts are much simpler than this one. E.g. when an enemy plane is killed, it sometimes goes into a death spiral. The script for this is simply:

EnemyPlaneDying
	db         88h	;  Repeat 8
        db         5Bh	;     Orientation += Flag[7] ?  3: -3
        db         20h	;     AddVelocity

This is not a full blown language by any stretch, but it does allow the game to be authored at a higher level of abstraction that z80 assembly.


Assembly at https://github.com/tomgrove/FlyingSharkBlog. The routine TickObjects handles all the object ticking.

39 views0 comments

Recent Posts

See All

Flying Shark: Collision Detection

Given two game objects, how do we determine if they overlap? By far the most common technique in 8-bit game development is to compare the extents of the two objects and see if they overlap. The extent

bottom of page