jhonatanoliveira Posted May 9, 2017 Share Posted May 9, 2017 Hello there, I am trying to randomly spawn objects (called populations in my code) in the screen without colliding them. The idea is to have a new positioning every time the player start the stage. I am trying to accomplish that with the following code in a create function: putPopulationRandomPosition(pop, maxX, maxY, minX, minY) { var minX = minX || 0; var minY = minY || 0; var hasCollision = true; while (hasCollision) { hasCollision = false; var newX = Math.floor(Math.random() * (maxX - minX + 1)) + minX; var newY = Math.floor(Math.random() * (maxY - minY + 1)) + minY; // Test collision pop.sprite.x = newX; pop.sprite.body.x = newX; pop.sprite.y = newY; pop.sprite.body.y = newY; for (var i = 0; i < this.populations.length; i++) { var currPop = this.populations[i]; this.game.physics.arcade.collide(pop.sprite, currPop.sprite,function(){hasCollision = true;}, null, this); if (hasCollision) { break; } } } } Here, each sprite (population) is passed to the above function, so the function can adjust its positioning to be random and not colliding. Then, in theory, after the create function finishes, all populations should not collide with each other. The problem is that right after create, the function update constantly checks for collision between populations and a collision is found! This is the function that I run in update to check for collision among all populations: checkCollisions(){ var hasCollision = false; var popMerge1; var popMerge2; for (var i = 0; i < this.populations.length; i++) { var population1Sprite = this.populations[i].sprite; // Check collision with populations for (var j = i+1; j < this.populations.length; j++) { var population2Sprite = this.populations[j].sprite; if (population1Sprite != population2Sprite) { this.game.physics.arcade.collide(population1Sprite, population2Sprite, function(){ popMerge1 = this.populations[i]; popMerge2 = this.populations[j]; hasCollision = true; }, null, this); } if (hasCollision) { break; } } if (hasCollision) { break; } } if (hasCollision) { this.performMerge(popMerge1, popMerge2); } } That is, in create, no population collides with each other. But right after, in update, a collision is detected. Please, do you have any insights into what is going on? Thank you a lot in advance. Link to comment Share on other sites More sharing options...
samme Posted May 9, 2017 Share Posted May 9, 2017 Try pop.sprite.body.reset(newX, newY) Also, in case you're using nested Groups, it's likely that objects' global/world positions haven't been updated yet. And try removing update() altogether and check if objects are where they're supposed to be. jhonatanoliveira 1 Link to comment Share on other sites More sharing options...
jhonatanoliveira Posted May 9, 2017 Author Share Posted May 9, 2017 Hey samme, you did it! Believe it or not, I've spent 2 days on this task, and the "reset" function worked out! Thank you so much. Now, just for my learning of Phaser, I would like to understand something strange in here... I tried before printing the position and size (width/height) of the populations (sprites) in create and in update after the collision. I did that just in case, for some unknown reason, the sprite/body was moving a bit. But, as it turns out, the positions and sizes were the same! So the sprites weren't moving at all. Out of curiosity, do you have any thoughts on why resetting all Body values (velocity, acceleration, rotation, etc) would make it work, since the bodies weren't moving at all? Thank you a lot for your time and support! Link to comment Share on other sites More sharing options...
samme Posted May 10, 2017 Share Posted May 10, 2017 I tried my own advice and I found that create → overlap gives the correct result if the sprite and body aren't moved after they're created create → overlap is correct after body.reset(X, Y), but the body's position in update() is incorrect create → overlap is correct after sprite.reset(X, Y) So I would say if you have to move a physics sprite during create(), use sprite.reset() only. In your case you may be able to use arcade.overlap instead of collide. It's simpler and it won't affect velocities. Link to comment Share on other sites More sharing options...
Recommended Posts