viernes, 16 de abril de 2010

Enemigos

Hoy hemos visto como programar los diferentes enemigos que van a salir por pantalla.
Hemos visto un poco de teoría sobre Inteligencia Artificial (un poco de culturilla, nada importante) y nos hemos puesto a la tarea.
Lo primero de todo es decidir el comportamiento de nuestro enemigo. Vamos a hacer un enemigo que se mueva en vertical por nuestra pantalla del móvil y que al llegar a una determinada altura (50), se mueva en diagonal.
De paso vemos alguna técnica propia de Java, como es la de crearnos una nueva clase a la que llamamos Enemigos (nos hacemos un nuevo archivo del tipo Clase en Netbeans) que va a extender de la clase Sprite.
El código de la nueva clase es el siguiente:
public Class Enemigos extends Sprite {
    private int Estado, intX, intY;
    public int getEstado(){
       return Estado;
    }
    public void setEstado(int nEstado){
       Estado=nEstado;
    }
    public void calcular_movimiento() {
       Random rdValor=new Random();
       if (getY()>50 && Estado!=2) {
            Estado=2;
            if (Math.abs(rdValor.nextInt() % 2)+1==1) {
                intX=2;
            }
            else
            {
               intX=-2;
            }
      }
      setX(getX()+intX);
      setY(getY()+intY);
    }
    public void Iniciar(){
         intX=0;
         intY=3;
    }
    public Enemigos (nFrames) {
         super(nFrames);
    }
}
Extendemos la clase y definimos un nuevo método para el movimiento, otros métodos para saber y establecer el estado y un método de inicialización de valores. Y ya hemos terminado nuestra nueva clase, que contiene todos los métodos y propiedades de la clase Sprite más los nuevos que acabamos de crear.

Modificaciones en programa principal
Ya tenemos la programación para crear objetos "enemigos". Vamos a crear una programación para mostrarlos de tal forma, que por cada 20 vueltas de nuestro bucle infinito aparezca un objeto enemigo, en una posición X aleatoria. Podemos tener varios a la vez, establecemos que un máximo de 6. Para ello haremos lo siguientes cambios.

Definir las siguientes variables globales:
int intEnemigoLibre;
int ciclos;
Enemigos[] arrEnemigos=new Enemigos[7];
Random rdValor=new Random();

En el método constructor de la clase SSCanvas, inicializamos las variables correspondientes:
public SSCanvas {
    //Inicializar baldosas
    ....
    //Control de enemigos
    ciclos=0;
    for (i=1;i<=6;i++) {
        arrEnemigos[i]=new Enemigos(1);
        arrEnemigos[i].Cargar_Frame(1,"ruta imagen");
        arrEnemigos[i].Off();
    }
}

Una vez inicializadas programamos lo que tiene que pasar en el bucle continuo:
public Run...{
    while (true) {
        //Control de enemigos
            if (ciclos==20) {
                ciclos=0;
                intEnemigoLibre=0;
                //Miramos si hay algún enemigo sin mostrar. Para no pasarnos del máximo de 6 a la vez
                for (i=1;i<=6;i++){
                    if (!arrEnemigos[i].Activado){
                        intEnemigoLibre=i;
                    }
                 }
                 if (intEnemigoLibre!=0) {
                     arrEnemigos[intEnemigoLibre].On();
                     //Mostramos al enemigo en una posX aleatoria dentro de la pantalla
                     arrEnemigos[intEnemigoLibre].SetX(Math.abs(rdValor.nextInt()%getWidth())+1);
                     arrEnemigos[intEnemigoLibre].SetY(0);
                     arrEnemigos[intEnemigoLibre].setEstado(1);
                     arrEnemigos[intEnemigoLibre].Iniciar();
                }
         }
         ciclos=ciclos+1;
         //Actualizamos el movimiento de los enemigos (si están visibles)
         for (i=1;i<=6;i++){
             if (arrEnemigos[i].Activado()) {
                 arrEnemigos[i].Calcular_Movimiento();
                 //Los hacemos desaparecer al llegar a los límites de la pantalla
                 if (arrEnemigos[i].getY()>getHeight() || arrEnemigos[i].getY()<0) {
                    arrEnemigos[i].Off;
                 }
         }

        //Resto de control del loop
        .....
    }
}

Para terminar, solo nos queda dibujar los enemigos activos en el método Paint...
void Paint (Graphics g){
    //Resto de programación baldosas
    ...
    //Control de enemigos
    for (i=1;i<=6;i++){
        if (arrEnemigos[i].Activado()) {
                 arrEnemigos[i].draw(g); 
        }
    }
}

Y listo. La potencia de todo esto, aparte de mostrar enemigos, es que hemos visto como extender clases y demostrado como la nueva clase Enemigos, también conserva las propiedades y métodos de la clase Sprite. Además de los nuevos, claro.

1 comentario:

Lluis Perez dijo...

En la clse Enemigos no se han especificados los métodos setX, setY, getX ni getY por lo que la compilación produce error. Estos métodos tampoco Existen en la clase Sprite de donde extiende Enemigos. La compilación también produce error ya que nFrames no se ha definido.