I am new to Phaser Framework and I wanted to try making some prototype of 2D pool game from top down perspective. The problem that I have right now is detecting if all balls have stopped moving before restarting.
I use Physics.Matter and here is the source code when create so far:
this.matter.world.setBounds(0, 0, 720, 1280, 32, false, false, false, true);
this.add.image(400, 300, 'sky');
var ball = this.matter.add.image(360, 1000, 'ball');
ball.setCircle();
ball.setVelocity(-5, -20);
ball.setBounce(0.5);
for (var i = 1; i < 10; i++) {
var target = this.matter.add.image(Phaser.Math.Between(400,450), Phaser.Math.Between(400,450), 'target');
target.setCircle();
target.setVelocity(0, 0);
target.setBounce(0.7);
target.setFriction(0, 0.01);
target.setSleepEvents(true, true);
}
this.matter.world.on('sleepstart', function() {console.log('sleepstart');});
this.matter.world.on('sleepend', function() {console.log('sleepend');});
This would detect if each target has slept but I need to detect if ALL of them stopped moving. I cannot count how many has slept because sometimes when a target has entered sleep state, there is a chance some other body will bounce off it and woke it up again.
Is there any way to globally detect them?
EDIT: As a fallback plan I add a basic JS function to be called whenever update is called and count the sleeping bodies, which looks like it should not be a proper way:
var isActive = false;
// Some commands here that changes isActive = true
function onupdate() {
if (isActive) {
var bodyCount = this.matter.world.getAllBodies().filter(o => o.isSleeping === true).length;
console.log(bodyCount);
if (bodyCount >= 11) {
isActive = false;
}
}
}
I would put all objects you want to track into a phaser group (https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.Group.html) and iterate over the items in the group, to see if all have the property isSleeping set to true;
Warning: I can't say how performant this solution is, youre use case. If it is too slow, I would setup a counter variable, and count it down / up on
sleepstartandsleepend. And when the counter is0all are sleeping.
Here a working demo, how I would do it:
(explaination are in the code, as comments)
// fix to prevent 'Warnings' in stackoverflow console
console.warn = _ => _
var config = {
type: Phaser.AUTO,
width: 400,
height: 100,
scene: { create },
physics: {
default: 'matter',
matter: {
debug: true,
setBounds: {
x: 0,
y: 0,
width: 400,
height: 100
},
enableSleeping: true
}
}
};
function create(){
// create the Phaser Group
this.targets = this.add.group();
for (var i = 1; i < 10; i++) {
var target = this.matter.add.image(200, 0, 10, 10, 'target');
target.setCircle();
target.setBounce(0.7);
target.setFriction(0, 0.01);
target.setSleepEvents(true, true);
// Add Item to the Group
this.targets.add(target);
}
this.matter.world.on('sleepstart', function(event, item){
// Check all targets are sleeping
if(!this.targets.getChildren().some( target => !target.body.isSleeping)){
console.log('all are sleeping');
}
}, this); // <- pass the scene as context
this.matter.world.on('sleepend', function() {console.log('sleepend');});
}
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>