Maquinas de estados

En la entrada de hoy voy a explicar el concepto de ‘maquina de estado’ (no se si se llama asi, pero asi lo aprendi yo). Basicamente  es separar el codigo en diferentes ‘bloques’ que se ejecutaran segun un numero de estado. Para el caso que nos compete, que son los jugadores, vamos a diferenciar el estado de los mismos en 4:

  • STATUS 0: Inicializacion del jugador
  • STATUS 1: Animacion de entrada: una pequeña animacion, durante la cual el jugador es inmune a los disparos (si no otro jugador lo suficientemente habilidoso directamente no lo dejaria jugar)
  • STATUS 2: El codigo de deteccion de movimientos, etc (todo lo que estaba hasta ahora)
  • STATUS 3: Animacion de muerte del jugador

Entonces, si yo tengo una variable statusJP, en base al valor de la misma voy a ejecutar un codigo u otro. Esto en C seria algo asi:


  switch(statusJP1) {
    case 0 : // inicializacion de todas las vars de jugador 1
        statusJP = 1;
        break;
    case 1 : // animacion entrada
             if (condicion_terminacion_animacion_entrada) {
               statusJP = 2;
             }
             break;
    case 2 : // estado normal de juego
             .
             .
             .
             .
             break;
    case 3 : // muerto
             // animacion muerte 
             // y lo que necesitemos
             if (termino_animacion_muerte) {
               statusJP = 0;
             }
             break;
  }
  

En assembler es un un poquito mas complicado, ya que no disponemos de la instruccion switch. Aqui muestro el codigo del player 2 (lo limpie un poco, para que no quede kilometrico – el codigo original esta en el repositorio).


animatePlayer2
                                   ; -------------- STATUS 0 -------
          ldx            statusJP2 
          cpx            #0
          bne            @statusJP2_1
                                   ; INIT SPRITE JP2
          ldx            #233      ; posicionamos jetpac 2
          stx            sprx2
          ldx            #0        ; que salga desde arriba de la pantalla...
          stx            spry2     
          lda            #ptrJPLeft      
          sta            sprpoint2  ; jet pac 2 mirando a la izquierda
                        
          ldx            #1        
          stx            statusJP2 
          
@statusJP2_1                       ; -------------- STATUS 1 -----------------
                                   
          ldx            statusJP2 
          cpx            #1        
          bne            @statusJP2_2
          
          inc            spry2      
          ldy            spry2      
          cpy            #50       
          beq            @set_statusJP2_2
          
          jmp            @exit     
          
@set_statusJP2_2
          ldx            #2
          stx            statusJP2
          
          
@statusJP2_2                       ; -------------- STATUS 2 -----------------------
                                   ; todo el codigo que estaba antes va aqui...
          
          
@statusJP2_3                       ; --------------- STATUS 3 -----------------
             
          ldx            gravityCounter2
          dex
          stx            gravityCounter2
          cpx            #$0       
          bne            @exit
          ldx            #gravity
          stx            gravityCounter2

          inc            fallCounter2
          lda            spry2
          adc            fallCounter2
          sta            spry2
          
          ldx            sprpoint
          cpx            #ptrJPRight  ; si esta mirando a la derecha
          bne            @decxspr2    ; decrementa sprx
         
          lda            sprx2
          adc            fallCounter2  ; si mira a la izq incrementa
          sta            sprx2      
          jmp            @chkFloor  
          
@decxspr2 
          lda            sprx2     
          sbc            fallCounter2
          sta            sprx2      
          
          
@chkFloor
          jsr            checkFloorP2
          cpx            #1        
          bne            @exit
          
          ldx            #0      
          stx            fallCounter2

          ldx            #0        
          stx            statusJP2
          

@exit                             
          rts
; ------------- end of main animatePlayer2 ---------------------------                

Para muestra, aqui tengo un videos, observen que cuando recibe un tiro sale disparado hacia atras, a diferencia de antes, que se corria 3 mugrosos pixeles. Mi idea ademas es hacer una pequeña animacion con una explosion, que lo voy a dejar para el proximo post.

Como siempre, el codigo completo lo pueden bajar desde el repositorio:
https://github.com/moonorongo/jp_wars.git
Hasta la proxima!

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s