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