Know what body overlaps what other body

Hi,

i’m new to Phaser and currently stuck.
In arcade physics, I have a body (block) and a group of bodies (players).
I need to know, who of the players currently overlaps with block.

I tried adding overlap() with a callback but this fires continoulsy.
For me block.body.touching and player[x].body.touching never hold any content.
I attempted to set something like player[x].overlapsWithBlock to null at the end of the update() method and then populate this in the callback but it seems the callback does not run on every frame. Sometimes, a player currently overlapping still has null in the variable for one frame. Then it works for like 80 frames.

Whats the recommended way to do this?

1 Like

The callbacks you pass to overlaps and colliders will be called once on every frame (this is actually not necessarily the case, but you can assume it is for now) the Game Objects touch and will be passed the two Game Objects as arguments. This is the intended way to handle this.

When you say your callback “fires continuously”, do you mean that you just want to run some code once when the objects first touch? I’m not aware of a universal way to achieve this, so it’d be good if you showed the code which doesn’t work.

Hi,

i prepared a little fiddle to demonstrate
https://jsfiddle.net/mhu42s7n/1/

Of that “area” in my example i will have multiple later on.
I need to know which of those the player is currently touching at any given point.

The code works but you can see “TOUCHES” flicker to “DOES NOT TOUCH” randomly, while the objects overlay.

It seems the callback is actually not being called on every frame.
Any hint to solve this?

I only alluded to this in my previous post, but now it turns out that it’s significant in your case. The game loop, which includes the update method in your Scene, is run by the browser, usually at the monitor’s refresh rate, which means that it doesn’t update at predictable intervals. Arcade Physics, on the other hand, runs on a fixed time step, which means that it will update at a definite frequency depending on how long the previous frame was. In order to do this, it can receive more than one update per frame - or none at all.

This is the reason for the behavior of your code. player.touchesArea is set to false on every game update, but it can only be set to true if the physics engine updates on that particular frame (or the frames around it; I haven’t checked when the two systems update relative to each other). I didn’t realize you were updating a variable from both update loops, which is why I thought that the discrepancy was irrelevant in your case.

Instead of using Colliders, you should look at the overlap method of this.physics. It allows you to check for overlap between two given objects at any time and is not affected by the frequency of the update loops. Setting player.touchesArea to the result of this.physics.overlap(this.player, this.area) at the start of the update method should work correctly. Note that doing this with the collide method might lead to unexpected behavior in the current version of Arcade Physics - stick to Colliders if you need separation.

2 Likes

This is perfect, thank you. I missed this method completely.
As i have to do a couple of those collision checks but they are all not “frame critical” I am currently thinking of doing this only every 10th frame or something like that.
Is there a frame counter or something like this for the update() method that i could reuse for something like this?

Generally, you shouldn’t measure periods of time in frames because frames are inconsistent. It’s cleaner to measure them in milliseconds. The update method receives two arguments when it’s called by Phaser - time, which is a measure of the total time elapsed in milliseconds (but it’s not necessarily a timestamp), and delta, which is the number of milliseconds elapsed since the last frame. You can use a variable on your Scene and accumulate the delta values in it; then, when it reaches a certain number (for instance, 165, which roughly 10 frames when running at 60 FPS), subtract that number from it and run your collision. This is essentially a simple fixed time step.

If you don’t want to do this manually, Phaser also provides Timers that you can use to easily pull this off. This is probably the simplest way you can do it.

If you want to measure in frames and you know what the implications of that are, you can just increment a counter every time update is called, then check its value to see how many frames have elapsed.

Hi,

I think in this case i would be better to have my own increment to run my code every X update calls.
But i will also consider using timers :slight_smile:
Thank you