javascriptgame-developmentphaser-frameworkphaserjs

How do I make 2 Immovable Objects Collide and Just Stop


I have searched online for many hours for an answer, but no one seemed to be doing movement like I was. I just started my Phaser journey, and got stuck pretty early. I want my game to have movement locked onto the player in the center, with everything else moving around it. When I tried to add a building, however, the player would be pushed out from the middle.

I have tried setting both sprites to immovable or .body.moves = false, but that just ends up making the 2 sprites phase through each other. I have also tried locking the player to the center, with no luck. If there is a better way to go about player movement, let me know, but for now I cannot figure this out.

CODE:

class greenearth extends Phaser.Scene {
    constructor() {
        super("startGame");
    }
    create() {
        this.playerCanMove = true;
        this.keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
        this.keyS = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S);
        this.keyD = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);
        this.keyW = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W);
        this.background = this.add.tileSprite(0, 0, config.width, config.height, "background").setScale(2);
        this.background.setOrigin(0, 0);
        this.house = this.physics.add.sprite(200, 300, "house").setScale(1);
        this.house.setImmovable(true);
        this.player = this.physics.add.sprite(config.width / 2, config.height / 2, "player").setScale(4);
        this.player.play("idle");
        this.physics.add.collider(this.player, this.house);

    }
    playerMovement(delta) {
        this.playerStopped();
        if (this.keyA.isDown) {
            this.playerMovedLeft(player.speed, delta);
        } else if (this.keyD.isDown) {
            this.playerMovedRight(player.speed, delta);
        }
        if (this.keyW.isDown) {
            this.playerMovedUp(player.speed, delta);
        } else if (this.keyS.isDown) {
            this.playerMovedDown(player.speed, delta);
        }

        this.player.body.velocity.normalize().scale(player.speed);
        if (this.keyA.isDown) {
            this.player.play("walkLeft", true);
        } else if (this.keyD.isDown) {
            this.player.play("walkRight", true);
        } else if (this.keyW.isDown) {
            this.player.play("walkUp", true);
        } else if (this.keyS.isDown) {
            this.player.play("walkDown", true);
        } else {
            this.player.play("idle", true);
        }
    }

    playerMovedLeft(speed, delta) {
        let speedCorrection = (1000 / 60) / delta;
        this.house.setVelocityX(player.speed * speedCorrection);
        this.background.tilePositionX -= this.house.body.velocity.x / 120;

    }
    playerMovedRight(speed, delta) {
        let speedCorrection = (1000 / 60) / delta;
        this.house.setVelocityX(-player.speed * speedCorrection);
        this.background.tilePositionX -= this.house.body.velocity.x / 120;
    }
    playerMovedUp(speed, delta) {
        let speedCorrection = (1000 / 60) / delta;
        this.house.setVelocityY(player.speed * speedCorrection);
        this.background.tilePositionY -= this.house.body.velocity.y / 120;
    }
    playerMovedDown(speed, delta) {
        let speedCorrection = (1000 / 60) / delta;
        this.house.setVelocityY(-player.speed * speedCorrection);
        this.background.tilePositionY -= this.house.body.velocity.y / 120;
    }
    playerStopped() {
        this.house.setVelocityX(0);
        this.house.setVelocityY(0);
    }
    update(time, delta) {
        this.playerMovement(delta);
        // this.player.x = config.width/2;
        // this.player.y = config.height/2;
    }
}

Solution

  • The easy solution is to set the camera to follow the player, with the function startFollow.
    (link to the documentation)

    Here Short Demo, showcasing this:

    document.body.style = 'margin:0;';
    
    var config = {
        width: 536,
        height: 183,
        physics: {
            default: 'arcade',
            arcade: {            
                debug: true
            }
        },
        scene: { create },
    }; 
    
    function create () {
        this.add.text(10, 10, 'Camera set to follow the player')
            .setScale(1.5)
            .setOrigin(0)
            .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
        let graphics  = this.make.graphics();
        graphics.fillStyle(0xffffff);
        graphics.fillRect(0, 0, 10, 10);
        graphics.generateTexture('img', 10, 10);
        graphics.fillStyle(0xff0000);
        graphics.fillRect(0, 0, 20, 20);
        graphics.generateTexture('obj', 20, 20);
        
        this.cursors = this.input.keyboard.createCursorKeys();
    
        this.player = this.physics.add.image(150, 90, 'img');
        this.player.setCollideWorldBounds(true);
        this.player.setImmovable(true)
        
        let testHouse = this.physics.add.image(200, 90, 'obj');
        testHouse.setVelocity(-150, 0);
        
        this.physics.add.collider(this.player, testHouse);
        
        this.cameras.main.startFollow(this.player);
    
    }
    
    new Phaser.Game(config);
    
    console.clear();
    <script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>