I keep up with doing it the easy way – hope later optimizations do work out.
I implemented the first enemy spawn – the dreaded “X” enemy :-).
Nothing very generic yet. Enemy object structure is two fold:
a) the definition of the enemy sprite/type:
;*************************************************************************** enemyXList: DB $00, +$3F, -$3F ; mode, y, x DB $02, -$7E, +$7E ; mode, y, x DB $00, +$00, -$7E ; mode, y, x DB $02, +$7E, +$7E ; mode, y, x DB $01 ; endmarker (1) enemyXObject: db 1 ; type 1 dw draw_vlcp ; draw routine dw enemyXList ; vectorlist list db 100 ; anim Delay db 10 ; size db $ff ; start scale db $7f ; intensity db 0 ; offsety db 0 ; offsetX dw enemyXObject ; next object after anim ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
That is the ROM structure that will be used for each enemy (at least until changed). It allows for setting all attributes needed.
b) Upon spawning of an in game object the RAM structure will be created and filled, which looks like:
struct ObjectStruct ds TYPE,1 ; enemy type ds SCALE,1 ; scale to position the object ds ANGLE,2 ; if angle base, angle in degree ds ANIM_COUNTER,1 ; jmp to current draw routine ds Y_POS,1 ; current position ds X_POS,1 ds CURRENT_LIST,2 ; current list vectorlist ds DRAW_ROUTINE,2 ; jmp to current draw routine ds ORIGIN,2 ; pointer to original object definition ds SHOT_ACTIVE,1 ds CHILD_ONE,2 ; tail of kite - or active shot ds CHILD_TWO,2 ds HIT_COUNT,1 ds DISPLAY_COUNT,1 ; time for scores to appear (max $ff ticks) ds BONUS_COUNT,1 ; max bonus = 255 ds filler, 11 end struct
Not all entries will be needed for all objects, and depending on how much other RAM I use later – there might be optimizations.
The structure above allows the definition of vectorlists with different draw routines, which might come handy. Also if U register is setup correctly doing a “pulu d,x,pc” (or similar) can be used to initiate a draw “directly” from above structure.
The only implemented enemy (spawn) for now is the “X” which is the most basic enemy, since it just slowly moves towards the player base. Spawn timer is implemented.
All enemies are held in a list of above structures in RAM. Upon destroying an enemy the list gets “cleaned” – the empty position is immediatly reused with the last object and the list counter decreased.
Next steps:
I will do one complete enemy before doing other stuff – next will be eliminating an enemy with a shield. Than possibly an “explosion” display.
Steps after that:
– one enemy after another
– starfield display has been postponed 🙂
For testing purposes an “X” enemy spawns every 1/2 seconds and just “vanishes” upon reaching the player base:
I keep saying optimizations have been postponed… here is an example of what that looks like. My draw routines, while already “outsourced”, very badly just call the BIOS routine and are thus more “pessimizations” than anything else:
*********************************************************** ; obviously non optimized! ; ; list in x ; list: ; counter ; move y,x ; draw y,x * count drawRotated: ldd 1,x jsr Moveto_d lda ,x leax 3,x jsr Draw_VL_a rts ; like draw_vlc with additional pattern byte befor each coordinate ; pattern byte is taken "directly" and used as shift value draw_vlcp: JSR Draw_VL_mode ; Vectrex BIOS print routine rts