相位P2物理.如何在与另一个碰撞组碰撞时杀死组中的子弹(精灵)

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

本文关键字:碰撞 子弹 精灵 另一个 相位 P2 物理      更新时间:2023-09-26

我对javaScript和编程很陌生,我正在尝试使用Phaser API制作一个一对一的2D坦克游戏。

在过去的两天里,我一直在想如何杀死击中另一辆坦克的一颗子弹。我确实通过街机物理和Phaser坦克游戏的例子让它发挥了作用。但到目前为止,我似乎无法将我的知识转化为我目前正在使用并希望坚持的P2物理。

这是我用来建造两辆坦克的坦克建造师,每辆坦克都有自己的子弹群,名为子弹,在最底部我有一个名为射击的功能,它可以重置子弹并使其飞向目标(这个特定的功能主要取自相位器坦克的例子)

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,并试图阅读尽可能多的文件,但对于这个特殊的问题,我似乎独自一人:)

感谢您抽出时间!

/Martin

这样的东西应该可以工作。

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或BroadphaseCallback