Sprites – Movimiento en X (bit 8) #Mauro Cifuentes

En el post de hoy tenia pensado ir implementando un generador de números aleatorios, para que a intervalos de tiempo vayan cayendo tanques de combustible con los que recargar los Jets. Pero decidi introducir unos cambios gracias a que MI amigo Pablo Borobia se bajo el codigo e introdujo unos cambios para que los jugadores se muevan por toda la pantalla.

Originalmente no puse esa caracteristica porque implica un poco mas de programación, y conocimientos que al principio del tutorial no tenía. Hay que  chequear si ocurre un desbordamiento de carro y setear un bit extra, para posicionar el sprite en una parte de la pantalla u otra.

Un poco de teoría

La posicion X de los sprites se guardan en las direcciones $d000, $d002,  …. $d00e. Ahora bien, una posicion de memoria tiene una longitud de 8 bits, con lo que nos permite posicionar el sprite en las posiciones de 0 a 255 en la pantalla… y nuestra pantalla tiene 320 pixels de ancho (la parte central, no contemos los bordes, que se pueden abrir y mostrar los sprites alli… pero eso es una historia mas avanzada).

Para ello necesitamos utilizar el registro del VIC II que esta en la direccion $d010. Este tiene el bit 8 que nos falta de cada uno de los sprites, correspondiendo el bit 0 al bit 8 del sprite 0, bit 1 al sprite 1… bit 7 al sprite 7. Por ejemplo, la posicion X del sprite 0 nos queda determinada por la direccion $d000 y el bit 0 de la posicion $d010.

Y esto como lo trabajamos?

Buena pregunta, hay montones de forma, una que me parecio bastante correcta es la implementacion que a continuación voy a explicar (para el jugador 1, luego tenemos que ampliar todo al jugador 2, los disparos, etc.)

  @chkLeft lda joy2    and #4 ; left   bne @chkRight       jsr checkFloorP1 ; solo se mueve si esta volando   cpx #1    beq @chkRight      lda #ptrJPLeft ; pone sprite mirando a la izquierda   sta sprpoint      ; CODIGO ANTERIOR   ; inc sprx     ; NUEVO CODIGO   sec ; seteo el carry, ya que voy a decrementar A   lda sprx ; cargo en A posicion X sprite jugador 1   sbc #1 ; y resto 1   bcc @chkOvrL ; si ocurre acarreo, llamo a checkOverflowP1   sta sprx ; si no, estamos en la de antes, actualizo posicion X   jmp @chkRight ; sigo checkeando el resto ...    @chkOvrL jsr checkOverflowP1 ; subrutina para controlar Bit 8 del jugador 1   sta sprx ; actualizo posicion, con el bit 8 actualizado  

Y mas adelante (al final de la maquina de estados):

  ; ------------- end of main animatePlayer1 ---------------------------     ; verifica posicion X, setea bit 8 spr 0  checkOverflowP1   tax ; guardo A en X (lo necesito despues)   lda sprxBit8 l cargo en A $d010   eor #1 ; invierto el bit 1 (jugador)   ; es simple: si ocurre un acarreo, es bit se invierte   ; es todo lo que hay que hacer :)    ; a lo sumo me quedará inicializarlo en 0   ; en initVars.asm   sta sprxBit8    txa ; restauro A, ya que al retornar tengo un STA...    rts  

Y eso es todo, tenemos que repetir este codigo (con las variables/etiquetas que correspondan) para animatePlayer2, y ver como lo agregamos en la parte de codigo de los disparos… no demasiado complicado.

Y creo que eso es todo.

No: me faltó agregar la variable sprxBit8 = $d010, en vars.asm, si no este codigo no anda ni para atras…

Como siempre, el codigo completo lo pueden bajar desde el repositorio:
https://github.com/moonorongo/jp_wars.git
Ahora si,  en la próxima entrega vamos a implementar un generador simple de numeros pseudoaleatorios, el que utilizaremos para que aparezcan cayendo tanques de combustible.
Hasta la proxima!



Editar

Josepzin

No hay comentarios:

Publicar un comentario