繁体   English   中英

html5 canvas移动元素

[英]html5 canvas move element

我正在使用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/

我已经更新了小提琴。 校验。 您没有使用动态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);
 }

这是我如何做的最新演示https : //jsfiddle.net/mulperi/1daahhap/

游戏的基本思想(通常)是具有更新功能(游戏循环)和平局功能。 更新函数是您使用requestAnimationFrame()调用的函数,它包含游戏中所有需要更新的不同内容,例如Player.update()等。另一方面,draw函数负责清除屏幕使用ctx.clearRect(),然后执行Player.draw()以及类似的操作。

在我的示例中,玩家的移动是通过侦听键盘按下和键盘输入并根据键盘上发生的事情将变量切换为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>

因此,我希望这可以帮助您考虑游戏功能的结构,使其更易于阅读和理解,并可能给您带来一些启发! 快乐的编码:)

我认为您有3种选择:

我真的会去多张画布(对于那些不会改变的东西,例如背景天空,只需绘制一次),因为保存/恢复也可能是昂贵的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM