Phaser P2物理。如何在与另一个碰撞组

时间:2015-11-05 09:10:07

标签: javascript game-physics phaser-framework

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

    }
  }
}




这是我分配collisionGroups并让它们相互碰撞的地方, 这里的一切都按预期工作,但子弹不会消失



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);
  }
}
&#13;
&#13;
&#13;

这是我试图用于与坦克碰撞时回调的功能,它似乎在重叠的街机物理中起作用

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

 }
&#13;
&#13;
&#13;

这就是我尝试将上述函数实现到我的collisionHandler 的方法

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

}
&#13;
&#13;
&#13;

现在,我已经尝试了各种不同的方法来解决这个问题,但我完全陷入困境,我开始认为我不能用P2物理学杀死一个精灵启用(但是又为什么它不起作用?)

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

感谢您的时间!

/马丁

1 个答案:

答案 0 :(得分:0)

这样的事情应该有效。

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

请记住,玩家将与子弹碰撞,它会在子弹被杀之前改变速度,加速度和其他属性。您可能希望使用onBeginContactBroadphaseCallback