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!
No hay comentarios:
Publicar un comentario