domingo, 25 de julio de 2021

libGDX: Colisiones con sprites animados (imágenes animadas)

En este tutorial vamos a hacer una modificación al código del tutorial anterior para agregar una explosion cada vez que dos objetos del mismo tipo colisionan

Antes de comenzar recuerda que puedes descargar el código completo en Github y si lo prefieres puedes ver el video tutorial de este articulo.


También puedes correr la aplicación de este tutorial en tu navegador.

En la siguiente imagen puedes ver el resultado de la colisión entre dos objetos:

Vamos a hacer una pequeña modificación en la clase GameObject ahora vamos a tener 3 estados que van a ser: normal, explosion y eliminar:

static final int STATE_NORMAL = 0;
static final int STATE_EXPLODE = 1;
static final int STATE_REMOVE = 2;

También debemos conocer la duración de la animación y el tiempo transcurrido entre cada estado. Para eso voy a agregar el siguiente código:

static private class GameObject {
	//...más código
	static final float EXPLOSION_DURATION = 0.95f;
	float stateTime;
}

La variable stateTime guarda el tiempo entre estados y ayudará a saber exactamente qué imagen de la animación debemos dibujar en pantalla.

También debemos modificar el la función hit porque ahora los estados son diferentes:

public void hit() {
	if (state == STATE_NORMAL) {
		state = STATE_EXPLODE;
		stateTime = 0;
	}
}

Como pueden ver solamente una objeto con estado STATE_NORMAL puede pasar a estado STATE_EXPLODE. Esto para evitar que un objeto explotando al ser colisionado por otro objeto vuelva a explotar.

Y cuando un objeto entra al estado STATE_EXPLODE después de que pase el tiempo transcurrido EXPLOSION_DURATION lo tenemos que cambiar al estado STATE_REMOVE, todo esto lo vamos a hacer en el update:

public void update(Body body, float delta) {
	if (state == STATE_NORMAL) {
		position.x = body.getPosition().x;
		position.y = body.getPosition().y;
		angleDeg = (float) Math.toDegrees(body.getAngle());
	} else if (state == STATE_EXPLODE) {
		if (stateTime >= EXPLOSION_DURATION) {
			state = STATE_REMOVE;
			stateTime = 0;
		}
	}
	stateTime += delta;
}

El siguiente paso es agregar las imagenes de la explosion a nuestro proyecto y cargarlas en el constructor de nuestro ejemplo:

public Learn7(MainLearn game) {
	super(game);
	//...más código

	TextureRegion exp1 = Utils.getRegion("data/explosion/explosion1.png");
	TextureRegion exp2 = Utils.getRegion("data/explosion/explosion2.png");
	TextureRegion exp3 = Utils.getRegion("data/explosion/explosion3.png");
	//...cargar las 19 imágenes

	explosion = new Animation<>(0.05f, exp1, exp2, exp3,
				exp4, exp5, exp6, exp7, exp8, exp9,
				exp10, exp11, exp12, exp13, exp14,
				exp15, exp16, exp17, exp18, exp19);
}

Y por último no hay que olvidar dibujar la explosion en la función drawGameObjects para esto tenemos que verificar el estado, si es STATE_NORMAL dibujamos una caja o pelota, si es STATE_EXPLODE dibujamos la explosion y cualquier otra cosa no dibujamos nada:

private void drawGameObjects() {
	for (GameObject obj : arrGameObjects) {
		TextureRegion keyframe;

		if (obj.state == GameObject.STATE_NORMAL) {
			if (obj.type == GameObject.BOX)
				keyframe = box;
			else
				keyframe = ball;

			spriteBatch.draw(keyframe, obj.position.x - .15f, obj.position.y - .15f, .15f, .15f,.3f, .3f, 1, 1, obj.angleDeg);
		}
		
		if (obj.state == GameObject.STATE_EXPLODE) {
			spriteBatch.draw(explosion.getKeyFrame(obj.stateTime), obj.position.x - .15f, obj.position.y - .15f,.15f, .15f, .3f, .3f, 1, 1, obj.angleDeg);
		}
	}
}
    

0 comments:

Publicar un comentario

Entradas populares