简体   繁体   English

Javascript游戏碰撞检测墙

[英]Javascript game collision detection 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. 我正在尝试找出一种方法,将其像一堵墙一样,盒子可能会撞到墙,不再移动该方向并继续游戏,从而使墙起作用。

I've previously tried detecting what direction hit the wall and stopping movement that direction, but when I hold down an arrow key it moves through it. 之前,我曾尝试检测击中墙壁的方向并停止该方向的移动,但是当我按住箭头键时,它会在其中移动。

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>

The problem is here: 问题在这里:

  if (myGamePiece.crashWith(myObstacle)) {
    console.log("crash");
  } else {

In a real physics engine you detect collisions then you resolve collisions. 在真实的物理引擎中,您可以检测到碰撞,然后解决碰撞。 The simplest "resolve collision" would be to move the piece back to the place it was before the crash. 最简单的“解决碰撞”是将零件移回碰撞之前的位置。 Something like: 就像是:

  if (myGamePiece.crashWith(myObstacle)) {
    resolveCollision(myGamePiece, myObstacle);
  } else {

But to do this you'll need to modify your physics engine, and your movement function to use a velocity vector. 但是,要做到这一点,您将需要修改物理引擎和运动函数以使用速度矢量。 That means that instead of function checkKeyD(e) moving the piece, that function sets a velocity vector. 这意味着代替function checkKeyD(e)移动片段,该函数将设置速度矢量。 Then crashWith() will determine if the position plus the velocity vector is going to crash and resolve collision will un-crash it. 然后crashWith()将确定位置和速度矢量是否将要崩溃,并解决碰撞将使其崩溃。

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

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