Eel Animation - UQdeco2800/2022-studio-1 GitHub Wiki

Link back to main page

Eel Animation

The eel animation process consisted of creating a character atlas based on a sprite sheet and utilising the GhostAnimationController class to produce animation.

Character Atlas

The character atlas is responsible for mapping coordinates according to the sprite sheet, and is used to optimise game performance.

Initially, the character atlas was not integrating with the game engine and it was found that it was necessary to have a default option. This was resolved by adding it to the sprite sheet, as the default design if no animations are being played. The rest of the atlas includes 6 frames of animation per direction (four facing directions). In total 25 designs are mapped in the character atlas.

In source/core/assets/images, both the character atlas and sprite sheet exists where it can be referenced in the game engine accordingly.

eel.png
size: 2048, 768
format: RGBA8888
filter: Linear,Linear
repeat: none
bl
  rotate: false
  xy: 0, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 256, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 512, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 768, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1024, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1280, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 1536, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 1792, 0
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 0, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 256, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 512, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 768, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
default
  rotate: false
  xy: 1024, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1024, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1280, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1536, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1792, 256
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 0, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 256, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 512, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 768, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 1024, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 1280, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 1536, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 1792, 512
  size: 256, 256
  orig: 256, 256
  offset: 0, 0
  index: -1

Implementation

Ghost Animation Controller

In this class the animations are initialised is responsible for playing animation when an event is triggered.

 @Override
  public void create() {
    super.create();
    animator = this.entity.getComponent(AnimationRenderComponent.class);
    entity.getEvents().addListener("wanderStart", this::animateWander);
    entity.getEvents().addListener("chaseStart", this::animateChase);

    //Eel animations for each direction
    entity.getEvents().addListener("fr", this::animateFrontRight);
    entity.getEvents().addListener("fl", this::animateFrontLeft);
    entity.getEvents().addListener("br", this::animateBackRight);
    entity.getEvents().addListener("bl", this::animateBackLeft);
  }

 void animateFrontLeft(){animator.startAnimation("fl");}
  void animateFrontRight(){animator.startAnimation("fr");}
  void animateBackRight(){animator.startAnimation("br");}
  void animateBackLeft(){animator.startAnimation("bl");}

Ranged Enemy Movement Task

The Ranged enemy movement task is responsible for the movement of the ranged enemies. A class, animationDirection was added to check which way the character should be facing by comparing its own position to the target. After this an animation in the desired direction is called.

//Class takes input of target values and compares current position
    private void animationDirection(int xValue, int yValue ) {
        //Eel current position
        int eelCurrentPosX = (int)this.owner.getEntity().getPosition().x;
        int eelCurrentPosY = (int)this.owner.getEntity().getPosition().y;

        checkAnimations();
        if (eelCurrentPosX < xValue && eelCurrentPosY > yValue) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).startAnimation("fr");
        } else if (eelCurrentPosX < xValue && eelCurrentPosY < yValue) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).startAnimation("br");
        } else if (eelCurrentPosX > xValue && eelCurrentPosY > yValue) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).startAnimation("fl");
        } else if (eelCurrentPosX > xValue && eelCurrentPosY < yValue) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).startAnimation("bl");
        }

        this.owner.getEntity().getComponent(AnimationRenderComponent.class).scaleEntity();
        this.owner.getEntity().setScale(1.2f, 1.2f);
    }

Furthermore, a checkAnimation class was added to ensure animations had been added to the game engine before calling an animation to play. This was added in comparison to adding the animation each time as animations should only be added to the game engine once.

//Checks all animation directions
    private void checkAnimations() {
        if (!(this.owner.getEntity().getComponent(AnimationRenderComponent.class).hasAnimation("fr"))) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).
                    addAnimation("fr", 0.1f, Animation.PlayMode.LOOP);
        }

        if (!(this.owner.getEntity().getComponent(AnimationRenderComponent.class).hasAnimation("br"))) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).
                    addAnimation("br", 0.1f, Animation.PlayMode.LOOP);
        }

        if (!(this.owner.getEntity().getComponent(AnimationRenderComponent.class).hasAnimation("fl"))) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).
                    addAnimation("fl", 0.1f, Animation.PlayMode.LOOP);
        }

        if (!(this.owner.getEntity().getComponent(AnimationRenderComponent.class).hasAnimation("bl"))) {
            this.owner.getEntity().getComponent(AnimationRenderComponent.class).
                    addAnimation("bl", 0.1f, Animation.PlayMode.LOOP);
        }
    }

Starfish Animation

Character Atlas

starfish.png
size: 1792, 64
format: RGBA8888
filter: Linear,Linear
repeat: none
default
  rotate: false
  xy: 0, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 0, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 64, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 128, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 192, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 256, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 320, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fr
  rotate: false
  xy: 384, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 448, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 512, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 576, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 640, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 704, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 768, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
br
  rotate: false
  xy: 832, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 896, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 960, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1024, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1088, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1152, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1216, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
fl
  rotate: false
  xy: 1280, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1344, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1408, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1472, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1536, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1600, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1664, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1
bl
  rotate: false
  xy: 1728, 0
  size: 64, 64
  orig: 64, 64
  offset: 0, 0
  index: -1