简体   繁体   English

Javascript游戏,撞墙时的碰撞检测

[英]Javascript game, collision detection when hitting a wall

I've been following W3schools tutorial on creating a JavaScript game in a canvas https://www.w3schools.com/graphics/game_obstacles.asp 我一直在遵循W3schools教程,以在画布上创建JavaScript游戏https://www.w3schools.com/graphics/game_obstacles.asp

I've got to the stage where they add an obstacle in. Currently, it has collision detection which stops the game when it hits the wall. 我已经到了他们在其中添加障碍物的阶段。目前,它具有碰撞检测功能,可以在撞到墙壁时停止游戏。 I am trying to figure out a way to treat it like a wall where the box could hit it and no longer move that direction and continue the game, making the wall work. 我正在尝试找出一种方法,将其像一堵墙一样,盒子可能会撞到墙,不再移动该方向并继续游戏,从而使墙起作用。

Heres what I've got so far: https://jsfiddle.net/j9cy1mne/1/ 这是到目前为止我所拥有的: https : //jsfiddle.net/j9cy1mne/1/

<body onload="startGame()">
  <script>
    var myGamePiece;
    var myObstacle;

    var speed = 3;

    function startGame() {
      myGamePiece = new component(30, 30, "red", 10, 120);
      myObstacle = new component(10, 200, "green", 300, 120);
      myGameArea.start();
    }

    var myGameArea = {
      canvas: document.createElement("canvas"),
      start: function() {
        this.canvas.width = 480;
        this.canvas.height = 270;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.interval = setInterval(updateGameArea, 20);
      },
      clear: function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
      },
      stop: function() {
        clearInterval(this.interval);
      }
    }

    function component(width, height, color, x, y) {
      this.width = width;
      this.height = height;
      this.speedX = 0;
      this.speedY = 0;
      this.x = x;
      this.y = y;
      this.update = function() {
        ctx = myGameArea.context;
        ctx.fillStyle = color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
      }
      this.crashWith = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;

        if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
          crash = false;

        }


        return crash;
      }
    }

    function updateGameArea() {
      if (myGamePiece.crashWith(myObstacle)) {
        console.log("crash");
      } else {
        myGameArea.clear();
        myObstacle.update();
        myGamePiece.x += myGamePiece.speedX;
        myGamePiece.y += myGamePiece.speedY;
        myGamePiece.update();
      }
    }
    document.onkeydown = checkKeyD;

    function checkKeyD(e) {

      e = e || window.event;

      if (e.keyCode == '38') {
        // up arrow
        myGamePiece.speedY = -speed;
      } else if (e.keyCode == '40') {
        // down arrow
        myGamePiece.speedY = speed;
      } else if (e.keyCode == '37') {
        // left arrow
        myGamePiece.speedX = -speed;
      } else if (e.keyCode == '39') {
        // right arrow
        myGamePiece.speedX = speed;
      }

    }

    document.onkeyup = clearmove;

    function clearmove() {
      myGamePiece.speedX = 0;
      myGamePiece.speedY = 0;
    }

  </script>

</body>

I see that you have part of it finished. 我看到您已经完成了一部分。 You just need to have the crash code in the if statement for moving the player right. 您只需要在if语句中添加崩溃代码即可向右移动播放器。 This will run the code only when the player is pressing the right arrow. 仅当玩家按下向右箭头时,这将运行代码。

else if (e.keyCode == '39') { // right arrow // add crash code here myGamePiece.speedX = speed; }

Your game loop only executes when there is no crash: 您的游戏循环仅在没有崩溃时执行:

function updateGameArea() {
  if (myGamePiece.crashWith(myObstacle)) {
    console.log("crash");
  } else {
    myGameArea.clear();
    myObstacle.update();
    myGamePiece.x += myGamePiece.speedX;
    myGamePiece.y += myGamePiece.speedY;
    myGamePiece.update();
  }
}

What you want to do is to set the myGamePiece.speedX and myGamePiece.speedX to 0 when a collision is detected. 您要做的就是在检测到冲突时将myGamePiece.speedXmyGamePiece.speedX设置为0 Something like: 就像是:

function updateGameArea() {
  myGameArea.clear();
  myObstacle.update();
  if (myGamePiece.crashWith(myObstacle)) {
    myGamePiece.speedX = 0;
    myGamePiece.speedY = 0;
  }
  myGamePiece.x += myGamePiece.speedX;
  myGamePiece.y += myGamePiece.speedY;
  myGamePiece.update();
}

Edit: You probably want to apply some code to "back up" when a collision is detected, so the pieces are no longer in a collided state 编辑:您可能想在检测到碰撞时将一些代码应用于“备份”,因此零件不再处于碰撞状态

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

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