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!


