游戏API动画循环

时间:2017-06-27 19:11:35

标签: javascript

我正在为一个项目制作一个简单的游戏,我遇到了其中一个功能的问题。在右手边沿y轴移动的敌舰应该每隔3秒以直线射击。我遇到的问题是镜头(小黄圈)是从船的位置拍摄的,因此一旦拍摄就跟随y轴上的船。是否有人会对如何使射击沿着一条直线并仍在被移动的船上射击有任何建议? https://codepen.io/Built-to-Code/pen/vZJdYz

    var tank = {
    x: 10,
    y: 10,
    width: 10,
    height: 15,
    cx: 115 + 0.5 * 10,
    cy: 65 + 0.5 * 15,
    angle: 0,
    speed: 100
  };

  var enemy = {
    x: 0,
    y: 0,
    width: 10,
    height: 80,
    speed: 1
  }

  var weapon = {
    x: 955,
    y: 10,
    r: 3
  }

  var weapon2 = {
    y: 70
  }

  var distanceToMove = function(delta, speed) {
    return (speed * delta) / 1000;
  }

  var measureFPS = function(newTime) {
    if(lastTime === undefined) {
      lastTime = newTime;
      return;
    }
    var diffTime = newTime - lastTime;

    if(diffTime >= 1000) {
      fps = frameCount;
      frameCount = 0 ;
      lastTime = newTime;
    }
    fpsContainer.innerHTML = "FPS: " + fps;
    frameCount++;
  };

  function timer(currentTime) {
    var delta = currentTime - oldTime;
    oldTime = currentTime;
    return delta;
  }

  function clearCanvas() {
    ctx.clearRect(0, 0, w, h);
  }

  function drawTank(x, y) {
    ctx.save();
    ctx.translate(x, y);
    ctx.strokeStyle = "#ffa64d";
    ctx.fillStyle = "#b1b181"
    ctx.strokeRect(100, 50, 40, 15);
    ctx.strokeRect(100, 80, 40, 15);
    drawCanon(tank.cx, tank.cy, tank.angle);
    ctx.restore();
  }

  function drawCanon(cx, cy, angle) {
    ctx.translate(cx, cy);
    ctx.rotate(angle);
    ctx.translate(-cx, -cy);
    ctx.fillRect(115, 65, 10, 15);
    ctx.strokeRect(125, 72.5, 5, 2);
  }

  function updatetankPosition() {
    tank.speedX = tank.speedY = 0;

    if (inputStates.left) {
      //ctx.fillText('left', 150, 20);
      tank.speedX = -tank.speed;
    }
    if (inputStates.right) {
      //ctx.fillText('right', 150, 50);
      tank.speedX = tank.speed;
    }
    if (inputStates.up) {
      //ctx.fillText('up', 150, 80);
      tank.speedY = -tank.speed;
    }
    if (inputStates.down) {
      //ctx.fillText('down', 150, 120);
      tank.speedY = tank.speed;
    }
    if (inputStates.space) {
      //ctx.fillText('space bar', 160, 150);
    }
    if (inputStates.mousePos) {
      /*ctx.fillText("x = " + inputStates.mousePos.x + " y = " +
    inputStates.mousePos.y, 5, 150);*/
    }
    if (inputStates.mousedown) {
      //ctx.fillText("mousedown b" + inputStates.mouseButton, 5, 180);
      tank.speed = 500;
    }else {
      tank.speed = 100;
    }
    tank.x += distanceToMove(delta, tank.speedX);
    tank.y += distanceToMove(delta, tank.speedY);
  }

  function drawEnemy(x, y) {
    ctx.save();
    ctx.strokeStyle = "red";
    ctx.strokeRect(w - enemy.width, y, enemy.width, enemy.height);
    drawEnemyWeapons();
    ctx.restore();
  }

  function drawEnemyWeapons() {
    ctx.save();
    ctx. strokeStyle = "green";
    ctx.strokeRect(w - enemy.width - 30, enemy.y + 10, 30, 2);
    ctx.strokeRect(w - enemy.width - 30, enemy.y + 70, 30, 2);
    ctx.restore();
  }

  function moveEnemy() {
    enemy.y += enemy.speed;
    var shot = window.setTimeout(enemyShots, 3000);
    checkEnemyPosition();
  }

  function checkEnemyPosition() {
    if(enemy.y + enemy.height > h || enemy.y <= 0)
      enemy.speed = -enemy.speed;
  }

  function enemyFire(x, y) {
    ctx.save();
    ctx.fillStyle = "yellow";
    ctx.beginPath();
    ctx.arc(weapon.x, enemy.y + weapon.y, weapon.r, 0, 2*Math.PI);
    ctx.arc(weapon.x, enemy.y + weapon2.y, weapon.r, 0, 2*Math.PI);
    ctx.fill();
    ctx.restore();
  }

  function enemyShots() {
    weapon.x -= 7;
    if(weapon.x <= 0){
      weapon.x = 955;
    }
  }

  var mainLoop = function(time) {
    measureFPS(time);
    delta = timer(time);
    clearCanvas();
    updateGamePadStatus();
    drawTank(tank.x, tank.y, tank.angle);
    drawEnemy(enemy.x, enemy.y);
    enemyFire(weapon.x, weapon.y, weapon.r);
    moveEnemy();
    updatetankPosition(delta);
    requestAnimationFrame(mainLoop);
  };

非常感谢!

1 个答案:

答案 0 :(得分:0)

问题在于您使用的是enemy.yenemy.x,它们不是数字,而是指向更新的数字的指针。您需要传递值,而不是通过引用传递。

相反,做这样的事情:

function enemyFire(x, y) {
    ctx.save();
    ctx.fillStyle = "yellow";
    ctx.beginPath();
    var coords = [ weapon.x, enemy.y + weapon.y, weapon.r ];
    var coords2 = [ weapon.x, enemy.y + weapon2.y, weapon.r ];
    ctx.arc(coords, 0, 2*Math.PI);
    ctx.arc(coords2, 0, 2*Math.PI);
    ctx.fill();
    ctx.restore();
  }

这是我在我的节点解释器中运行的一个简单示例,用于演示如上所示的分配后的差异:

> var weaponX = 10;
undefined
> var weaponY = 12;
undefined
> var coords = [ weaponX, weaponY ];
undefined
> console.log(coords);
[ 10, 12 ]
undefined
> weaponY = '99999';
'99999'
> console.log(coords);
[ 10, 12 ]
undefined