# Making the player a "global object"

**URL:** <https://phaser.discourse.group/t/making-the-player-a-global-object/15509>\
**Category:** Phaser 3\
**Created:** [October 22, 2025, 7:15pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509 "2025-10-22T19:15:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 22, 2025, 7:15pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/1 "2025-10-22T19:15:29Z")

</div>

I was wondering, is there any way to make the player a different object or scene that can interact with other scenes with this code structure? (for example: different stages)

This is an example of what I have for the character set-up inside the stage (if you want to have a closer look to the whole code, the GitHub repo is [righ here](https://github.com/HootsAndTheSuperstars/HootsAndTheSuperstars.github.io))

```javascript
init(){

 this.charstateWalk = false;
 this.charstateIdle = true;
 this.charstateDead = false;

 this.facingRight = true;
 this.facingLeft = false;

}
create(){
 this.cursors = this.input.keyboard.createCursorKeys(); //for the movement keys
 this.platforms = this.physics.add.staticGroup(); //The platforms, should be behind the player
 this.player = this.physics.add.sprite(100, 450, 'player'); //This creates the player itself
 this.anims.create({
   key: 'idle',
   frames: [{ key: 'player', frame: 0 }],
   frameRate: 20
   }); //for the idle animation (just 1 frame for now)
 this.anims.create({
    key: 'walk',
    frames: this.anims.generateFrameNumbers('player', { start: 4, end: 7 }),
    frameRate: 10,
    repeat: -1
    }); //for the walking animation
 this.physics.add.collider(this.player, this.platforms, null, (player) => { return (this.player.body.velocity.y >= 0)}); //the platform collider, should be disabled when the character is going upwards (aka. jumping or stunned)
}
update(){
 if(!this.charstateDead){ 
      //This sets the sprite and the movement go ethier left or right
      if(this.facingLeft == true){
        this.player.setFlipX(true);
        console.log("Fliping player anims to the Left")
      }
      else if(this.facingRight == true){
       this.player.setFlipX(false);
       console.log("Fliping player anims to the Right")
    };
    
     //Now we go with the movement handler
     if(this.charstateWalk){
        console.log("State: Walking");
        if(this.facingLeft){
         this.player.setVelocityX(-160);
         console.log("Left, normal speed");
        }
        else if(this.facingRight){
         this.player.setVelocityX(160);
         console.log("Right, normal speed");                
        }
     };
     //Input handler, planned to be compatible with custom keybinding
     if(this.cursors.left.isDown || this.cursors.right.isDown){
       this.charstateWalk = true;
       this.charstateIdle = false;
     }
     else{
       this.charstateIdle = true;
       this.charstateWalk = false;
     };
     // Animation handler, i should find a way to make something similar to "[characterKey]_walk" instead of "char1_walk" and "char2_walk" for optimization when i get to char2
     if(this.Char1){
       if (this.charstateWalk && this.player.body.onFloor())
       {
          this.player.anims.play('walk', true);
       }
       else if(this.charstateIdle){
          this.player.anims.play('idle', true);
       };

     };

  }

}

```

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 22, 2025, 9:32pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/2 "2025-10-22T21:32:49Z")

</div>

If possible, can you share more on what you were looking to do? When you mention interacting with other scenes, in general a game object in one Phaser Scene cannot interact with an another scene. However, there are ways you can pass messages between the two scenes.

Are you looking to just make the code reusable, that way you can use the same logic in multiple scenes?

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 22, 2025, 9:45pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/3 "2025-10-22T21:45:08Z")

</div>

Actually, that’s somewhat what I need, sorry for the inconvinience.

I am looking for having the player code on it’s own file that can be called or re-used between various scenes instead of being in the stage code and having to copy-paste the same code if I make a different stage or gamemode.

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 22, 2025, 9:53pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/4 "2025-10-22T21:53:04Z")

</div>

Thanks for the additional details. For this, there are a few different approaches you can take, but one of the common patterns is to create a class for the Player that would extend the Sprite Game Object. You can then put this Player class in a separate file, and then just create a new instance of that player in the various places you need it.

A good example of this can be seen here: [Phaser - Examples - v3.55.0 - physics - arcade - Extending Arcade Sprite](https://phaser.io/examples/v3.55.0/physics/arcade/view/extending-arcade-sprite). In this example, there is a `SpaceShip` class that extends the Sprite, and in the Phaser Scene, a new instance of the ship is created.

In the player class, you could move all of the logic for the character state, the direction that is being faced, and playing animation.

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 22, 2025, 10:02pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/5 "2025-10-22T22:02:06Z")

</div>

What about the animations? Can I move the `this.anims.create()` I require for the player to the extension too?

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 22, 2025, 10:25pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/6 "2025-10-22T22:25:33Z")

</div>

You can have those as part of the class too, but for creating the animations, this is something that only needs to be done one time for the game, and is not something that needs to be done each time you create a player.

In my past games, I usually did the animation as early as possible after loading in my assets. In your code, this could be done as part of the `PreLoader` scene. If you wanted to keep the logic with the player logic, you could add a static method to the class, or have a function that is exported, that creates those animations. You could also keep the logic in your class constructor, and then check if the animations have already been created in the animation manager, and if so, skip that code.

The reason you only need to run the animation creation logic one time is that the Animation Manager is a system that is shared for the whole Phaser Game instance, and each Phaser Scene references the same animation manager.

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 22, 2025, 11:12pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/7 "2025-10-22T23:12:54Z")

</div>

Great, I have tried what you said, the problem is that it the logic can’t identify the keys ethier in the extension or in the stage in general, is there a way to fix that?

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 23, 2025, 12:52am UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/8 "2025-10-23T00:52:04Z")

</div>

By chance, can you share the code you have? Or if you have it on a branch on the GitHub repo above, I can take a look there.

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 23, 2025, 1:31am UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/9 "2025-10-23T01:31:03Z")

</div>

Of course! The old code is still on the GitHub repo (the file is called “stage.js”) and the code for the player extension is here (might not be the best out there, but it’s something to start with)

```javascript
export class ObjPlayer extends Phaser.Physics.Arcade.Sprite {

    init(){

        //this are the character states (ex. walking, facing left... right... etc)

        //This is especially for flipping the sprites, DO NOT REMOVE

        this.facingRight = true;

        this.facingLeft = false;

        //char check

        this.Char1 = true;

        //background

        //movement spud

        this.charstateWalk = false;

        this.charstateIdle = true;

        this.charstateJump = false;

        this.charstateAbility = false;

        this.charstateFall = false;

        this.charstateHurt = false;

        this.upStun = false;

        this.charstateDead = false;

        this.charstateRun = false;

        this.charstateSkidd = false;

        this.invAfterHit = false;

        this.checkforpreventingSkiddafterStun = false

    }

    constructor (scene, x, y)

    {

        super(scene, x, y, 'dude');

        scene.add.existing(this);

        scene.physics.add.existing(this);

        console.log("Player Created!");

        this.body.setSize(16, 38);

        this.body.setOffset(25, 14);

        console.log("The player's hitbox should be mesured to fit the sprites");

        // Player physics properties. Give the little guy a slight bounce.

        this.setBounce(0);

        this.body.setGravityY(600);

        this.setCollideWorldBounds(true);

        this.debugBodyColor = 0x9048fc;

        console.log("Player's MISC configs should work now...");

        // Our player animations, turning, walking left and walking right

        //Updates

                //char starts here

        if(!this.charstateDead)

        {

        //states for flipping the char

            if(!this.charstateSkidd){

                if(this.facingLeft == true){

                    this.setFlipX(true);

                    console.log("Fliping player anims to the Left")

                }

                else if(this.facingRight == true){

                    this.setFlipX(false);

                    console.log("Fliping player anims to the Right")

                }

            }

            if(!this.charstateHurt && !this.charstateSkidd){

                if(this.cursors.left.isDown && !this.cursors.right.isDown && this.body.velocity.x >= 0){

                    this.facingLeft = true;

                    this.facingRight = false;

                }

                else if(this.cursors.right.isDown && !this.cursors.left.isDown && this.body.velocity.x <= 0){

                    this.facingLeft = false;

                    this.facingRight = true;

                }

            else if((this.cursors.left.isDown && this.cursors.right.isDown || this.cursors.left.isDown && this.cursors.right.isDown)){

                if(this.body.velocity.x > 0){

                    this.facingLeft = false;

                    this.facingRight = true;

                }

                else if(this.body.velocity.x < 0){

                    this.facingLeft = true;

                    this.facingRight = false;

                }

            }

            }

        //now this is where things get spicy

        //states for movement

            if(!this.charstateHurt){

                if(this.charstateWalk && !this.charstateRun && !this.charstateSkidd){

                    console.log("State: Walking");

                    if(this.facingLeft){

                        this.setVelocityX(-160);

                        console.log("Left, normal speed");

                    }

                    else if(this.facingRight){

                        this.setVelocityX(160);

                        console.log("Right, normal speed");                

                    }

                }

                else if(this.charstateRun && this.charstateWalk && !this.charstateSkidd){

                    console.log("State: Running");

                    if(this.facingLeft){

                        this.setVelocityX(-300);

                        console.log("Left, fast speed");

                    }

                    else if(this.facingRight){

                        this.setVelocityX(300);

                        console.log("Right, fast speed");                

                    }

                }

                else if(this.charstateSkidd){

                    console.log("State: Skidding")

                    if(!this.skiddSound.isPlaying && this.body.onFloor()){

                        this.skiddSound.play()

                    }

                    else if(!this.body.onFloor()){

                        this.skiddSound.stop()

                    }

                    if(!this.charstateIdle){

                        if(this.cursors.left.isDown){

                            this.setAccelerationX(-350);

                            console.log("Pushing right");

                        }

                        else if(this.cursors.right.isDown){

                            this.setAccelerationX(350);

                            console.log("Pushing left");                

                        }

                    }    

                    else if(this.charstateIdle){

                        if(this.facingLeft){

                            this.setAccelerationX(350);

                            console.log("Pushing right");

                        }

                        else if(this.facingRight){

                            this.setAccelerationX(-350);

                            console.log("Pushing left");                

                        }

                    }             

                }

                else if(this.charstateIdle){

                    this.setAccelerationX(0);

                    this.setAccelerationY(0);

                    this.setVelocityX(0);

                    console.log("State: idle");

                }

                if(this.charstateJump && !this.charstateFall){

                    this.setVelocityY(-490);

                    console.log("State: Jumping");

                }

                else if(this.charstateFall && !this.charstateJump){

                    this.setAccelerationY(900);

                    console.log("State: Falling");

                }

                else if(this.charstateFall && this.charstateJump){

                    this.setAccelerationY(0);

                    console.log("State: Maintaining jump");

                }

                else if(this.charstateAbility){

                    this.setVelocityX(0);

                    this.setVelocityY(1500)

                    console.log("State: Stomp")

                }

            }

            else if(this.charstateHurt){

                console.log("State: Hurt");

                

                if(this.facingLeft){

                    this.setVelocityX(180);

                    console.log("Pushed right");

                }

                else if(this.facingRight){

                    this.setVelocityX(-180);

                    console.log("Pushed left");                

                }

            }

            if (this.upStun){

                this.body.setVelocityY(-200)

                this.charstateHurt = true;

                this.time.delayedCall(100, () => {

                    this.upStun = false

                })

            }

        }

        else if(this.charstateDead){

            this.setVelocityX(0);

            console.log("State: Dead")

        }

        //input states

        if(!this.charstateHurt){

            //general walk

            if(this.cursors.left.isDown || this.cursors.right.isDown){

                    this.charstateWalk = true

                if(this.keyS.isDown && this.body.onFloor()){

                    this.charstateRun = true

                    if((this.cursors.left.isDown && this.body.velocity.x > 160) || (this.cursors.right.isDown && this.body.velocity.x < -160)){

                        this.charstateSkidd = true

                    }

                    else if((this.cursors.left.isDown && this.body.velocity.x < 160) || (this.cursors.right.isDown && this.body.velocity.x > -160)){

                        this.charstateSkidd = false

                    }

                }

                else if(!this.keyS.isDown || !this.body.onFloor()){

                    this.charstateRun = false

                    this.charstateSkidd = false

                }

                

            }

            //jumping and falling

            if((this.cursors.up.isDown || this.keyD.isDown || this.keySPACEBAR.isDown) && this.body.onFloor()){

                if(!this.jumpSound.isPlaying){

                    this.jumpSound.play()

                }

                this.charstateJump = true;

                this.charstateFall = false;

                this.charstateSkidd = false

            }

            else if(!this.keyA.isDown && !this.cursors.down.isDown){

                if((this.cursors.up.isDown || this.keyD.isDown || this.keySPACEBAR.isDown) && !this.body.onFloor() && this.body.velocity.y < -1){

                    this.charstateJump = true;

                    this.charstateFall = true 

                }

                else if(!this.body.onFloor() && (this.body.velocity.y >= -1 && (this.cursors.up.isDown || this.keyD.isDown || this.keySPACEBAR.isDown) || (!this.cursors.up.isDown || !this.keyD.isDown || this.keySPACEBAR.isDown))){

                    this.charstateJump = false;

                    this.charstateFall = true;

                    this.charstateSkidd = false

                }

            }

            else if(!this.body.onFloor() && (this.keyA.isDown || this.cursors.down.isDown)){

                if(!this.charstateAbility && this.Char1){

                    this.charstateAbility = true;

                    if(!this.activeStomp.isPlaying){

                        this.activeStomp.play()

                    }

                    this.charstateJump = false;

                    this.charstateFall = false;

    

                }

            }

        }

        else if(this.body.onFloor()){

            this.charstateHurt = false;

            this.time.delayedCall(300, () =>{

                this.checkforpreventingSkiddafterStun = false

            })

        };

        if(!this.charstateHurt){

            if((this.body.onFloor() && (!this.cursors.up.isDown && !this.keyD.isDown || this.keySPACEBAR.isDown)|| !this.body.onFloor()) && (!this.cursors.left.isDown && !this.cursors.right.isDown || this.cursors.left.isDown && this.cursors.right.isDown) || (this.body.velocity.x == 0 && (this.body.touching.left || this.body.touching.right))){

                if((this.body.velocity.x >= 150 || this.body.velocity.x <= -150) && !this.checkforpreventingSkiddafterStun){

                    this.charstateSkidd = true

                    this.charstateIdle = true

                }

                else if(this.body.velocity.x < 150 && this.body.velocity.x > -150 || this.checkforpreventingSkiddafterStun){

                    this.charstateIdle = true

                    this.charstateSkidd = false

                }

            }

            else if (this.keyA.isDown || this.cursors.down.isDown || this.keyD.isDown || this.keySPACEBAR.isDown || this.cursors.up.isDown || this.cursors.left.isDown || this.cursors.right.isDown){

                this.charstateIdle = false

            }

            if(this.body.onFloor()){

                this.charstateFall = false;

                this.charstateAbility = false;

            };

            if(this.charstateIdle){

                this.charstateWalk = false;

                

            }

        }

        //gameover ig

        if (this.gameOver)

        {

            this.charstateDead = true;

        }

        if(this.charstateHurt){

            this.checkforpreventingSkiddafterStun = true

        }

        //states for animations per char

        if(this.Char1){

            if(!this.charstateDead && !this.charstateHurt){

                if (this.charstateWalk && this.body.onFloor() && !this.charstateJump)

                {

                    if(!this.charstateSkidd && this.body.velocity.y == 0){

                        if((this.body.velocity.x < 0 && this.body.velocity.x > -199) || (this.body.velocity.x > 0 && this.body.velocity.x < 199)){

                            this.anims.play('walk', true);

                        }

                        else if(this.body.velocity.x <= -200 || this.body.velocity.x >= 200){

                            this.anims.play('run', true);

                        }

                    }

                        else if(this.charstateSkidd){

                        this.anims.play('skidd', true);

                    }

                

                }

                else if (this.charstateJump && this.body.velocity.y <= -1){

                    this.anims.play('jump', true);

                }

                else if (this.charstateFall && this.body.velocity.y >= 1){

                    this.anims.play('fall', true)

                }

                else if(this.charstateAbility && !this.body.onFloor() && !this.charstateFall){

                    this.anims.play('stomp', true)

                }

                else if(this.charstateIdle && this.body.onFloor())

                {

                    if(this.charstateSkidd){

                        this.anims.play('skidd', true);

                    }

                    else{

                        this.anims.play('turn', true);

                    }

                }

            }

            else if(this.charstateDead){

                this.anims.play('dead', true)

            }

            else if (this.charstateHurt && !this.body.onFloor()){

                this.anims.play('hurt', true)

            }

        }

    }

}

```

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 23, 2025, 4:24am UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/10 "2025-10-23T04:24:06Z")

</div>

Thanks for sharing the code. So, for the input logic and moving the character around, you will likely need to make two changes:

First, in the `ObjPlayer` class, you will need to move all of the code below this section `Our player animations, turning, walking left and walking right`to a new method in the class. This new method can be called anything, but `update` probably makes the most sense.

The second change is, this new method would need to be called from the same Phaser Scene that created the player object.

Example code:

```javascript
class StageScene extends Phaser.Scene {
  create() {
    this.cursors = this.input.keyboard.createCursorKeys();
    this.player = new ObjPlayer(this, 100, 450);
  }

  update() {
    this.player.update(this.cursors); // to check the input, we will need to pass this to the player
  }
}

class ObjPlayer extends Phaser.Physics.Arcade.Sprite {
  // existing code that was shared

  // now new method with the input logic
  update(cursors) {
    //input states
    if(!this.charstateHurt){
      if(cursors.left.isDown || cursors.right.isDown){
        this.charstateWalk = true
    }
    // rest of the code
  }
}

```

The main thing here is, you will need to pass the input object to the player class, that way you can check if any keys were pressed.

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 23, 2025, 8:25pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/12 "2025-10-23T20:25:46Z")

</div>

Done! The player now works fine except for the animations and somehow the `keyA` isn’t working (although the `keyA` isn’t big of a priority right now), I have tried using just `this.` instead of `this.anims` as well as just `anims`, but nethier of them worked.

```javascript
export class ObjPlayer extends Phaser.Physics.Arcade.Sprite {

    init(){

        //this are the character states (ex. walking, facing left... right... etc)

        //This is especially for flipping the sprites, DO NOT REMOVE

        this.facingRight = true;

        this.facingLeft = false;

        //char check

        this.Char1 = true;

        //background

        //movement spud

        this.charstateWalk = false;

        this.charstateIdle = true;

        this.charstateJump = false;

        this.charstateAbility = false;

        this.charstateFall = false;

        this.charstateHurt = false;

        this.upStun = false;

        this.charstateDead = false;

        this.charstateRun = false;

        this.charstateSkidd = false;

        this.invAfterHit = false;

        this.checkforpreventingSkiddafterStun = false

    }

    constructor (scene, x, y)

    {

        super(scene, x, y, 'dude');

        scene.add.existing(this);

        scene.physics.add.existing(this);

        console.log("Player Created!");

        this.body.setSize(16, 38);

        this.body.setOffset(25, 14);

        console.log("The player's hitbox should be mesured to fit the sprites");

        // Player physics properties. Give the little guy a slight bounce.

        this.setBounce(0);

        this.body.setGravityY(600);

        this.setCollideWorldBounds(true);

        this.debugBodyColor = 0x9048fc;

        console.log("Player's MISC configs should work now...");

        // Our player animations, turning, walking left and walking right

    }

    update (cursors, keyA, keyS, keyD, keySPACEBAR, skiddSound, jumpSound, activeStomp){

        //Updates

        //sprites

        //char starts here

        if(!this.charstateDead)

        {

        //states for flipping the char

            if(!this.charstateSkidd){

                if(this.facingLeft == true){

                    this.setFlipX(true);

                    console.log("Fliping player anims to the Left")

                }

                else if(this.facingRight == true){

                    this.setFlipX(false);

                    console.log("Fliping player anims to the Right")

                }

            }

            if(!this.charstateHurt && !this.charstateSkidd){

                if(cursors.left.isDown && !cursors.right.isDown && this.body.velocity.x >= 0){

                    this.facingLeft = true;

                    this.facingRight = false;

                }

                else if(cursors.right.isDown && !cursors.left.isDown && this.body.velocity.x <= 0){

                    this.facingLeft = false;

                    this.facingRight = true;

                }

            else if((cursors.left.isDown && cursors.right.isDown || cursors.left.isDown && cursors.right.isDown)){

                if(this.body.velocity.x > 0){

                    this.facingLeft = false;

                    this.facingRight = true;

                }

                else if(this.body.velocity.x < 0){

                    this.facingLeft = true;

                    this.facingRight = false;

                }

            }

        }

        //now this is where things get spicy

        //states for movement

            if(!this.charstateHurt){

                if(this.charstateWalk && !this.charstateRun && !this.charstateSkidd){

                    console.log("State: Walking");

                    if(this.facingLeft){

                        this.setVelocityX(-160);

                        console.log("Left, normal speed");

                    }

                    else if(this.facingRight){

                        this.setVelocityX(160);

                        console.log("Right, normal speed");                

                    }

                }

                else if(this.charstateRun && this.charstateWalk && !this.charstateSkidd){

                    console.log("State: Running");

                    if(this.facingLeft){

                        this.setVelocityX(-300);

                        console.log("Left, fast speed");

                    }

                    else if(this.facingRight){

                        this.setVelocityX(300);

                        console.log("Right, fast speed");                

                    }

                }

                else if(this.charstateSkidd){

                    console.log("State: Skidding")

                    if(!skiddSound.isPlaying && this.body.onFloor()){

                        skiddSound.play()

                    }

                    else if(!this.body.onFloor()){

                        skiddSound.stop()

                    }

                    if(!this.charstateIdle){

                        if(cursors.left.isDown){

                            this.setAccelerationX(-350);

                            console.log("Pushing right");

                        }

                        else if(cursors.right.isDown){

                            this.setAccelerationX(350);

                            console.log("Pushing left");                

                        }

                    }    

                    else if(this.charstateIdle){

                        if(this.facingLeft){

                            this.setAccelerationX(350);

                            console.log("Pushing right");

                        }

                        else if(this.facingRight){

                            this.setAccelerationX(-350);

                            console.log("Pushing left");                

                        }

                    }             

                }

                else if(this.charstateIdle){

                    this.setAccelerationX(0);

                    this.setAccelerationY(0);

                    this.setVelocityX(0);

                    console.log("State: idle");

                }

                if(this.charstateJump && !this.charstateFall){

                    this.setVelocityY(-490);

                    console.log("State: Jumping");

                }

                else if(this.charstateFall && !this.charstateJump){

                    this.setAccelerationY(900);

                    console.log("State: Falling");

                }

                else if(this.charstateFall && this.charstateJump){

                    this.setAccelerationY(0);

                    console.log("State: Maintaining jump");

                }

                else if(this.charstateAbility){

                    this.setVelocityX(0);

                    this.setVelocityY(1500)

                    console.log("State: Stomp")

                }

            }

            else if(this.charstateHurt){

                console.log("State: Hurt");

                

                if(this.facingLeft){

                    this.setVelocityX(180);

                    console.log("Pushed right");

                }

                else if(this.facingRight){

                    this.setVelocityX(-180);

                    console.log("Pushed left");                

                }

            }

            if (this.upStun){

                this.body.setVelocityY(-200)

                this.charstateHurt = true;

                this.time.delayedCall(100, () => {

                    this.upStun = false

                })

            }

        }

        else if(this.charstateDead){

            this.setVelocityX(0);

            console.log("State: Dead")

        }

        if(!this.charstateHurt){

            //general walk

            if(cursors.left.isDown || cursors.right.isDown){

                    this.charstateWalk = true

                if(keyS.isDown && this.body.onFloor()){

                    this.charstateRun = true

                    if((cursors.left.isDown && this.body.velocity.x > 160) || (cursors.right.isDown && this.body.velocity.x < -160)){

                        this.charstateSkidd = true

                    }

                    else if((cursors.left.isDown && this.body.velocity.x < 160) || (cursors.right.isDown && this.body.velocity.x > -160)){

                        this.charstateSkidd = false

                    }

                }

                else if(!keyS.isDown || !this.body.onFloor()){

                    this.charstateRun = false

                    this.charstateSkidd = false

                }

                

            }

            //jumping and falling

            if((cursors.up.isDown || keyD.isDown || keySPACEBAR.isDown) && this.body.onFloor()){

                if(!jumpSound.isPlaying){

                    jumpSound.play()

                }

                this.charstateJump = true;

                this.charstateFall = false;

                this.charstateSkidd = false

            }

            else if(!keyA.isDown && !cursors.down.isDown){

                if((cursors.up.isDown || keyD.isDown || keySPACEBAR.isDown) && !this.body.onFloor() && this.body.velocity.y < -1){

                    this.charstateJump = true;

                    this.charstateFall = true 

                }

                else if(!this.body.onFloor() && (this.body.velocity.y >= -1 && (cursors.up.isDown || keyD.isDown || keySPACEBAR.isDown) || (!cursors.up.isDown || !keyD.isDown || keySPACEBAR.isDown))){

                    this.charstateJump = false;

                    this.charstateFall = true;

                    this.charstateSkidd = false

                }

            }

            else if(!this.body.onFloor() && (keyA.isDown || cursors.down.isDown)){

                if(!this.charstateAbility && this.Char1){

                    this.charstateAbility = true;

                    if(!activeStomp.isPlaying){

                        activeStomp.play()

                    }

                    this.charstateJump = false;

                    this.charstateFall = false;

    

                }

            }

        }

        else if(this.body.onFloor()){

            this.charstateHurt = false;

            this.time.delayedCall(300, () =>{

                this.checkforpreventingSkiddafterStun = false

            })

        };

        if(!this.charstateHurt){

            if((this.body.onFloor() && (!cursors.up.isDown && !keyD.isDown || keySPACEBAR.isDown)|| !this.body.onFloor()) && (!cursors.left.isDown && !cursors.right.isDown || cursors.left.isDown && cursors.right.isDown) || (this.body.velocity.x == 0 && (this.body.touching.left || this.body.touching.right))){

                if((this.body.velocity.x >= 150 || this.body.velocity.x <= -150) && !this.checkforpreventingSkiddafterStun){

                    this.charstateSkidd = true

                    this.charstateIdle = true

                }

                else if(this.body.velocity.x < 150 && this.body.velocity.x > -150 || this.checkforpreventingSkiddafterStun){

                    this.charstateIdle = true

                    this.charstateSkidd = false

                }

            }

            else if (keyA.isDown || cursors.down.isDown || keyD.isDown || keySPACEBAR.isDown || cursors.up.isDown || cursors.left.isDown || cursors.right.isDown){

                this.charstateIdle = false

            }

            if(this.body.onFloor()){

                this.charstateFall = false;

                this.charstateAbility = false;

            };

            if(this.charstateIdle){

                this.charstateWalk = false;

                

            }

        }

            //gameover ig

            if (this.gameOver)

            {

                this.charstateDead = true;

            }

            if(this.charstateHurt){

                this.checkforpreventingSkiddafterStun = true

            }

        

    

        if(this.Char1){

            if(!this.charstateDead && !this.charstateHurt){

                if (this.charstateWalk && this.body.onFloor() && !this.charstateJump)

                {

                    if(!this.charstateSkidd && this.body.velocity.y == 0){

                        if((this.body.velocity.x < 0 && this.body.velocity.x > -199) || (this.body.velocity.x > 0 && this.body.velocity.x < 199)){

                            this.play('walk', true);

                        }

                        else if(this.body.velocity.x <= -200 || this.body.velocity.x >= 200){

                            this.play('run', true);

                        }

                    }

                        else if(this.charstateSkidd){

                        this.play('skidd', true);

                    }

                

                }

                else if (this.charstateJump && this.body.velocity.y <= -1){

                    this.play('jump', true);

                }

                else if (this.charstateFall && this.body.velocity.y >= 1){

                    this.play('fall', true)

                }

                else if(this.charstateAbility && !this.body.onFloor() && !this.charstateFall){

                    this.play('stomp', true)

                }

                else if(this.charstateIdle && this.body.onFloor())

                {

                    if(this.charstateSkidd){

                        this.play('skidd', true);

                    }

                    else{

                        this.play('turn', true);

                    }

                }

            }

            else if(this.charstateDead){

                this.play('dead', true)

            }

            else if (this.charstateHurt && !this.body.onFloor()){

                this.play('hurt', true)

            }

        }

    }

}

```

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 23, 2025, 8:27pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/13 "2025-10-23T20:27:06Z")

</div>

By the way, the player animations are now loaded through the `preloader`

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 23, 2025, 9:38pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/14 "2025-10-23T21:38:40Z")

</div>

For the animations, when you go to play them, are there are any errors or warnings being logged in the browser developer console?

Can you please share the code that was added for the animations in the preloader scene?

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 23, 2025, 9:45pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/15 "2025-10-23T21:45:35Z")

</div>

Here they are! although the problem with the animations is that they don’t actually play, the player just displays the frame that’s called when first created (being this the idle)

```javascript
create (){

        this.anims.create({

            key: 'turn',

            frames: [{ key: 'dude', frame: 0 }],

            frameRate: 20

        });

        this.anims.create({

            key: 'walk',

            frames: this.anims.generateFrameNumbers('dude', { start: 4, end: 7 }),

            frameRate: 10,

            repeat: -1

        });

        this.anims.create({

            key: 'run',

            frames: this.anims.generateFrameNumbers('dude', { start: 8, end: 11 }),

            frameRate: 15,

            repeat: -1

        });

        this.anims.create({

            key: 'skidd',

            frames: this.anims.generateFrameNumbers('dude', { start: 16, end: 17 }),

            frameRate: 15,

            repeat: -1

        });

        this.anims.create({

            key: 'jump',

            frames: this.anims.generateFrameNumbers('dude', { start: 18, end: 19 }),

            frameRate: 10,

            repeat: -1

        });

        this.anims.create({

            key: 'fall',

            frames: this.anims.generateFrameNumbers('dude', { start: 20, end: 21 }),

            frameRate: 10,

            repeat: -1

        });

        this.anims.create({

            key: 'stomp',

            frames: this.anims.generateFrameNumbers('dude', { start: 22, end: 25 }),

            frameRate: 30,

            repeat: -1

        });

        this.anims.create({

            key: 'hurt',

            frames: [{ key: 'dude', frame: 26 }],

            frameRate: 20

        });

        this.anims.create({

            key: 'dead',

            frames: this.anims.generateFrameNumbers('dude', { start: 27, end: 28 }),

            frameRate: 10,

            repeat: -1

        });

}

```

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 23, 2025, 10:23pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/16 "2025-10-23T22:23:15Z")

</div>

The code for the animations looks good to me. For the logic in the `update` method of the player class, were you able to verify the code for the playing the animations is being reached? There is a number nested if/else blocks, and would need to debug to verify we are reaching that point.

If possible, would you be able to push the code you have locally to branch on the GitHub repo you shared earlier?

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 23, 2025, 11:20pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/17 "2025-10-23T23:20:03Z")

</div>

Sure, the repo should be updated now

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 24, 2025, 6:30pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/18 "2025-10-24T18:30:40Z")

</div>

Thanks for sharing the updated code. I was able to pull and run the code locally. The issue with the animations playing is tied to the `Char1` property not being set in your `ObjPlayer` class. To fix this, you just need to call the `init` method for your `ObjPlayer` class.

In Phaser, when you extend the `Phaser.Scene` class, the lifecycle events for these classes will automatically invoke the `init` methods for those instances. However, for other class like the `Phaser.GameObjects.Sprite`, or `Phaser.Physics.Arcade.Sprite` classes, the `init` method will not automatically be invoked.

To fix this, in your constructor of your `ObjPlayer` class, you can just call your `init` method there. Example:

```javascript
    constructor (scene, x, y)
    {
        super(scene, x, y, 'dude');
        this.init();
        scene.add.existing(this);
        scene.physics.add.existing(this);
        console.log("Player Created!");
        // .... rest of your code you had before
     }

```

Once you do this, you should see the rest of your logic for your animations in the `update` method get invoked.

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 24, 2025, 7:03pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/20 "2025-10-24T19:03:45Z")

</div>

Sorry if I am being too annoying… but one last question… I have this code that handles the stun of the bomb depending on your state (handled by the `hitBomb` function, unfortunately, it doesn’t seem to detect whenever the player is actually using his ability (wether if it’s true or false)

Is there a way to make the extension tell the main scene that the player is in the `this.charstateAbility`?

```javascript
hitBomb (player, bomb)

    {

    if(!this.effectShield && this.charstateAbility){

                this.charstateAbility = false;

                this.upStun = true;

                this.sound.play('hurt')

                this.score += 100;

                this.innerScore += 100;

                this.scoreText.setText(`SCORE: ${this.score}`);

                this.bombsExploded += 1

            }
    }

```

---

<div class="post-metadata">

**Author:** ![scottwestover](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/scottwestover/32/7442_2.png) [@scottwestover](https://phaser.discourse.group/u/scottwestover)\
**Post date:** [October 25, 2025, 3:02pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/21 "2025-10-25T15:02:33Z")

</div>

Not annoying whatsoever! It’s great that you’re digging in and asking questions — that’s exactly what the community’s for.

The issue is that `this.charstateAbility` is referencing the **scene** , not your player object.

Since `charstateAbility` is now a property on your `ObjPlayer` class, you need to access it _through the player instance_ that you created in the scene.

So instead of:

```javascript
if(!this.effectShield && this.charstateAbility){
    // ...
}

```

You should use:

```javascript
if(!this.effectShield && this.player.charstateAbility){
    // ...
}

```

That way, the scene is checking the actual player object’s state rather than looking for a property that doesn’t exist on the scene itself.

Basically, `this` inside the scene refers to the **Phaser.Scene** , not the player — so you just need to tell the scene _which_ object to check. 👍

---

<div class="post-metadata">

**Author:** ![s-a3](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/s-a3/32/9322_2.png) [@s-a3](https://phaser.discourse.group/u/s-a3)\
**Post date:** [October 29, 2025, 5:55pm UTC](https://phaser.discourse.group/t/making-the-player-a-global-object/15509/22 "2025-10-29T17:55:26Z")

</div>

Ok! thanks for helping me!

[Next page](https://phaser.discourse.group/t/making-the-player-a-global-object/15509.md?page=2)
