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.
