Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
0
Members

[2D Animation] Making an animation not loop is not working. HELP

A topic by TeuFox created Oct 20, 2017 Views: 579 Replies: 8
Viewing posts 1 to 6

this.actor.spriteRenderer.setAnimation("Crouch",false);  

API: this.actor.spriteRenderer.setAnimation(String " ",looping? boolean);  

No matter what I do I cannot get this animation to not loop, and I have tried to go the long way by using "wait" functions but I could not figure out how to do that either, please help!

If you upload your project file (or at least just your spritesheet), I can help you with this.

(1 edit)

The crouch frames are frame 8 and 9 (Sorry for the late response)

Alright, so I just set-up a quick project and so far everything is working as expected.


Where are you placing the line:

this.actor.spriteRenderer.setAnimation("Crouch",false);

If it's in an update-loop (or any loop that is getting repeatedly called for that matter), it's probably just looping over that line and constantly playing the crouch animation.


Could you paste your code for me to see?

(+1)

I will do that once I get to work! Thank you so much for your help

(2 edits)

I agree with Spencer. If crouch is set in your update function, it will be called repeatedly. You need a state variable to guard against repeatedly calling crouch, like:

if (action that causes crouch) {

   if (!this.crouching) { this.actor.spriteRenderer.setAnimation("Crouch", false); this.crouching = true; }

}


(I don't know how to do quote code yet...)

Sup.ArcadePhysics2D.setGravity(0, -0.02);

class PlayerBehavior extends Sup.Behavior {
  speed = 0.08;
  jumpSpeed = 0.35;
  frameSpeed = 1;
  reverseSpeed = -1;

  update() {
    Sup.ArcadePhysics2D.collides(this.actor.arcadeBody2D, Sup.ArcadePhysics2D.getAllBodies());

    // As explained above, we get the current velocity
    let velocity = this.actor.arcadeBody2D.getVelocity();

    // We override the `.x` component based on the player's input
    if (Sup.Input.isKeyDown("DOWN"))  {
      this.actor.spriteRenderer.setAnimation("Crouch",true);  
      velocity.x = 0.000001;
      //this.actor.spriteRenderer.setPlaybackSpeed(this.frameSpeed);
      
    }else if (Sup.Input.isKeyDown("RIGHT")) {
      velocity.x = this.speed;
      this.actor.spriteRenderer.setAnimation("Walk");
      this.actor.spriteRenderer.setPlaybackSpeed(this.frameSpeed);
    } else if (Sup.Input.isKeyDown("LEFT")) {
      velocity.x = -this.speed + 0.02;
      this.actor.spriteRenderer.setAnimation("Walk");
      this.actor.spriteRenderer.setPlaybackSpeed(this.reverseSpeed);
      //velocity.x = this.speed - 0.08;
    } else {
      velocity.x = 0;
    }
      

    // If the player is on the ground and wants to jump,
    // we update the `.y` component accordingly
    let touchBottom = this.actor.arcadeBody2D.getTouches().bottom;
    if (touchBottom) {
      if (Sup.Input.wasKeyJustPressed("UP")) {
        velocity.y = this.jumpSpeed;
        this.actor.spriteRenderer.setAnimation("Jump");
      } else {
        // Here, we should play either "Idle" or "Run" depending on the horizontal speed
        if (velocity.x === 0) {
          this.actor.spriteRenderer.setAnimation("Idle");
          this.actor.spriteRenderer.setPlaybackSpeed(this.frameSpeed);
        } else {
          if (velocity.x === 0.000001) {
            this.actor.spriteRenderer.setAnimation("Crouch",false);
          }
        }
        
      }
    } else {
      // Here, we should play either "Jump" or "Fall" depending on the vertical speed
      if (velocity.y >= 0) this.actor.spriteRenderer.setAnimation("Jump");
      else this.actor.spriteRenderer.setAnimation("Fall");
    }

    // Finally, we apply the velocity back to the ArcadePhysics body
    this.actor.arcadeBody2D.setVelocity(velocity);
  }
}
Sup.registerBehavior(PlayerBehavior);

(1 edit)

I built on top of the preset built into SuperPowers. PLEASE NOTE IT SAYS true BUT THAT WAS JUST A TEST

Alright, so here's the issue:

 if (Sup.Input.isKeyDown("DOWN"))  {
      this.actor.spriteRenderer.setAnimation("Crouch",true);  

Your animation isn't actually looping, it's just constantly being restarted and applied to the character.


The function:

Sup.Input.isKeyDown('KEY-NAME')

runs every update loop (60 times a second). So, if you're holding down the key, this if statement will return true and run the code inside every frame. Hence, your sprite is constantly setting it's animation to "Crouch" and is looking like it's looping the animation.


To fix this, you can set a variable at the beginning of the behavior and check against it, like this:

class PlayerBehavior extends Sup.Behavior {
 crouching = false;
 update() {
  if( Sup.Input.isKeyDown("DOWN") ) {
   if( !this.crouching ) {
    this.actor.spriteRenderer.setAnimation("Crouch", false);
    this.crouching = true;
   }
  } else if( this.crouching ) {
    this.actor.spriteRenderer.setAnimation("Idle", false);
    this.crouching = false;
  }
 }
}

This way, the code will only set the animation once, and prevent 'looping' the animation every frame you're holding the button down for.


Another way to fix this, is to use:

Sup.Input.wasKeyJustPressed("KEY-NAME")

which will only run once when the key is first pressed down.


If you need any more info, let me know!