Phaser P2 Sprite Scale Change对所有组儿童都无法正常工作

时间:2016-04-11 14:04:30

标签: javascript game-physics phaser-framework

我希望这段代码能够解释我想要做的事情。我有一张台球桌,如果它们足够接近,我希望球加速进入口袋。在这一点上,我还没有检查距离,只是想知道如何去做。

我确定有更好的方法!

  balls.forEachAlive(
    pockets.forEachAlive( moveBallTowardPocket, this), this);

更新:以下代码正在工作,除了一件事,前五个球上的球的比例变化。加速适用于所有口袋的所有球。比例变化仅适用于最后一个口袋,而不是前五个口袋。

function update() {
  pockets.forEachAlive(function(pocket) {
    accelerateBallToPocket(flipper, pocket, 60);
    balls.forEachAlive(function(ball) {
      accelerateBallToPocket(ball, pocket, 60);
    });
  });
  //...
}

function accelerateBallToPocket(ball, pocket, speed) {
  if (typeof speed === 'undefined') {
    var speed = 120;
  }
  var pocket_body_x = pocket.body.x;
  var pocket_body_y = pocket.body.y;
  var ball_body_x   = ball.body.x;
  var ball_body_y   = ball.body.y;

  // move ball toward pocket if close enough
  var dx = ball_body_x - pocket_body_x;  //distance ship X to enemy X
  var dy = ball_body_y - pocket_body_y;  //distance ship Y to enemy Y
  var dist = Math.sqrt(dx*dx + dy*dy);   //pythagoras

  if (dist < pocket_radius * pocket_leniency_factor) {

    // accelerate ball to pocket on right angle
    var angle = Math.atan2(pocket.y - ball.y,
                             pocket.x - ball.x);
    ball.body.rotation = angle + game.math.degToRad(90);
    ball.body.force.x = Math.cos(angle) * speed;
    ball.body.force.y = Math.sin(angle) * speed;

    // change scale
    // FIXME only works on the last pocket lower right
    if (ball === flipper) {
      ball.scale.setTo(Math.tan(pocket.x - ball.x),
                         Math.tan(pocket.y - ball.y));
    } else {
      ball.scale.setTo(Math.sin(pocket.x - ball.x),
                         Math.cos(pocket.y - ball.y));
    }
  } else {
    // reset the scale when the ball is out of range of the pocket
    ball.scale.setTo(1.0, 1.0);
  }
}

第二次更新: 基于解决方案,以下内容让我再次朝着正确的方向前进,我认为......

  for (var i = 0; i < pockets.children.length; i++) {
    accelerateBallToPocket(cue, pockets.children[i], 60);
    if (cue.pocketing) break;
  }

  for (var i = 0; i < balls.children.length; i++) {
    if (balls.children[i].pocketing) continue;
    for (var j = 0; j < pockets.children.length; j++) {
      accelerateBallToPocket(balls.children[i], pockets.children[j], 60);
      if (balls.children[i].pocketing) return;
    }
  }

1 个答案:

答案 0 :(得分:1)

好的,问题是如果球没有靠近口袋,你将比例设置为1。并且,当你检查每个球袋的每个球时,总会有一个口袋(后面会在循环中检查)球也没有关闭,除了口袋列表中的最后一个口袋。因此,即使将球比例设置为正确的值,也会在检查下一个showHint时重置。

你可以做的是检查一个球是否靠近至少一个口袋,如果是,那么它不能靠近其他口袋,所以你不要再检查其他口袋。

editor.on('cursorActivity', function() {
  var options = {
    hint: function() {
      return {
        from: editor.getDoc().getCursor(),
          to: editor.getDoc().getCursor(),
        list: ['foo', 'bar']
      }
    }
  };
  editor.showHint(options);
});

然后,在你的移动功能中,如果球靠近口袋,你必须将pocket成员设置为真。

// Consider that every ball is not inside a pocket
balls.forEachAlive(function(ball) {
   ball.inPocket = false;
});
flipper.inPocket = false; // You should really add the flipper to the balls group to remove duplicate code

pockets.forEachAlive(function(pocket) {
    if(!flipper.inPocket) accelerateBallToPocket(flipper, pocket, 60);
    balls.forEachAlive(function(ball) {
      if(!ball.inPocket) accelerateBallToPocket(ball, pocket, 60);
    });
  });

另一种方法是颠倒循环顺序,首先遍历所有球并且每个球检查每个口袋,一旦你发现它在口袋中继续外圈(跳过检查其他口袋)。为了做到这一点,您的inPocket函数应返回function accelerateBallToPocket(ball, pocket, speed) { ... if (ball === flipper) { ball.scale.setTo(Math.tan(pocket.x - ball.x), Math.tan(pocket.y - ball.y)); ball.inPocket = true; } else { ball.scale.setTo(Math.sin(pocket.x - ball.x), Math.cos(pocket.y - ball.y)); ball.inPocket = true; } } else { // reset the scale when the ball is out of range of the pocket ball.scale.setTo(1.0, 1.0); } } accelerateBall,当球距离口袋足够时为true,否则为false。 / p>

我会像这样重写你的迭代:

true