html5 canvas移动元素

时间:2018-04-24 16:52:36

标签: javascript html5-canvas

我正在研究HTML5和JS的赛车游戏。我正试图用箭头键移动汽车。但它不起作用。

如何在画布中移动元素,是否需要在移动元素之前清除整个画布窗口?

代码:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var yCoordinate = 115;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var distance = 10;
var speed = 0.5;
var angle = 25;

var car = new Image();
car.src = "./images/p1.png";

startGame();

function startGame(){
  requestAnimationFrame(moveLane);
}

function moveLane(){
  clearCanvas();  
  drawCar();
  drawLane(10 - yCoordinate);
  drawLane(60 - yCoordinate);
  drawLane(110 - yCoordinate);
  //speed of the lane
  yCoordinate = yCoordinate - 0.4;
  //if lane crossed the bottom boundrary then reset the y co-ordinate
  if (yCoordinate <= -145){
    yCoordinate = 115;
  }

  requestAnimationFrame(moveLane);
}

function drawCar(){
  context.drawImage(car, canvasWidth/2, canvasHeight/4, car.width*0.4, car.height*0.13);
  setCarControls();
}

function moveCarLeft(){
  clearCanvas();
  var x = canvasWidth/2 - distance;
  context.drawImage(car, x, canvasHeight/4, car.width*0.4, car.height*0.13);
}

function drawLane(yCoordinate){
  context.fillStyle = "#ffffff";
  context.fillRect(canvasWidth/2, yCoordinate, 10, 20);
}

function clearCanvas(){
  context.clearRect(0, 0, canvasWidth, canvasHeight);
}

function setCarControls() {
  document.addEventListener('keydown', function(e){
    switch(e.keyCode){
      case 37: 
        console.log('left');
        requestAnimationFrame(moveCarLeft);
        break;
      case 38:
        console.log('up');
        break;
      case 39:
        console.log('right');
        break;
      case 40:
        console.log('down');
        break;
    }
  });
}

直播链接:https://jsfiddle.net/jackysatpal/6j4c5dod/6/

3 个答案:

答案 0 :(得分:1)

我已经更新了小提琴。校验。您没有使用动态x坐标。

https://jsfiddle.net/6j4c5dod/7/

function moveCarLeft(){
 clearCanvas();
 currentX = currentX - 0.1;
 context.drawImage(car, currentX, canvasHeight/4, car.width*0.4, car.height*0.13);
 }

答案 1 :(得分:1)

以下是我的更新演示,了解如何执行此操作:https://jsfiddle.net/mulperi/1daahhap/

游戏的基本思路(通常)是更新功能(游戏循环)和绘制功能。 更新功能是您使用requestAnimationFrame()调用的函数,它包含游戏中需要更新的所有不同内容,例如Player.update()等。 另一方面,绘图功能负责用ctx.clearRect()清除屏幕,然后播放Player.draw()和类似的东西。

在我的示例中,播放器移动是通过监听keydown和keyup并根据键盘上发生的事情将变量切换为true / false来完成的。 Player.update -function仅检查变量并在按下键时移动(例如ArrowLeft)。

完整代码:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>World's BEstest Game</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>

  <body>
    <canvas id="canvas" style="border:1px solid black;">

  </canvas>
    <script>
      const c = document.getElementById("canvas");
      const ctx = c.getContext("2d");

      /*
          TODO: Change player to Class based object
      */
      keyPresses = {};
      player = {
        x: 100,
        y: 100,
        update: () => {
          if (keyPresses['ArrowLeft']) {
            player.x -= 1;
          }
          if (keyPresses['ArrowRight']) {
            player.x += 1;
          }
          if (keyPresses['ArrowUp']) {
            player.y -= 1;
          }
          if (keyPresses['ArrowDown']) {
            player.y += 1;
          }
        },
        draw: () => {
          ctx.fillStyle = "black";
          ctx.beginPath();
          ctx.arc(player.x, player.y, 10, 0, Math.PI * 2, false);
          ctx.closePath();
          ctx.fill();
        }
      };

      function listenKeyboard() {
        document.addEventListener("keyup", keyUp.bind(this));
        document.addEventListener("keydown", keyDown.bind(this));
      };

      function keyUp(e) {
        keyPresses[e.key] = false;
      };

      function keyDown(e) {
        console.log(e.key)
        keyPresses[e.key] = true;
      };

      /*
        Everything drawing and graphics related goes here and also
        clearing the screen before drawing each frame.
      */
      function draw() {
        ctx.clearRect(0, 0, 300, 300);
        player.draw();
      };

      /*
        All the update methods go here
      */
      function update() {
        draw();
        listenKeyboard();
        player.update();
        requestAnimationFrame(update);
      };

      requestAnimationFrame(update);

    </script>
  </body>

</html>

所以我希望这可以帮助你思考游戏功能的结构,让它更容易阅读和理解,也许会给你一些灵感!快乐的编码:)

答案 2 :(得分:-1)

我认为你有3个选择:

我真的会选择多个画布(对于不像背景天空那样改变的东西,画一次),因为保存/恢复也可能是昂贵的操作。