碰撞检测在我的游戏中不准确

时间:2015-12-16 16:28:38

标签: javascript collision-detection

我正在使用javascript制作太空入侵者游戏。所以,让我说到这一点,在我的更新函数中,在最后一个for循环中我说每次碰撞console.log("collision"),但发生的事情是起初它等待直到它到达敌人(whitch是好的),然后当它接触它记录的敌人碰撞(whitch再次好),但是当它远离它时仍会记录碰撞?这是为什么?我的碰撞功能错了,告诉你.Thankyou!这是我的代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Space Invaders</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <style>
  canvas{
    position: absolute;
    top:0px;
    left:0px;
    background: transparent;
  }
  #backgroundCanvas{
   background-color: black;
  }

  </style>
</head>
<body>

<canvas id="backgroundCanvas" width="550" height="600"></canvas>
<canvas id="playerCanvas" width="550" height="600"></canvas>
<canvas id="enemiesCanvas" width="550" height="600"></canvas>

   <script>
   (function(){
    $(document).ready(function(){
      var game = {};

      game.stars = [];
      game.width = 550;
      game.height = 600;
      game.images = [];

      game.doneImages = 0;
      game.requiredImages = 0;
      game.keys = [];
      game.projectiles = [];
      game.enemies = [];

      game.count = 0;
      game.division = 48;
      game.left = false;
      game.enemySpeed = 3;

      game.fullShootTimer = 10;
      game.shootTimer = game.fullShootTimer;


      game.contextBackground = document.getElementById("backgroundCanvas").getContext('2d');

      game.contextPlayer = document.getElementById("playerCanvas").getContext('2d');

      game.contextEnemies = document.getElementById("enemiesCanvas").getContext('2d');

      game.player = {
        x:  game.width / 2 -50,
        y:  game.height - 103,
        width:80,
        height:100,
        speed: 3,
        rendered: false
      }




      $(document).keydown(function(e){
        game.keys[e.keyCode ? e.keyCode : e.which] = true;

      })
      $(document).keyup(function(e){
       delete game.keys[e.keyCode ? e.keyCode : e.which];

      })

      /*
      up -38
      down-40
      left -37
      right-39
      w-87
      a-65
      s-83
      d-68
      space-32
    */

    function addBullet(){
      game.projectiles.push({
        x:game.player.x,
        y:game.player.y,
        size: 20,
        speed: 3,
        image: 2

      })

    }

      function init(){
        for(i=0; i<600;i++){
          game.stars.push({
            x:Math.floor(Math.random()* game.width),
            y:Math.floor(Math.random()* game.height),
            size: Math.random()*5
          })
        }

        for(y=0;y<5;y++){
          for(x =0;x<5;x++){
             game.enemies.push({
              x: (x*70) + (70*x) + 10,
              y: (y*70) + (10*y) + 40,
              width:70,
              height: 70,
              image:1
             })
          }
        }


        loop();
      }
      function addStars(num){
          for(i=0; i<num;i++){
            game.stars.push({
              x:Math.floor(Math.random()* game.width),
              y:game.height+10,
              size: Math.random()*5
            })
          }

      }
      function update(){
         addStars(1);
         game.count++;

         if(game.shootTimer>0){
           game.shootTimer--;
         }
           for(i in game.stars){
            if(game.stars[i].y <= -5){
                game.stars.splice(i,1);
            }
            game.stars[i].y--;
           }

           if(game.keys[37] || game.keys[65]){
            if(game.player.x>=0){
              game.player.x-=game.player.speed;
              game.player.rendered = false;
            }

           }
          if(game.keys[39] || game.keys[68]){
              if(game.player.x<=500-50){
              game.player.x+=game.player.speed;
              game.player.rendered = false;
            }

           }
           if(game.count % game.division == 0){
            game.left = !game.left;
           }

           for(i in game.enemies){
              if(game.left){

                game.enemies[i].x-=game.enemySpeed;
              }else{
                game.enemies[i].x+=game.enemySpeed;
              }
            }

            for(i in game.projectiles){
                game.projectiles[i].y-=3;
                if(game.projectiles[i]<=-10){
                  game.projectiles.splice(i,1)
                }
            }

            if(game.keys[32] && game.shootTimer<=0){
                addBullet();
                game.shootTimer = game.fullShootTimer
            }

            for(m in game.enemies){
              for(p in game.projectiles){
                  if(collision(game.enemies[m], game.projectiles[p])){
                    console.log("collision")
                  }
              }
            }
        }

      function render(){
         game.contextBackground.clearRect(0,0,game.width,game.height)
         game.contextBackground.fillStyle = "white";
         for(i in game.stars){
            var star = game.stars[i];
            game.contextBackground.fillRect(star.x,star.y,star.size,star.size);
         }
         if(!game.player.rendered){
       game.contextPlayer.clearRect(0, 0, game.width, game.height);
      game.contextPlayer.drawImage(game.images[0], game.player.x, game.player.y, game.player.width, game.player.height);
      game.player.rendered = true;
         }

         game.contextBackground.clearRect(0, 0, game.width, game.height);
         game.contextEnemies.clearRect(0, 0, game.width, game.height);
         for(i in game.enemies){
          var enemy = game.enemies[i];
          game.contextEnemies.drawImage(game.images[enemy.image], enemy.x, enemy.y, enemy.width, enemy.height);
         }

         for(i in game.projectiles){
           var proj = game.projectiles[i];
            game.contextEnemies.drawImage(game.images[proj.image], proj.x, proj.y, proj.size, proj.size);

         }
      }

      function loop(){
          requestAnimFrame(function(){
            loop();
        });
        update();
        render();
      }

      function initImages(paths){
        game.requiredImages = paths.length;
          for(i in paths){
              var img = new Image;
              img.src = paths[i];
              game.images[i] = img;
              game.images[i].onload = function(){
                  game.doneImages++;
              }
          }
      }

      function collision(first,second){
        return !(first.x>second.x + second.width||
                  first.x+first.width < second.x||
                 first.y>second.y+second.height||
                  first.y+first.height<second.y);

      }

      function checkImages(){

        if(game.doneImages>=game.requiredImages){
          init();
        }
        else{
          setTimeout(function(){
            checkImages();

          },1)
        }
      }
      game.contextBackground.font = "bold 50px monaco"
      game.contextBackground.fillStyle = "white";
      game.contextBackground.fillText("loading" , game.width/2-100 ,game.height/2-25)
     initImages(["player.gif", "enemy.png", "bullet.jpg"])
      checkImages();
});

  window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          window.oRequestAnimationFrame      ||
          window.msRequestAnimationFrame     ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
   })();
   })();

   </script>

</body>
</html>

2 个答案:

答案 0 :(得分:0)

这是我使用的简单矩形到矩形碰撞检测,对我来说很好用

// Just incase you want to create a simple Mathematics object :p

function Mathematics()
{

}

Mathematics.prototype.PointInRect = function(pnt_x, pnt_y, rect_x, rect_y, rect_w, rect_h)
{
    if ( (pnt_x >= rect_x) && (pnt_x <= rect_x + rect_w - 1) )
    {
        if ( (pnt_y >= rect_y) && (pnt_y <= rect_y + rect_h - 1) )
        {return true;}
    }
    return false;
}

Mathematics.prototype.RectToRectCollision = function(rect1_x, rect1_y, rect1_w, rect1_h,
                             rect2_x, rect2_y, rect2_w, rect2_h)
{
    // top-left corner
    if ( this.PointInRect(rect1_x, rect1_y, rect2_x, rect2_y, rect2_w, rect2_h) ){return true;}
    // top-right corner
    if ( this.PointInRect(rect1_x + rect1_w - 1, rect1_y, rect2_x, rect2_y, rect2_w, rect2_h) ){return true;}
    // bottom-right corner
    if ( this.PointInRect(rect1_x + rect1_w - 1, rect1_y + rect1_h - 1, rect2_x, rect2_y, rect2_w, rect2_h) ){return true;}
    // bottom-left corner
    if ( this.PointInRect(rect1_x, rect1_y + rect1_h - 1, rect2_x, rect2_y, rect2_w, rect2_h) ){return true;}
    // Check to see if rectangle 2 is hit any part of rectanlge 1
    // top-left corner
    if ( this.PointInRect(rect2_x, rect2_y, rect1_x, rect1_y, rect1_w, rect1_h) ){return true;}
    // top-right corner
    if ( this.PointInRect(rect2_x + rect2_w - 1, rect2_y, rect1_x, rect1_y, rect1_w, rect1_h) ){return true;}
    // bottom-right corner
    if ( this.PointInRect(rect2_x + rect2_w - 1, rect2_y + rect2_h - 1, rect1_x, rect1_y, rect1_w, rect1_h) ){return true;}
    // bottom-left corner
    if ( this.PointInRect(rect2_x, rect2_y + rect2_h - 1, rect1_x, rect1_y, rect1_w, rect1_h) ){return true;}
    // If there is no collision
    return false;
}

示例调用

mathematics = new Mathematcis();

if (mathematics.RectToRectCollision(
                bullet.XPos,
                bullet.YPos,
                bullet.Sprite.width,
                bullet.Sprite.height,
                enemy.XPos,
                enemy.YPos,
                enemy.Sprite.width,
                enemy.Sprite.height))
{
    alert("collision");
}

jsFiddle:https://jsfiddle.net/s6zzmxhz/

答案 1 :(得分:0)

您的代码中检查是否应删除项目符号时出错:

for(i in game.projectiles){
  game.projectiles[i].y-=3;
  if(game.projectiles[i].y<=-10){   <-- Missing the "y"
    game.projectiles.splice(i,1)
  }
}