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