Player interaction Sprint4 - UQdeco2800/2021-ext-studio-1 GitHub Wiki

Sprint4

In this sprint, we redesigned all player interaction animations, improved some functions and fixed some bugs.

Player interaction animation improvement

  • According to previous user testing, most participants believe that the character facing to the right instead of facing to the player can be more reasonable with the forward direction of the game.
  • In addition, a couple people were confused regarding the character's hair colour. They expected Thor's hair color to be Blonde, like in the movie. Therefore, we changed the character's hair color to yellow instead of red, which is more reasonable with the identity background of the game character.

Running animation(default status)

Attack enemy animation

Touch enemy animation

Collect coin animation

Buff animation

Debuff animation

Death animation

Improve the functions and fix some bugs

Attack frequency

According to previous user testing, setting an attack frequency will allow players to have a better gaming experience.

  • Add variables "attackCount" and "attackTrigger" to set conditions for judgment.
  • Through the "update()" method, update the variable "attackCount". This method is executed once every frame.
  • In the "attack()" method, it is judged whether the variable "attackCount" or "attackTrigger" reaches the conditions. If the conditions are reached, the player can successfully attack the enemy.
private int attackCount = 0;
private boolean attackTrigger = false;

public void update() {
    if(animator7.getCurrentAnimation() != null){
      animator5.stopAnimation();
    }
    if(animator5.getCurrentAnimation() == null) {
      animator5.startAnimation("run");
    }
    if(animator.getCurrentAnimation() != null || animator2.getCurrentAnimation() != null|| animator3.getCurrentAnimation() != null || animator4.getCurrentAnimation() != null || animator6.getCurrentAnimation() != null){
      animator5.stopAnimation();
    }
    if (animator2.isFinished() || animator3.isFinished() || animator4.isFinished() || animator6.isFinished()){
      animator2.stopAnimation();
      animator3.stopAnimation();
      animator4.stopAnimation();
      animator6.stopAnimation();
      animator5.startAnimation("run");
    }
    if (moving) {
      updateSpeed();
    }
    if(attackTrigger) {
      attackCount += 1;
    }
  }

void attack() {
    if(attackCount > 150 || attackTrigger == false){
      attackTrigger = true;
      logger.info("attack",attackTrigger);
      Array<Entity> entities = ServiceLocator.getEntityService().getEntities();
      Entity nearest = findNearestTargets(entities);
      if (nearest != null) {
        if (nearest.getType().equals(Entity.Type.GHOST) || nearest.getType().equals(Entity.Type.GHOSTKING)) {
          nearest.dispose();
        }
      }
      Sound attackSound = ServiceLocator.getResourceService().getAsset("sounds/attack.ogg", Sound.class);
      attackSound.play();
      animator5.stopAnimation();
      animator.startAnimation("attack");
      attackCount = 0;
    }
  }

Animations speed

According to previous user testing, changing suitable animations speed will allow players to have a better gaming experience.

After several tests, we found the most suitable animation speed for different animations

animator.addAnimation("attack", 0.1f, Animation.PlayMode.NORMAL);

animator2.addAnimation("touch", 0.3f, Animation.PlayMode.NORMAL);

animator5.addAnimation("run", 0.07f, Animation.PlayMode.LOOP);

animator3.addAnimation("buff", 0.1f, Animation.PlayMode.NORMAL);

animator4.addAnimation("deBuff", 0.1f, Animation.PlayMode.NORMAL);

animator6.addAnimation("coin", 0.08f, Animation.PlayMode.NORMAL);

animator7.addAnimation("death", 0.1f, Animation.PlayMode.NORMAL);

Coin problem

Fix the bug of the coin

Due to the characters are making bugs when collecting gold coins and diamonds, resulting in the crushing of the game. Changes were made to the physical collision of coin and diamond instances. Fixed a problem with gold coins

public void hitCoin(CombatStatsComponent attacker) {
    try {
      if (ServiceLocator.getTimeSource().getTimeSince(invincibleStart) < 1000L) {
        return;
      }

      if (attacker.getEntity().getType() == Entity.Type.PLAYER) {
        logger.error("attacker--{}", attacker.getEntity().getType(),attacker.getEntity());
        AnimationRenderComponent6 animator =
                attacker.getEntity().getComponent(AnimationRenderComponent6.class);
        animator.startAnimation("coin");
                Sound coinSound = ServiceLocator.getResourceService().getAsset(
                "sounds/coin.ogg", Sound.class);
        coinSound.play();

        try {
          Sound deBuffSound = ServiceLocator.getResourceService().getAsset(
                  "sounds/e.ogg", Sound.class);
          deBuffSound.play();
        } catch (GdxRuntimeException e) {
          //pass;
        }
        logger.error("--end--attacker--{}",attacker.getEntity().getType());
      }

//      if (armour > 0){
//        int newArmour = getArmour() - attacker.getBaseAttack();
//        setArmour(newArmour);
//        invincibleStart = ServiceLocator.getTimeSource().getTime();
//      }
//      else{
//        int newHealth = getHealth() - attacker.getBaseAttack();
//        setHealth(newHealth);
//        invincibleStart = ServiceLocator.getTimeSource().getTime();
//      }

    } catch (NullPointerException e) {
      int newHealth = getHealth() - attacker.getBaseAttack();
      setHealth(newHealth);
    }

  }

Duplication of background music

Fix the bug of duplication of background music.

  • Add variable "musicSign" as the judgment condition.
  • Through the method "musicControl()", determine whether the variable "musicSign " meets the requirements, so that background music can be played.
private static int musicSign = 0;

private void musicControl(){
    if (musicSign == 0){
        playMusic();
        musicSign++;
    }
}

UML diagram

Sequence diagram

Sequence diagram for attackfrequency control .

Sequence diagram for death animation .

Sequence diagram for background music control.

.

Class diagram

The diagram shows the relationship between RagnorakRacer class and RainbowBridge class. .

Unit Testing

Improve the unit test of class "PlayerActions"

Test the attack frequency.

@Test
    public void attackFrequencyTest1() {
        if(attackTrigger) {
            attackCount += 1;
        }
        assertFalse(attackTrigger);
        assertEquals(0, attackCount);
    }

    @Test
    public void attackFrequencyTest2() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            if(attackTrigger) {
                attackCount += 1;
            }
        }
        assertTrue(attackTrigger);
        assertEquals(1, attackCount);
    }

    @Test
    public void attackFrequencyTest3() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            if(attackTrigger) {
                attackCount += 1;
            }
        }
        if (attackCount > 150 || !attackTrigger) {
            if(attackTrigger) {
                attackCount += 100;
            }
        }
        assertTrue(attackTrigger);
        assertEquals(1, attackCount);
    }

    @Test
    public void attackFrequencyTest4() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            while (true) {
                attackCount += 1;
                if (attackCount == 150) {
                    break;
                }
            }
        }
        assertTrue(attackTrigger);
        assertEquals(150, attackCount);
    }

    @Test
    public void attackFrequencyTest5() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            while (true) {
                attackCount += 1;
                if (attackCount > 150) {
                    break;
                }
            }
        }
        assertTrue(attackTrigger);
        assertEquals(151, attackCount);
    }

    @Test
    public void attackFrequencyTest6() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            while (true) {
                attackCount += 1;
                if (attackCount > 150) {
                    break;
                }
            }
        }
        attackCount = 0;
        assertTrue(attackTrigger);
        assertEquals(0, attackCount);
    }

    @Test
    public void attackFrequencyTest7() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            while (true) {
                attackCount += 1;
                if (attackCount > 150) {
                    break;
                }
            }
        }
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = false;
        }
        assertFalse(attackTrigger);
        assertEquals(151, attackCount);
    }

    @Test
    public void attackFrequencyTest8() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            while (true) {
                attackCount += 1;
                if (attackCount > 150) {
                    break;
                }
            }
        }
        if (attackCount > 150) {
            attackCount += 1000;
        }
        assertTrue(attackTrigger);
        assertEquals(1151, attackCount);
    }

    @Test
    public void attackFrequencyTest9() {
        if (attackCount > 150 || !attackTrigger) {
            attackTrigger = true;
            while (true) {
                attackCount += 1;
                if (attackCount > 150) {
                    break;
                }
            }
        }
        if (!attackTrigger) {
            attackCount += 1000;
        }
        assertTrue(attackTrigger);
        assertEquals(151, attackCount);
    }

Changes to plan

We originally planned to add an animation when the player jumps between lanes. This was inspired by the change lane animation in Subway Surfer. It shows animation not only when the player is on the lanes but also when the player is between two lanes. But in our RagnorakRacer game, when the user presses key to change lane, the player will disappear from the original position, and will directly show at the destination position, there’s no intermediate position change. So, the animation could only be played on some points on the map. Therefore, the idea of adding animation for jumping between lanes could not be realized in this game. So, we gave up this idea.

⚠️ **GitHub.com Fallback** ⚠️