简体   繁体   中英

Phaser P2 physics. How to kill a bullet(sprite) in a group on collision with another collision group

I'm quite new to javaScript and programing in general and i'm trying to make a one vs one 2D tank game using Phaser API.

I have been stuck for the past two days trying to figure out how to kill a single bullet that hits the other tank. I did manage to get it to work using the arcade physics and by using the Phaser example tank game. But i can't seem to convert my knowlegde so far and apply it to the P2 physics which i am currently using and would like to stick to.

This is the tank constructor which i use to create two tanks, each tank holds its individual bulletGroup named bullets, at the far bottom i have a function called shoot which reset a bullet and make it fly towards the target (this particular function is mostly taken from the phaser tank example)

 var tank = function(playerIndex, startX, startY, facing, keyLeft, keyRight, keyUp, keyDown, keyTLeft, keyTRight, keyShoot) { this.playerIndex = playerIndex.toString();; this.tankBody; this.tankTurret; this.facing = facing; this.bullets; this.fireRate = 200; this.nextFire = 0; this.health = 100; this.isAlive = true; this.bodyTurnSpeed = 2; this.turretTurnSpeed = 2; this.currentSpeed = 0; this.maxSpeed = 50; this.keyLeft = keyLeft; this.keyRight = keyRight; this.keyUp = keyUp; this.keyDown = keyDown; this.keyTLeft = keyTLeft; this.keyTRight = keyTRight; this.keyShoot = keyShoot; this.create = function() { if (this.playerIndex === "1") { this.tankBody = game.add.sprite(startX, startY, "body_player_one"); this.tankTurret = game.add.sprite(startX, startY, "turret_player_one"); } else if (this.playerIndex === "2") { this.tankBody = game.add.sprite(startX, startY, "body_player_two"); this.tankTurret = game.add.sprite(startX, startY, "turret_player_two"); } this.tankBody.anchor.setTo(0.5, 0.5); this.tankTurret.anchor.setTo(0.5, 0.5); game.physics.p2.enable([this.tankBody]); this.tankBody.body.immovable = false; this.tankBody.body.collideWorldBounds = true; this.tankBody.body.debug = false; this.tankBody.body.fixedRotation = true; this.tankBody.body.mass = 50; // this.tankBody.body.kinematic = true; this.bullets = game.add.group(); this.bullets.enableBody = true; this.bullets.physicsBodyType = Phaser.Physics.P2JS; this.bullets.createMultiple(100, 'bullet', 0, false); this.bullets.setAll('anchor.x', 0.5); this.bullets.setAll('anchor.y', 0.5); this.bullets.setAll('outOfBoundsKill', true); this.bullets.setAll('checkWorldBounds', true); switch (this.facing) { case "left": this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(-90); this.tankTurret.rotation = Phaser.Math.degToRad(-90); break; case "right": this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(90); this.tankTurret.rotation = Phaser.Math.degToRad(90); break; case "up": this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(0); this.tankTurret.rotation = Phaser.Math.degToRad(0); break; case "down": this.tankBody.rotation = this.tankBody.body.rotation = Phaser.Math.degToRad(180); this.tankTurret.rotation = Phaser.Math.degToRad(180); break; } } this.update = function() { if (this.isAlive) { if (game.input.keyboard.isDown(this.keyLeft)) { this.tankBody.rotation = this.tankBody.body.rotation -= Phaser.Math.degToRad(this.bodyTurnSpeed); } if (game.input.keyboard.isDown(this.keyRight)) { this.tankBody.rotation = this.tankBody.body.rotation += Phaser.Math.degToRad(this.bodyTurnSpeed);; } if (game.input.keyboard.isDown(this.keyUp)) { this.tankBody.body.moveForward(50); } else if (game.input.keyboard.isDown(this.keyDown)) { this.tankBody.body.moveBackward(50); } else this.tankBody.body.setZeroVelocity(); if (game.input.keyboard.isDown(this.keyTLeft)) { this.tankTurret.rotation -= Phaser.Math.degToRad(this.turretTurnSpeed); } else if (game.input.keyboard.isDown(this.keyTRight)) { this.tankTurret.rotation += Phaser.Math.degToRad(this.turretTurnSpeed); } if (game.input.keyboard.isDown(this.keyShoot)) { this.shoot(); } this.tankTurret.x = this.tankBody.x; this.tankTurret.y = this.tankBody.y; } else { this.tankTurret.kill(); this.tankBody.kill(); } } this.shoot = function() { if (game.time.now > this.nextFire && this.bullets.countDead() > 0) { this.nextFire = game.time.now + this.fireRate; var bullet = this.bullets.getFirstExists(false); bullet.reset(this.tankTurret.x + this.tankTurret.width / 2 * Math.cos(this.tankTurret.rotation - Phaser.Math.degToRad(90)), this.tankTurret.y + this.tankTurret.width / 2 * Math.sin(this.tankTurret.rotation - Phaser.Math.degToRad(90))); bullet.body.rotation = this.tankTurret.rotation; bullet.body.mass = 100; bullet.body.moveForward(500); } } } 

This is where i assign collisionGroups and make them collide with eachother, everything here is working as intended but the bullets do not dissapear

 function create() { game.add.sprite(0, 0, "background_one"); game.physics.startSystem(Phaser.Physics.P2JS); game.physics.p2.setImpactEvents(true); //creating the collisiongroups var bulletsCollisionGroup = game.physics.p2.createCollisionGroup(); var playerOneCollisionGroup = game.physics.p2.createCollisionGroup(); var playerTwoCollisionGroup = game.physics.p2.createCollisionGroup(); var wallCollisionGroup = game.physics.p2.createCollisionGroup(); //sets the objects to collide with gamestage borders (prevent objects from moving out of bounds) game.physics.p2.updateBoundsCollisionGroup(); //creating players, each player holds its own bulletgroup player_one.create(); player_two.create(); //creates the tiles (mouseclick to place) createTiles(); //sets sprites to different collisiongroups player_one.tankBody.body.setCollisionGroup(playerOneCollisionGroup); for (var i = 0; i < player_one.bullets.children.length; i++) //player_one bullets { player_one.bullets.children[i].body.setCollisionGroup(bulletsCollisionGroup); } player_two.tankBody.body.setCollisionGroup(playerTwoCollisionGroup); for (var i = 0; i < player_two.bullets.children.length; i++) //player_two bullets { player_two.bullets.children[i].body.setCollisionGroup(bulletsCollisionGroup); } for (var i = 0; i < tiles.children.length; i++) //tiles { tiles.children[i].body.setCollisionGroup(wallCollisionGroup); } //makes the collisiongroups collide with eachother player_one.tankBody.body.collides([playerTwoCollisionGroup, wallCollisionGroup, bulletsCollisionGroup]); player_two.tankBody.body.collides([playerOneCollisionGroup, wallCollisionGroup, bulletsCollisionGroup]); for (var i = 0; i < tiles.children.length; i++) //tiles with everything { tiles.children[i].body.collides([playerOneCollisionGroup, playerTwoCollisionGroup, bulletsCollisionGroup]); } for (var i = 0; i < player_one.bullets.children.length; i++) //player_one bullets with everything { player_one.bullets.children[i].body.collides([wallCollisionGroup]); player_one.bullets.children[i].body.collides(playerTwoCollisionGroup, function() { bulletHitPlayer(player_two) }, this); } for (var i = 0; i < player_two.bullets.children.length; i++) //player_two bullets with everything { player_two.bullets.children[i].body.collides([wallCollisionGroup]); player_two.bullets.children[i].body.collides(playerOneCollisionGroup, function() { bulletHitPlayer(player_one) }, this); } } 

this is the function i tried to use for callback on collision with a tank, it seems to work in arcade physics with overlap

 function bulletHitPlayerOne(tank, bullet) { bullet.kill() tank.health -= 20; if (player.health <= 0) { tank.isAlive = false; } } 

and this is how i tried to implement the function above to my collisionHandler

 for (var i = 0; i < player_two.bullets.children.length; i++) { player_two.bullets.children[i].body.collides(playerOneCollisionGroup, bulletHitPlayerOne, this); } 

Now, I've tried a various of different ways to solve this problem but im completely stuck, I'm begining to think that i can't kill a sprite in a group with the P2 physics enabled (but then again why wouldn't it work?)

I did seacrh and tried to read as much documentations as possible but with this particular problem i seem to be alone :)

Thank you for your time!

/Martin

Something like this should work.

 Game.prototype = { create: function(){ //... var bulletsCollisionGroup = game.physics.p2.createCollisionGroup(); var playerOneCollisionGroup = game.physics.p2.createCollisionGroup(); //.... this.bullets = game.add.group(); this.bullets.enableBody = true; this.bullets.physicsBodyType = Phaser.Physics.P2JS; this.bullets.createMultiple(100, 'bullet', 0, false); this.bullets.setAll('anchor.x', 0.5); this.bullets.setAll('anchor.y', 0.5); this.bullets.setAll('outOfBoundsKill', true); this.bullets.setAll('checkWorldBounds', true); this.bullets.forEach(function(bullet){ bullet.body.setCollisionGroup(bulletsCollisionGroup); bullet.body.collides(playerOneCollisionGroup); }); player.body.setCollisionGroup(playerOneCollisionGroup); player.body.collides(bulletsCollisionGroup, this.hit, this); }, /... hit: function(player,bullet){ bullet.parent.sprite.kill(); } } 

Bear in mind that player will collide with the bullet and it will change velocity, acceleration and other properties before the bullet is killed. You may want to use onBeginContact or maybe BroadphaseCallback

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM