DragonBonesJS icon indicating copy to clipboard operation
DragonBonesJS copied to clipboard

Phaser 3 restart the scene armature not animate

Open jentleyonadoss opened this issue 4 years ago • 7 comments

when I star scene newly all animation are working very good but once I restart the scene all armature are not animating

jentleyonadoss avatar Apr 26 '20 12:04 jentleyonadoss

Too. i think it's a phaser 3 problem. After scene chenging armature don't loading any more...

MadDogMayCry0 avatar Jun 25 '20 06:06 MadDogMayCry0

Hey, guys! Sorry I just saw this. I had this problem ages ago, but digging in the source code was able to solve it. Before switching scenes or restarting, you need to destroy the armature and clear the dragonbones pool. I typically put the scene change inside of a setTimeout, just to be sure. So example:

`this.player.armature.destroy(); this.dragonbone.factory.clear(true); dragonBones.BaseObject.clearPool();

setTimeout(()=>{ this.scene.start('nextScene'); }, 20);`

@jentleyonadoss @Stasikiii I hope this helps! If you have questions, let me know and maybe I can answer!

faradaym avatar Sep 04 '20 19:09 faradaym

@faradaym Hi. Ths for answer this. But i have no property armature of my player.

this.load.dragonbone("player","characters/player/player_tex.png","characters/player/player_tex.json","characters/player/player_ske.json"); player=SceneMain.add.armature(skin, name); player.armature.destroy();

player.armature.destroy is not a function

and whe i can find this.dragonbone.factory.clear(true); and what mean "this" in your's case? A Scene?

SceneMain.dragonbone.factory.clear(true); not a function! :(

Pls help. :(

MadDogMayCry0 avatar Sep 22 '20 14:09 MadDogMayCry0

@Stasikiii in your case, player is the armature, so just call destroy on it directly.

dragonbone is a property of a Scene, so dragonbone.factory.clear(true) needs to be run from within a Scene, or from an object with access to the Scene.

photonstorm avatar Sep 22 '20 15:09 photonstorm

@photonstorm Hello, Richard. Glad to answered my question, but i still stuck on this last Month :(

I moved those lines of code you did pointed for me, but still no effect :( after scenes chenging my dragonbones character every time disapeart.

My scene:

var SceneMain = new Phaser.Scene('SceneMain');
SceneMain.preload = function(){
        player.destroy();
	SceneMain.dragonbone.factory.clear(true);
	dragonBones.BaseObject.clearPool(true);
	
	SceneMain.load.dragonbone("doc",
	"characters/doc/doc_tex.png",
	"characters/doc/doc_tex.json",
	"characters/doc/doc_ske.json");
	clickHandler(SceneMain);
	
	player=SceneMain.add.armature("doc", "doc_test");
}

No errors, game runned normaly.

MadDogMayCry0 avatar Sep 22 '20 17:09 MadDogMayCry0

That code really doesn't look right to me. Some obvious things:

  1. SceneMain is an instance of a Scene, so from within a method of it you should be calling this.dragonbone to get the Scene level property. You really shouldn't be overriding preload like this, either. See below for a much cleaner approach.

  2. You cannot do add.armature in the preload function. None of the data has even loaded by that point, so you cannot then create your player from it. All calls to add._anything_, that relies on assets being preloaded, should happen in the Scene create method, or later.

  3. There looks to be lots of confusion with your JS scope. Global properties, open accessors, etc. There is almost certainly code outside of what you've shown influencing what is going on here.

I would use a much more standard approach to your Scenes, like the following (assuming ES6, but easy to backport to ES5 if you need):

export class SceneMain extends Phaser.Scene
{
    constructor ()
    {
        super('SceneMain');
    }

    preload ()
    {
        this.load.dragonbone("doc",
            "characters/doc/doc_tex.png",
            "characters/doc/doc_tex.json",
            "characters/doc/doc_ske.json"
        );
    }

    create ()
    {
        this.player = this.add.armature('doc', 'doc_test');

        this.events.once('shutdown', this.shutdown, this);

        //  Do stuff, when finished, move to another Scene, this will trigger the shutdown event
    }

    shutdown ()
    {
        this.player.destroy();

        this.dragonbone.factory.clear(true);
	    
        dragonBones.BaseObject.clearPool(true);
    }
}

const config = {
    width: 800,
    height: 600,
    backgroundColor: 0x0,
    plugins: {
        scene: [
            { key: "DragonBones", plugin: dragonBones.phaser.plugin.DragonBonesScenePlugin, mapping: "dragonbone" }
        ]
    },
    scene: [ SceneMain ]
};

new Phaser.Game(config);

Obviously, you cannot just run this code directly. But you should clearly see the approach. The scope of your calls is of paramount importance in JavaScript.

photonstorm avatar Sep 22 '20 19:09 photonstorm

@photonstorm thx for answer. I don't sure about ES6, i can't try on this moment becuse of error about export. I tryed and created a new scene with content below. No success. As scene will be changed - character disapert.

One more. I adding some code in dragonBones.js in line 16042 after "textureAtlasData = dragonBones_3.BaseObject.borrowObject(phaser.display.TextureAtlasData);" -> console.log(textureAtlasData); Iis calling 3 times! Maby it's helps to some one fix this buggy plugin for Phaser 3 :( but this time it's not usable at all.

Now I don't even know what to do with all of this. :(

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
    <script src="api/phaser.js"></script>	
	<script src="api/dragonBones.js"></script>
</head>
<script>
class SceneMain extends Phaser.Scene {

    constructor ()
    {
        super('SceneMain');
    }

    preload ()
    {
        this.load.dragonbone("doc",
            "characters/doc/doc_tex.png",
            "characters/doc/doc_tex.json",
            "characters/doc/doc_ske.json"
        );
    }

    create ()
    {
        this.player = this.add.armature('doc_test', 'doc');
		this.player.setPosition(300, 500);
		this.player.animation.play("idle");
		
		this.input.on('pointerup', function (pointer) {

            this.scene.start('SceneMain2');

        }, this);
		this.events.once('shutdown', this.shutdown, this);
    }

    shutdown ()
    {
		console.log("*****************");
        this.player.destroy();
        this.dragonbone.factory.clear(true);
        dragonBones.BaseObject.clearPool(true);
    }
}

class SceneMain2 extends Phaser.Scene {

    constructor ()
    {
        super('SceneMain2');
    }

    preload ()
    {
        this.load.dragonbone("doc",
            "characters/doc/doc_tex.png",
            "characters/doc/doc_tex.json",
            "characters/doc/doc_ske.json"
        );
    }

    create ()
    {
        this.player = this.add.armature('doc_test', 'doc');
		this.player.setPosition(500, 500);
		this.player.animation.play("idle");
		this.input.on('pointerup', function (pointer) {

            this.scene.start('SceneMain');

        }, this);
		this.events.once('shutdown', this.shutdown, this);
    }

    shutdown ()
    {
        console.log("!!!!!!!!!!!!!!!");
		this.player.destroy();
        this.dragonbone.factory.clear(true);
        dragonBones.BaseObject.clearPool(true);
    }
}

const config = {
			type: Phaser.WEBGL,
			scale: {
				mode: Phaser.Scale.FIT,
				autoCenter: Phaser.Scale.CENTER_BOTH,
				width: 1920,
				height: 1080
			},
			audio: {
				noAudio: true
			},
			plugins: {
				scene: [
					{ key: "DragonBones", plugin: dragonBones.phaser.plugin.DragonBonesScenePlugin, mapping: "dragonbone" }
				]
			},
			scene: [ SceneMain,SceneMain2 ]
		};

var game = new Phaser.Game(config);
</script>

With no succes :(

MadDogMayCry0 avatar Sep 22 '20 20:09 MadDogMayCry0