Bomberman v1.2: добавлена анимация взрыва

Bomberman

Реализовал анимацию взрыва. Оказалось всё довольно-таки не просто. Обойтись одним объектом не получалось никак. Да и ещё сложность была в том, что анимация взрыва по краям и в центре разная. Но, обо всё по порядку.

Во-первых, сделать всё одним объектом нельзя, ибо у меня объекты прямоугольной формы, а тут нужно крестообразный объект реализовать. В итоге сделал класс 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.