Manage automatic movement of the enemy sprites in assembly

Par gasparrini

Champion (335)

Portrait de gasparrini

16-03-2013, 22:51

Hello Dears Guys of MSX !! (O_*)

Manage automatic movement of the enemy sprites in assembly

I have a little problem to handle the frames of the sprite enemies with automatic movement.

The problem is this:

For the moment this routine that I report below, it works well!
But it only works with two sprite frames is towards the left in
the right direction.

Instead I would like to modify it as follows:
I would like to sprite to 4 frames, that is 2 frames for each direction for left and right.

So this routine in assembly must be changed again.

Example with format:

2 frames with animation <--- (left) | 2 frames with animation ---> (right).

I wait your good news.....
Best Regards
(^_^)
AG.

; [YOUR GROUP] MSX Z80 source file.
;
; Prog: automatic movement of 2 sprites enemies
; Code: ANDREA GASPARRINI E ARTURO RAGOZINI
; Date: 18 giugno 2005
; 
; last modified by Danysoft
; cmnt: con la gentile collaborazione di Arturo Ragozini
;
; Coded in TeddyWareZ' Chaos Assembler 3
;
; (C) 2013 GameCast Entertainment 

;#include "macro's.asm"

; routine esempio per velocità di animazione a 2 fotogrammi per sprites
;       anim_spr:

;       jp anim_SPEED  <== metti questa

;ld a,(anim_dummy)
;inc a
;cp 10
;jr nz,anim_spr0
;ld a,0
;anim_spr0:
;ld (anim_dummy),a

;ld a,(anim_dummy)
;cp 5
;ret nz


;anim_SPEED:
;ld ix,spritedata1

;ld a,(ix+2)
;xor 4
;ld (ix+2),a

;ld a,(ix+6)
;xor 4
;ld (ix+6),a
;ret


	.org $BE00 - 7

	.db $fe
	.dw startProgram,endProgram,startProgram

startProgram:
; vdp ports
;
vdpport0   .equ 098h        ; vram read/write
vdpport1   .equ 099h        ; vdp registers read/write
vdpport2   .equ 09ah        ; palette registers write
vdpport3   .equ 09bh        ; indirect register write
svdp0      .equ $f3e7       ; posizione in memoria del s0

main:  ; routine principale
	jp start_main
		; questi sono per dare alla BASIC (W.bas)
	.dw spr_mov_1	;data base sprite 1
	.dw spr_mov_2	;data base sprite 2
	.dw spritedata1    ;data attrib sprite 1
	.dw spritedata2    ;data attrib sprite 2
	
start_main:
    call movesprt  ; routine movimento sprite nemici 
    call anim_spr	; by DanySoft Animazione dei 2 sprites
    ld hl,$1b10 ; address define sprite
    call setvramaddr_w
    ld bc,2*4*256+vdpport0 ; 2 sta per 2 sprite
    ld hl,spritedata1
    otir

    RET  ; RETURN BASIC

	;0,1,2,3 sprite 1
	;4,5,6,7 sprite 2
anim_spr:
	ld a,(anim_dummy)
	inc a
	cp 3      ; velocità animazione  10
	jr nz,anim_spr0
	ld a,0
anim_spr0:
	ld (anim_dummy),a
		
	ld a,(anim_dummy)
	cp 1      ; velocità animazione 5
	ret nz

	ld ix,spritedata1
	
	ld a,(ix+2)
	xor 4
	ld (ix+2),a
	
	ld a,(ix+6)
	xor 4
	ld (ix+6),a
	ret

movesprt:
    ld ix,spritemov
    call nextstep
    ld ix,spritemov2

nextstep:

    ld a,(ix+0)
    dec a ; decrementa contatore passi
    ld (ix+0),a
    call z,nextdir

    ld e,(ix+1) ; prende offeset xy
    ld d,(ix+2)
    ld l,(ix+6)
    ld h,(ix+7) ; hl ora punta alla posizione nella tabella degli
                ; attributi sprite relativi allo sprite corrente
    push hl     
    pop ix      ; IX <= HL
    call movexy ;
    ret

nextdir ; cambia direzione
    ld a,(ix+3)
    dec a
    ld (ix+3),a
    call z,initdir

    ld l,(ix+4)
    ld h,(ix+5)
    ld a,(hl) ; aggiorna conta-passi
    ld (ix+0),a
    inc hl
    ld e,(hl) ; aggiorna direzione
    inc hl
    ld d,(hl)
    ld (ix+1),e
    ld (ix+2),d
    inc hl
    ld (ix+4),l
    ld (ix+5),h
    ret

initdir:
    ld l,(ix+8)
    ld h,(ix+9)
    ld (ix+4),l
    ld (ix+5),h
    dec hl
    ld a,(hl)
    ld (ix+3),a

    ret

movexy:
   ld a,d
   add a,(ix+0)
   ld (ix+0),a
   ld a,e
   add a,(ix+1)
   ld (ix+1),a
   ld a,(ix+2)
   xor 1
   ld (ix+2),a
   ret

setvramaddr_w:
   di
   ld  a,l
   out (vdpport1),a
   ld  a,h
   or  001000000b
   out (vdpport1),a
   ei
   ret


; ROUTINES MOVIMENTO SPRITE NEMICI AUTOMATICI
dir:
   .dw 0000  ; fermo
   .dw $fB00 ; up
   .dw $fB04 ; muove in diagonale
   .dw $0001 ; right
   .dw $0101 ; muove in diagonale
   .dw $0100 ; down
   .dw $01fB ; muove in diagonale
   .dw $00fB ; left
   .dw $fBfB ; muove in diagonale
   
spritemov:
    .db 1       ; conta quanti passi restano
    .dw 0       ; mantine l'offeset xy corrente
    .db 1       ; conta quanti cambi di direzione restano
    .dw movedata ; punta alla direzione corrente
    .dw spritedata1 ; punta a quale piano sprite fa riferimento
    .dw movedata ; punta alla direzione iniziale
    
spritemov2:
    .db 1 ; conta quanti passi restano
    .dw 0 ; mantine l'offeset xy corrente
    .db 1 ; conta quanti cambi di direzione restano
    .dw movedata2 ; punta alla direzione corrente
    .dw spritedata2 ; punta a quale piano sprite fa riferimento
    .dw movedata2 ; punta alla direzione iniziale
spr_mov_1:    
    .db 4        ; numero di direzioni ; @DIR
movedata:
    .db 160      ; numero di passi   	;0-160
    .dw $0004    ; move right			;@DIR1
    .db 160      ; numero di passi        ;0-160
    .dw $00fB    ; move left			;@DIR2
    .db 160      ; numero di passi        ;0-160
    .dw $0004    ; move right			;@DIR3
    .db 160      ; numero di passi        ;0-160
    .dw $00fB    ; move left			;@DIR4
spr_mov_2:    
    .db 4        ; numero di direzioni
movedata2:
    .db 160      ; numero di passi
    .dw $00fB    ; move left
    .db 160      ; numero di passi
    .dw $0004    ; move right
    .db 160      ; numero di passi
    .dw $00fB    ; move left
    .db 160      ; numero di passi
    .dw $0004    ; move right
    .db 4        ; numero di direzioni

; settaggi iniziali INIT SPRITES y, x, n.spr, colore
anim_dummy:	.db 0
spritedata1:
    .db 127,104,80,12  ; sprite nemico 1
spritedata2:
    .db 87,100,80,7 ;  sprite nemico 2



endProgram:

.end
!login ou Inscrivez-vous pour poster

Par Edwin

Paragon (1182)

Portrait de Edwin

19-03-2013, 23:41

I'm not going to try and put it into the code (Italian comments hurt my head Tongue ), but I'll give you a decent method.

Usually, one will take care of part of the problem by assigning convenient numbers to sprite patterns. Something like this for instance (I'm assuming 16x16 sprites):

16 - left, frame 1
20 - left, frame 2
24 - right, frame 1
28 - right, frame 2

In binary, these pattern numbers are:

7654 3210 <= bit number
=========
0001 0000
0001 0100
0001 1000
0001 1100

If you look carefully, you see that bit 2 is the frame number and bit 3 is the direction.

Now you can separate the two problems:
1: Animation simply becomes a timed "xor 4" of the sprite pattern.
2: Setting the direction becomes an "or 8" to set the direction to the right and an "and 255-8" to set the direction to the left.

If different types of enemies simply have their patterns aligned at 16, then this method works regardsless of the base pattern you selected. I'll leave the exercise to put this into the code to you.

Par gasparrini

Champion (335)

Portrait de gasparrini

20-03-2013, 23:00

hmmm ..... I understand ..... well, in short ....

I apologize if you really need some comments are in Italian,
then I apologize to the whole community of this forum.

Unfortunately for me it is not easy to put into practice this assembly code
I requested, I know you from the beginning we want to put my hand on this source in assembly,
but I insist some of you a volunteer, I could put into practice the advice of your precious you notes.

So people! Come forward to solve this little problem I have in question.
good job....
I wait your good news.....
Best Regards
(O_o)
AG.