alessa Posted May 30, 2018 Share Posted May 30, 2018 Hello everybody, new Phaser3 user here! I am trying to modify the Making your First Game tutorial in order to make a prototype of a similar game with online multiplayer capabilities. Everything works fine, however I cannot make the collision of the bombs physics group to work against the current player. Some of my code: Initialization in create() this.bombs = this.physics.add.group(); this.physics.add.collider(this.bombs, this.platforms); this.physics.add.collider(this.player, this.bombs, hitBomb, null, this); hitBomb callback function function hitBomb(player, bomb){ console.log("Inside hitBomb") this.physics.pause(); player.setTint(0x000000); player.anims.play('turn'); } In this example, the collision with the platforms of the game work fine. Next step, I get some information from the server side SocketIO about some characteristics of the bomb to create when an event is triggered (the self you see here comes from var self = this;) this.socket.on('bombLocation', function (bombLocation) { console.log("bombLocation message received"); var bomb = self.bombs.create(bombLocation.x, bombLocation.y, 'bomb'); bomb.setBounce(1); bomb.setCollideWorldBounds(true); bomb.setVelocity(bombLocation.velocityX, bombLocation.velocityY); bomb.allowGravity = false; }); The bomb is spawn like it should be, everything works just fine. However, the hitBomb function never gets called (I can't see the console message). Am I missing something? Cheers! Link to comment Share on other sites More sharing options...
alessa Posted May 30, 2018 Author Share Posted May 30, 2018 Ok, I don't understand why but now I got it working by moving the line this.physics.add.collider(this.player, this.bombs, hitBomb, null, this); Inside the bombLocation socket function, like this: this.socket.on('bombLocation', function (bombLocation) { console.log("bombLocation message received"); var bomb = bombs.create(bombLocation.x, bombLocation.y, 'bomb'); bomb.setBounce(1); bomb.setCollideWorldBounds(true); bomb.setVelocity(bombLocation.velocityX, bombLocation.velocityY); bomb.allowGravity = false; self.physics.add.collider(player, bombs, hitBomb, null, self); }); I really would like to understand why, anybody knows perhaps? Link to comment Share on other sites More sharing options...
samme Posted May 30, 2018 Share Posted May 30, 2018 Did hitBomb ever work, even before adding bombLocation etc.? Link to comment Share on other sites More sharing options...
rich Posted May 30, 2018 Share Posted May 30, 2018 Don't add the collider inside the socket function, or it will create a brand new collider ever time that function is called, which I'm pretty sure is not what you wanted. Instead, try and get it working without using a Socket connection at all - do the bombs work locally? If so, I think it's likely just a scope issue. AhmedElyamani 1 Link to comment Share on other sites More sharing options...
alessa Posted May 31, 2018 Author Share Posted May 31, 2018 Well, I tried again to put the collider outside the socket, like this: // Creating a group for all the bombs in the game bombs = this.physics.add.group(); // Collisions between bombs and platforms this.physics.add.collider(bombs, platforms); // Checking the collision between player and bombs this.physics.add.collider(player, bombs, hitBomb, null, self); The weird thing is that this way, the collision between bombs and platforms works well. So I don't think it can be a scope issue... the hitBomb function is declared outside the create function, in the same file, so it shouldn't be an issue to call it right? What I mean is this structure: let gameScene = new Phaser.Scene('Game'); let config = { type: Phaser.AUTO, width: 800, height: 600, physics: { default: 'arcade', arcade: { debug: false, gravity: { y: 300 } } }, scene: gameScene }; let game = new Phaser.Game(config); var sensorValue; var pressureText; var player; var star; var platforms; var bombs; var gameOver; var otherPlayers; var blueScoreText; var redScoreText; gameScene.preload = function () { ... } gameScene.create = function () { ... } gameScene.update = function () { ... } hitBomb = function(player, bomb){ console.log("Inside hitBomb"); }; I have also other functions at the same scope of hitBomb that get called without issues. I tried a simplified version, releasing a bomb as soon as the game starts: // Creating a group for all the bombs in the game bombs = this.physics.add.group(); var bomb = bombs.create(200, 16, 'bomb'); bomb.setBounce(1); bomb.setCollideWorldBounds(true); bomb.setVelocity(-200, 20); bomb.allowGravity = false; // Checking the collision between player and bombs this.physics.add.collider(player, bombs, hitBomb, null, self); This also doesn't work I don't understand the issue honestly Link to comment Share on other sites More sharing options...
alessa Posted May 31, 2018 Author Share Posted May 31, 2018 Just a crazy thought perhaps: could it be that the order in which you initialize the player and bombs affect whether the collider finds an instance of player or not? Is there a way to refresh this? EDIT: I think I got this right! I tried to wrap the collider code into being initialized with a delay, like this: // Wait 3 seconds to be sure that the player is created, so the collider can be associated with it setTimeout(function () { // Checking the collision between player and bombs self.physics.add.collider(player, bombs, hitBomb, null, self); }, 3000); This actually works, but it's not the most elegant solution. Any suggestion? Perhaps a callback function when the player is created? Link to comment Share on other sites More sharing options...
rich Posted May 31, 2018 Share Posted May 31, 2018 I still don't really get why you can't create everything you need up-front, the moment the game starts. Create your bombs group, create the player, create the colliders. Then in the Socket callbacks all you need do is create the bombs themselves, within the pre-existing Group. The fact you're having to use setTimeout is a big red warning flag there are structural problems in the code imho. Link to comment Share on other sites More sharing options...
alessa Posted May 31, 2018 Author Share Posted May 31, 2018 The problem is that the player is created on the server, therefore I experienced that the collider needs to be created once both bombs and player are initialized. Since I have to wait information from the server to create the player, I have no other way than this unfortunately. However, instead of the timer I set up a callback function that is fired after a player is created. Link to comment Share on other sites More sharing options...
shion Posted June 20, 2019 Share Posted June 20, 2019 I'm having the same issue, I can't get collisions to work with a group and my tilemap. this.map = this.make.tilemap({ key: "map" }); const tileset = this.map.addTilesetImage("warTileset_64x64", "tiles"); this.belowLayer = this.map.createStaticLayer("Tile Layer 1", tileset, 0, 0); this.belowLayer.setCollisionByProperty({ collides: true }); this.physics.world.setBounds(0, 0, this.map.widthInPixels, this.map.heightInPixels); this.playerBullets = this.physics.add.group({ classType : Bullet, runChildUpdate : true, setCollideWorldBounds: true, }); this.physics.add.collider(this.belowLayer, this.playerBullets, () => { console.log('Collision') }); And this is my Bullet Class import Phaser from 'phaser' class Bullet extends Phaser.GameObjects.Sprite { constructor(scene) { super(scene, 0, 0, 'bullet'); scene.physics.world.enable(this); scene.add.existing(this); this.speed = 1; this.born = 0; this.direction = 0; this.xSpeed = 0; this.ySpeed = 0; this.setSize(12, 12); } fire(shooter, target) { this.setPosition(shooter.x, shooter.y); // Initial position this.direction = Math.atan((target.x - this.x) / (target.y - this.y)); // Calculate X and y velocity of bullet to moves it from shooter to target if (target.y >= this.y) { this.xSpeed = this.speed * Math.sin(this.direction); this.ySpeed = this.speed * Math.cos(this.direction); } else { this.xSpeed = -this.speed * Math.sin(this.direction); this.ySpeed = -this.speed * Math.cos(this.direction); } this.rotation = shooter.rotation; // angle bullet with shooters rotation this.born = 0; // Time since new bullet spawned } // Updates the position of the bullet each cycle update(time, delta) { this.x += this.xSpeed * delta; this.y += this.ySpeed * delta; this.born += delta; if (this.born > 1800) { this.setActive(false); this.setVisible(false); } } } export default Bullet; The Bullets work locally, and they collide with the other players, but no with world bounds or tilemaps. Link to comment Share on other sites More sharing options...
CROCKFIREKING Posted February 19, 2020 Share Posted February 19, 2020 this.yoursprite.body.setImmovable(); Link to comment Share on other sites More sharing options...
Hem Posted May 7, 2021 Share Posted May 7, 2021 I faced the same issue, When I create the emitter outside of Scene. Link to comment Share on other sites More sharing options...
Recommended Posts