Home > Mobile >  Stop animation at specific frame?
Stop animation at specific frame?

Time:12-07

I'm making a game with Phaser, and I need to have an animation for the health bar going down dynamically stop on a frame, and I couldn't find any clear documentation on the stopOnFrame() method, or the this.anims.getFrame(index) method, both of which woulden't work. I believe that stopOnFrame accepts a frame object, not a frame number but I coulden't figure out how to get that specific frame, as the getFrame() method returned undefined. If there's something I'm missing, my ideal solution looks something like this:

this.hpBar.play({key: 'damageAnimation', startFrame: this.hp})
this.hpBar.stopOnFrame(this.hpBar.getFrame(this.hp - amountOfDamage))

Thanks for any suggestions, cheers!

PS: I know there's some more nuance to how I would use the animations in forwards and reverse to properly create this effect, the example is purely for demonstration.

CodePudding user response:

It looks like you're trying to use the stopOnFrame() method in the Phaser game engine to stop a playing animation on a specific frame. This method does exist, but it's not clear from your question how you're using it or what problems you're encountering.

One possible solution would be to use the stop() method instead of stopOnFrame(), which will stop the animation immediately at its current frame. If you want to stop the animation on a specific frame, you can use the setFrame() method to set the animation to the desired frame before calling stop().

// Start playing the animation
this.hpBar.play({key: 'damageAnimation', startFrame: this.hp})

// Set the animation to the desired frame
this.hpBar.setFrame(this.hp - amountOfDamage)

// Stop the animation
this.hpBar.stop()

CodePudding user response:

You have to pass the Phaser frame and I think the function getFrame doesn't exist. And the index has to be a valid integer. (btw.: here is the link to the documenation of the stopOnFrame function)

Info: the frame index-count, is based on the frames of the specific animation, not the frame in the spritesheet.

Here a Demo:

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    scene: {
    preload,
        create
    },
    banner: false
}; 

function preload(){
this.load.spritesheet('brawler', 'http://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
       
}

function create () {
    this.add.text(10,10, 'Click, to Stop on kick (third frame)')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});


       this.anims.create({
            key: 'kick',
            frames: this.anims.generateFrameNumbers('brawler', { frames: [ 10, 11, 12, 13, 10 ] }),
            frameRate: 8,
            repeat: -1,
            repeatDelay: 0
        });
        
        const cody = this.add.sprite(100, 90);
        cody.setScale(3);
        cody.play('kick');
                
         this.input.on('pointerdown', () => {
            cody.stopOnFrame(cody.anims.currentAnim.getFrameAt(2))
         })
}

new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

but for a healt-bar, I would use a tween.

Here a demo how I would do it:

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    scene: {
        create
    },
    banner: false
}; 

function create () {
    this.add.text(10,10, 'Click, to animate healthbar')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
        this.healthbarBG = this.add.rectangle(10, 50, 100, 10, 0xffffff)
            .setOrigin(0)
         this.healthbar = this.add.rectangle(12, 52, 100 - 4, 10 - 4, 0xff0000)
            .setOrigin(0)
                
         this.input.on('pointerdown', () => {
            // remove 50% health
            let newHealthWidth = this.healthbar.width * .5;
            this.tweens.add({
                targets: this.healthbar,
                width: newHealthWidth,
                duration: 750,
                ease: 'Power2'
            });
         })
}

new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

  • Related