Player interaction Sprint4 - UQdeco2800/2021-ext-studio-1 GitHub Wiki
In this sprint, we redesigned all player interaction animations, improved some functions and fixed some bugs.
- 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.
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;
}
}
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);
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);
}
}
- 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++;
}
}
Sequence diagram for attackfrequency control
.
Sequence diagram for death animation
.
Sequence diagram for background music control.
.
The diagram shows the relationship between RagnorakRacer class and RainbowBridge class.
.
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);
}
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.