如何为递归循环HTML画布添加延迟

时间:2019-02-08 00:40:22

标签: javascript html canvas

我有一个游戏循环,在该循环上有一个红色矩形和一个黄色矩形。当玩家受到伤害时,黄色矩形的宽度会减小,因为它取决于玩家的生命。当玩家的生命达到零时,他将输掉游戏,所有动画都将被取消。我遇到的问题是,因为循环是如此之快,所以黄色矩形没有时间将寿命降低为零,并且当取消动画时,它的一部分会留在屏幕上。因此,在取消动画之前,我需要添加一些延迟。谢谢大家。

if ($form->isSubmitted() === true) {
    if ($form->isValid() === true) {
        $httpClient = new Client();

        $response = $httpClient->post('https://paymentgate.com', [
            'key' => 'value',
        ]);

        // Validate response somehow
        if ($response->statusCode() !== 200) {
            $this->addFlash('error', 'Payment gate failed to respond');
        } else {
            // Let's assume that the gate returns a json with key 'redirect' containing the url
            $json = json_decode($response->getContent());
            return new RedirectResponse($json->redirect);
        }
    }

    $this->addFlash('error', 'Le formulaire comporte des erreurs.');
}

Image of player life bar when animations are canceled. There is a bit left still.

1 个答案:

答案 0 :(得分:1)

您还没有真正解释游戏逻辑的样子。但是我怀疑您可能需要做的就是将导致损坏的游戏逻辑移到渲染上方,而不是移到渲染之后。

编辑:如评论中所述,如果允许播放器寿命转为负值,也可能导致显示图像,在这种情况下,您可以向渲染器添加Math.max(value,0)

 // ANIMATION LOOP

  function animate(currentTime) {
    const animation = requestAnimationFrame(animate);
    c.clearRect(0, 0, canvas.width, canvas.height);

    // Move game logic that decreases player life to here.

    // PLAYER LIFE
    // RED REC
    c.beginPath();
    c.rect(20, 20, 150, 30);
    c.fillStyle = "red";
    c.fillRect(10, 30, 200, 20);
    // YELLOW REC
    c.beginPath();
    c.rect(20, 20, 150, 30);
    c.fillStyle = "yellow";
    c.fillRect(10, 30, Math.max(player.life,0) , 20); // prevent negative value


    // Is game logic that decreases player life here?
    // END GAME

   //I need some delay here so that fillRect has time to decrease the yellow bar to 0;
    if (player.life <= 0) {
      console.log("You Lose");
      music.pause();
      paused = true;
      cancelAnimationFrame(animation);
    }
  }
  animate();

通常,您将像这样组织代码。

var paused=false;
  // Game Logic
function update()
{
  enemyArray.forEach(function(enemy) {
  if (collides(player, enemy)) {
      player.life += -10;
      enemy.delete();
  }
  });
  if (player.life <= 0) {
    console.log("You Lose");
    music.pause();
    paused = true;
  }
}
// Render
function draw()
{
  c.clearRect(0, 0, canvas.width, canvas.height);
  // PLAYER LIFE
  // RED REC
  c.beginPath();
  c.rect(20, 20, 150, 30);
  c.fillStyle = "red";
  c.fillRect(10, 30, 200, 20);
  // YELLOW REC
  c.beginPath();
  c.rect(20, 20, 150, 30);
  c.fillStyle = "yellow";
  c.fillRect(10, 30, Math.max(player.life,0) , 20); // prevent negative value
}
 
 // Animation Loop
function animate(currentTime) {
  update();
  draw();
  if (!paused)
    const animation = requestAnimationFrame(animate);
}
animate();