Phaser P2物理。如何在与另一个碰撞组发生碰撞时杀死一个组中的子弹(精灵)

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

我对 javaScript 和一般编程还很陌生,我正在尝试使用 Phaser API.

制作一对一的 2D 坦克游戏

过去两天我一直在思考如何杀死击中另一辆坦克的一颗子弹。我确实设法使用街机物理和 Phaser 示例坦克游戏让它工作。但到目前为止,我似乎无法转换我的知识并将其应用于我目前正在使用并希望坚持的 P2 物理学。

这是我用来创建两个坦克的坦克构造函数,每个坦克都有自己的 bulletGroup 命名为 bullets,在最底部我有一个名为 shoot 的函数,它重置子弹并使其飞行朝向目标(此特定功能主要取自移相器坦克示例)

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);

    }
  }
}

这是我分配碰撞组并使它们相互碰撞的地方, 这里的一切都按预期工作,但子弹并没有消失

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);
  }
}

这是我尝试在与坦克碰撞时用于回调的函数,它似乎在重叠的街机物理学中有效

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

 }

这就是我尝试将上述功能实现到我的 collisionHandler 的方式

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

}

现在,我已经尝试了各种不同的方法来解决这个问题,但我完全卡住了,我开始认为我无法在启用 P2 物理的情况下杀死一个小组中的精灵(但是后来又为什么它不起作用?)

我做了 seacrh 并尝试阅读尽可能多的文档,但对于这个特殊问题,我似乎是孤独的:)

感谢您的宝贵时间!

/马丁

像这样的东西应该有用。

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();
  }
}
  

请记住,玩家将与子弹发生碰撞,并在子弹被击杀前改变速度、加速度和其他属性。您可能想使用 onBeginContact or maybe BroadphaseCallback