Jump to content

Is there a way to separate two objects with body.immovable = true?


Recommended Posts

I have 3 sprites:

  1. spritePlayer is my main sprite I control
  2. sprite2 will NEVER move.
  3. sprite3 will only move when spritePlayer moves against it AND presses a key. Then I want it to have a constant velocity in that direction and if it comes across sprite2 then it collides/separates and loses it's velocity.

I set sprites 2 and 3 to have body.immovable = true so if spritePlayer touches either of them they don't move and spritePlayer can't move through them either which is exactly what I want.

If I press a key to trigger sprite3 to move I set sprite3.body.velocity.x = 50 and it moves right through sprite 2 when it comes across it which is what I don't want. I know two immovable objects don't separate as programmed in phaser so there must be some other way to get the desired effect I need.

Perhaps I'm going about this the wrong way but I'm having a hard time figuring out any other way.

Link to comment
Share on other sites

Caveat: I have never worked on this myself in a real setting.

You've got two competing antagonists here: you want the collision effect to be that your player can push things, but you want the other sprites not to have collision effects. You've got to pick one or the other. Either those sprites don't have immovable set to true, or they do and you take over the collision effect entirely.

That said, I'm not sure which one I'd pick... *probably* the one where I do the collision manually. If you could simplify it down to something you post in the sandbox we could probably stumble to a solution in public eventually.

Link to comment
Share on other sites

Yeah unfortunately I thought that was the case drhayes.

I agree that I think I will have to do the collision manually myself.

What I have tried is when sprite2 and sprite3 do collide phaser still calls the collide callback and then I set sprite3.body.velocity.x = 0;

The sprite stops moving as expected but it's like <=1pixel into sprite2. I'm guessing I would then have to manually separate the two objects myself there.

Hmm... I wonder if there is an easy/proper way to do that.

I'll give it a go and then maybe get it into the sandbox if I still can't get a proper solution going. Thanks

Link to comment
Share on other sites

Okay I figured out a nice, easy solution at least for my situation (top-down tiled game).

If the overlap callback is triggered then for sprite3 (which is the one I'm manually putting a velocity on) I just manually set velocity to 0 and then x, y to be outside of sprite2.

In my case I actually have a helper function where I determine which tile the object is in and then i can just set sprite3 to those coordinates but that won't work for most games so I made a little snippet of code as an example of what people can use. I renamed sprite3 to be moveableSprite and sprite2 to be stationarySprite so the code reads better.

Also I converted some code from TypeScript to JS for the example so it might not work in JS exactly as is shown

this.stationarySprite.immovable = true;
this.moveableSprite.immovable = true;

this.game.physics.arcade.overlap(this.stationarySprite, this.moveableSprite, this.immovableOverlap, null, this);

// at some point a velocity is applied to moveableSprite
this.moveableSprite.body.velocity.x = 50;

// Manually place moveableSprite beside stationarySprite. This isn't a full example since I'm using my own
// tile helper functions in my game but it shows how someone would likely do it.
immovableOverlap(stationarySprite, moveableSprite) {
    moveableSprite.body.velocity.x = 0;
    moveableSprite.body.velocity.y = 0;

    var moveableSpriteXLeft = moveableSprite.x;
    var moveableSpriteXRight = moveableSpriteXLeft + moveableSprite.width;
    var stationarySpriteXLeft = stationarySprite.x;
    var stationarySpriteXRight = stationarySprite.x + stationarySprite.width;

    // Test if moveableSprite has collided with the left side of stationarySprite
    if (moveableSpriteXRight > stationarySpriteXLeft && moveableSpriteXRight < stationarySpriteXRight) {
        moveableSprite.x = stationarySpriteXLeft - moveableSprite.width;

    // More tests for other sides/directions
    if () {}

Honestly now that I've written this I bet the Phaser library itself has this exact type of code only better so maybe it's worth actually looking at the Phaser source code to see if some code can be reused.

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...