Main Menu Title Animation Code Implementation - UQdeco2800/2022-studio-2 GitHub Wiki

Introduction

A great once said, "A cool animation makes the game dope." That is exactly why we want to add an innovative and stylish title animation in the main menu display as an optimisation feature. Challenges you might faced during programming:

  1. How do I let the animation automatically play as soon as the game is launched?
  2. How do I actually implement the Animation?
  3. How do I implement the seemingly basic and easy animation loop?
  4. How do I make the animation run at the same time with the static main menu?

If you are interested in the design process of main menu title animation and how user testing is conducted, please refer to: Main menu title animation design

Animation auto-start as game start

The key of solution is to have a great understanding of MainMenuDisplayProMax.java and MainMenuScreen.java. Specifically, the logic is to implement the animation play within the addActor(). If you look closer, addActor() is running inside of create() and update(), this means it will be initialised/called as soon as the game object is instantiated. Additionally, putting addActor() into update() will grant it with iterator's characteristics since update() is responsible for constantly updating the game frames.

Therefore, to make the animation start together with game launch, we need to initialise main menu display and main menu screen at the same time with game launch event, we can achieve this through:

// In main menu screen: 
  public MainMenuScreen(GdxGame game) {
      this.game = game;
      loadAssets();
      createUI();
  }
// In main menu display:
    @Override
  public void create() {
      frame=1;
      super.create();
      addActors();
  }

Animation loop (count, pull, and reset)

In preious section, we talked about how addActor() is granted with iterators property. We use the same old trick again, putting all the frames (190 frames in total) all in a list, and the list size is the same as frameCount. While the game frames are constatnly updating, initialise a counter and keep record of frame counter, when the game time is passed one second, frame counter will increment, and the first title animation frame will be pulled out from the list and so on. With that bearing mind, when the frame counter reaches 190, the game will either automatically exit or the animation will be frozen at last frame. In order to resolve this issue, we add an else statement, else when frame counter reaches 190, reset the counter to zero again, so that the count and pull operation will be repeat forever. In another word, this can be considered as brute-force hardcoded while loop in libGdx, see use case:

        if (frame < MainMenuScreen.frameCount) {
            transitionFrames = new Image(ServiceLocator.getResourceService()
                    .getAsset(MainMenuScreen.transitionTextures[frame], Texture.class));
                                            .
                                            .
                                            .
            frame++;
                                            .
                                            .
        } else {
            frame=0;
        }

Animation run with static main menu together

The reason why this becomes a challenge is to simplify the title animation logic. Specifcally, it is discussed that it is more efficient to only design the animation frames as half size of the static menu, in that case, the original button positioning will not be changed, and designing animation frames with the full screen size will make the main menu button click logic hard to maintain. Therefore, after discussing with the design side, we finally agreed on using half-sized animation frames to be placed on the actual interactive main menu, this will look something like this:

(Note that the green area is the original static menu, and the red part is where we want the title animation frames to play at.)

To achieve this, we want to first display the animation together with the static menu, it is done through setting the priority of loadFrames() the same as loadAsset(). In simpler terms, perform loading frames operation within loading asset operation:

  private void loadAssets() {
    logger.debug("Loading assets");
    ResourceService resourceService = ServiceLocator.getResourceService();
    resourceService.loadTextures(mainMenuTextures);
    loadFrames();                                                        <- look at this line :)
    resourceService.loadMusic(mainMenuMusic);
    ServiceLocator.getResourceService().loadAll();
  }

Further reading

For those of you who still does not know how to implement animations and loading animations, please check out this amazing documentation by a dedicated author or gain some insipirations by looking at the animation sequence and class structure from this amazing team.

Who to talk to

Yingzheng Cai (@Rey_cyz#1464 on discord, @Rey-666 on github)