Реализовал анимацию взрыва. Оказалось всё довольно-таки не просто. Обойтись одним объектом не получалось никак. Да и ещё сложность была в том, что анимация взрыва по краям и в центре разная. Но, обо всё по порядку.
Во-первых, сделать всё одним объектом нельзя, ибо у меня объекты прямоугольной формы, а тут нужно крестообразный объект реализовать. В итоге сделал класс Boom для взрыва, который содержит массив частей взрыва =D
public class Boom {
TimerTask task;
Timer timer;
Array<BoomPart> boomParts = new Array<BoomPart>();
...
public Boom(Array<BoomPart> boomParts){
this.boomParts = boomParts;
name = "Boom";
state = State.NONE;
createTimer();
}
//взрыв живёт всего 0.5 секунд
//после этого меняем статус на BOOM...
//тогда при следущем рендеринге мы этот объект удаляем
private void createTimer(){
task = new TimerTask(){public void run(){state = State.BOOM;}};
timer=new Timer();
timer.schedule(task,500);
}
Ну, ясно всё. Класс по сути является лишь контейнером, этот объект никогда не отрисовывается, рендерятся его части:
public class BoomPart {
public static float SIZE = 1f;
protected Vector2 position = new Vector2();
protected Rectangle bounds = new Rectangle();
//думаю, типы очевидны)
public static enum Type {MIDDLE, UP, DOWN, LEFT, RIGHT, HORIZONTAL, VERTICAL}
Type type;
//текущий фрейм
public float animationState = 0;
public BoomPart(Vector2 pos, Type type){
this.position = pos;
this.bounds.width = SIZE;
this.bounds.height = SIZE;
this.type = type;
}
//в зависимости от типа части выбирается начальный фрейм для отрисовки
private void changeAnimationFrame(){
switch(type){
case MIDDLE:
animationState = Boom.SPEED*16;
break;
case HORIZONTAL:
animationState =Boom.SPEED*20;
break;
...
}
}
//метод вызывается при рендеринге
//здесь мы возвращаем какой кадр надо отрисовать из спрайта
public float getAnimationState(){
animationState+=Gdx.graphics.getDeltaTime();
return animationState;
}
public void setType(Type type){
this.type = type;
changeAnimationFrame();
}
public Vector2 getPosition() {
return position;
}
public Rectangle getBounds() {
return bounds;
}
}
Ну а при рендеринге отрисовываем нужный кадр из Animation, про который можно прочитать в прошлой статье.
private void drawBooms(){
for(Boom boom : world.getBooms())
for(BoomPart boomPart: boom.getParts())
spriteBatch.draw(animations.get(Boom.Name).getKeyFrame( boomPart.getAnimationState(),true), (boomPart.getPosition().x - cam.position.x+CAMERA_WIDTH/2)* ppuX, boomPart.getPosition().y * ppuY,BoomPart.SIZE * ppuX, BoomPart.SIZE * ppuY);
}
Если кто-то хочет помочь с тестированием, можете скачать Bomberman v1.2.