0
votes

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

1
here is the game in its current form TanksMartin Nilsson
sprite.kill() should workShohanur Rahaman
Sprite.kill() should work, yes. But my question is how to implement it in a group with p2 physics. In my examples i do use the kill commandMartin Nilsson

1 Answers

0
votes

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