Search code examples
javascriptcollision-detection

Collision Detection not accurate in my game


Im making a space invaders game using javascript. So let me get to the point, in my update function in the last for loop i said everytime they collide console.log("collision") , but what happenes is at first it waits until it gets to the enemies(whitch is good), then when it touches the enemies it logs collision(whitch is again good), but when it goes out far away it still logs collision? Why is that? Its something wrong with my collision function ill tell you that.Thankyou! here is my code:

<!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>

Solution

  • You have an error in your code in the place where it checks if the bullet should be removed:

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