移动圆圈碰撞

时间:2017-07-23 21:27:13

标签: javascript collision

我正在尝试实现一个能够检测2个移动圆和矩形之间碰撞的函数,对于我正在做的小游戏。 它很接近,但它不能像它应该的那样工作,我无法弄清楚原因。任何帮助非常感谢。

/**************/
//Game Framework
/**************/
window.onload = function init() {
  //Starting a new game
  var game = new GF();
  game.start();
};

var GF = function() {
  //Variables
  var canvas, ctx, w, h;
  var height, width;
  var frameCount = 0;
  var lastTime;
  var fps, fpsContainer;
  var gamepad;
  var inputStates = {};
  var score;
  var bullets = [];
  var numberOfShips;
  var delta, oldTime = 0;

  var tank = {
    x: 10,
    y: 10,
    cx: 115 + 0.5 * 10,
    cy: 65 + 0.5 * 15,
    angle: 0,
    speed: 100,
  };

  var tankBoundingRect = {
    x: tank.x,
    y: tank.y,
    width: 40,
    height: 45
  }

  var enemy = {
    x: 0,
    y: 0,
    width: 10,
    height: 80,
    speed: 1
  }

  var weapon = {
    x: 955,
    y: 10,
    startX: 0,
    startY: 0,
    r: 3,
    speed: 5
  }

  var weapon2 = {
    y: 70,
    startY: 0
  }

  var distanceToMove = function(delta, speed) {
    return (speed * delta) / 1000;
  }

  var measureFPS = function(newTime) {
    if (lastTime === undefined) {
      lastTime = newTime;
      return;
    }
    var diffTime = newTime - lastTime;

    if (diffTime >= 1000) {
      fps = frameCount;
      frameCount = 0;
      lastTime = newTime;
    }
    fpsContainer.innerHTML = "FPS: " + fps;
    frameCount++;
  };

  function timer(currentTime) {
    var delta = currentTime - oldTime;
    oldTime = currentTime;
    return delta;
  }

  function clearCanvas() {
    ctx.clearRect(0, 0, w, h);
  }

  function drawTank(x, y) {
    ctx.save();
    ctx.translate(x, y);
    drawBoundingRect();
    ctx.strokeStyle = "#ffa64d";
    ctx.fillStyle = "#b1b181"
    ctx.strokeRect(100, 50, 40, 15);
    ctx.strokeRect(100, 80, 40, 15);
    drawCanon(tank.cx, tank.cy, tank.angle);
    ctx.restore();
  }

  function drawCanon(cx, cy, angle) {
    ctx.translate(cx, cy);
    ctx.rotate(angle);
    ctx.translate(-cx, -cy);
    ctx.fillRect(115, 65, 10, 15);
    ctx.strokeRect(125, 72.5, 5, 2);
  }

  function drawBoundingRect() {
    ctx.strokeStyle = "white";
    ctx.strokeRect(100, 50, 40, 45);
  }

  function tankFire() {
    ctx.save();

  }

  function updatetankPosition() {
    tank.speedX = tank.speedY = 0;

    if (inputStates.left) {
      //ctx.fillText('left', 150, 20);
      tank.speedX = -tank.speed;
    }
    if (inputStates.right) {
      //ctx.fillText('right', 150, 50);
      tank.speedX = tank.speed;
    }
    if (inputStates.up) {
      //ctx.fillText('up', 150, 80);
      tank.speedY = -tank.speed;
    }
    if (inputStates.down) {
      //ctx.fillText('down', 150, 120);
      tank.speedY = tank.speed;
    }
    if (inputStates.space) {
      //ctx.fillText('space bar', 160, 150);
    }
    if (inputStates.mousePos) {
      /*ctx.fillText("x = " + inputStates.mousePos.x + " y = " +
        inputStates.mousePos.y, 5, 150);*/
    }
    if (inputStates.mousedown) {
      //ctx.fillText("mousedown b" + inputStates.mouseButton, 5, 180);
      tank.speed = 500;
    } else {
      tank.speed = 100;
    }
    tank.x += distanceToMove(delta, tank.speedX);
    tank.y += distanceToMove(delta, tank.speedY);

    if (tank.y < -50) {
      tank.y = -50;
    }
    if (tank.y > 555) {
      tank.y = 555;
    }
    if (tank.x < -100) {
      tank.x = -100;
    }
  }

  function drawEnemy(x, y) {
    ctx.save();
    ctx.strokeStyle = "red";
    ctx.strokeRect(w - enemy.width, y, enemy.width, enemy.height);
    drawEnemyWeapons();
    ctx.restore();
  }

  function drawEnemyWeapons() {
    ctx.save();
    ctx.strokeStyle = "green";
    ctx.strokeRect(w - enemy.width - 30, enemy.y + 10, 30, 2);
    ctx.strokeRect(w - enemy.width - 30, enemy.y + 70, 30, 2);
    ctx.restore();
  }

  function moveEnemy() {
    enemy.y += enemy.speed;
    checkEnemyPosition();
  }

  function checkEnemyPosition() {
    if (enemy.y + enemy.height > h || enemy.y <= 0) {
      enemy.speed = -enemy.speed;
    }
  }

  function enemyFire(x, y) {
    ctx.save();
    ctx.fillStyle = "yellow";
    ctx.beginPath();
    ctx.arc(weapon.x, weapon.startY, weapon.r, 0, 2 * Math.PI);
    ctx.arc(weapon.x, weapon2.startY, weapon.r, 0, 2 * Math.PI);
    ctx.fill();
    ctx.restore();
  }

  function startShooting() {
    weapon.startX = weapon.x;
    weapon.startY = enemy.y + weapon.y;
    weapon2.startY = enemy.y + weapon2.y;
    weapon.targetX = tank.x;
    weapon.targetY = tank.y;
    var dx = tank.x - weapon.startX;
    var dy = tank.y - weapon.startY;
    weapon.angle = Math.atan2(dy, dx);
    console.log(tank.x);
    console.log(tank.y);
    console.log(weapon.x);
    console.log(weapon.startY);
    console.log(weapon2.startY);
  }

  function moveShot() {
    weapon.x += weapon.speed * Math.cos(weapon.angle);
    if (weapon.x < 0) {
      weapon.x = 955;
      startShooting();
    }
  }

  function tankHit(x0, y0, w0, h0, cx, cy, r) {
    var testX = cx;
    var testY = cy;

    if (testX < x0) testX = x0;
    if (testX > (x0 + w0)) testX = (x0 + w0);
    if (testY < y0) testY = y0;
    if (testY > (y0 + h0)) testY = (y0 + h0);

    return (((cx - testX) * (cx - testX) + (cy - testY) * (cy - testY)) < r * r);
  }

  var mainLoop = function(time) {
    clearCanvas();
    measureFPS(time);
    delta = timer(time);
    updateGamePadStatus();
    drawTank(tank.x, tank.y, tank.angle);
    drawEnemy(enemy.x, enemy.y);
    enemyFire();
    moveEnemy();
    moveShot();
    updatetankPosition(delta);
    if (tankHit(tank.x, tank.y, 40, 45, weapon.x, weapon.startY, weapon.r) || tankHit(tank.x, tank.y, 40, 45, weapon.x, weapon2.startY, weapon.r)) {
      ctx.fillStyle = "red";
      ctx.fillText("HIT", 400, 50);
    };
    requestAnimationFrame(mainLoop);
  };

  function getMousePos(evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
  }

  function updateGamePadStatus() {
    scangamepads();
    checkButtons(gamepad);
    checkAxes(gamepad);
  }

  window.addEventListener("gamepadconnected", function(evt) {
    gamepad = evt.gamepad;
    var index = gamepad.index;
    var id = gamepad.id;
    console.log("Gamepad connected");
  });

  window.addEventListener("gamepaddisconnected", function(evt) {
    var gamepad = evt.gamepad;
    var index = gamepad.index;
    console.log("Gamepad No " + index + " has been disconnected.");
  });

  function checkAxes(gamepad) {
    if (gamepad === undefined) return;
    if (!gamepad.connected) return;

    inputStates.left = inputStates.right = inputStates.up = inputStates.down = false;
    if (gamepad.axes[0] > 0.5) {
      inputStates.right = true;
      inputStates.left = false;
    } else if (gamepad.axes[0] < -0.5) {
      inputStates.left = true;
      inputStates.right = false;
    }

    if (gamepad.axes[1] > 0.5) {
      inputStates.down = true;
      inputStates.up = false;
    } else if (gamepad.axes[1] < -0.5) {
      inputStates.up = true;
      inputStates.down = false;
    }
    inputStates.angle = Math.atan2(-gamepad.axes[1], gamepad.axes[0]);
  }

  function checkButtons(gamepad) {
    if (gamepad === undefined) return;
    if (!gamepad.connected) return;
    for (var i = 0; i < gamepad.buttons.length; i++) {
      var b = gamepad.buttons[i];
      if (b.pressed) {
        console.log(i + ":" + b.value);
      }
      var gas = gamepad.buttons[7];
      var moveRight = gamepad.buttons[5];
      var moveLeft = gamepad.buttons[4];

      if (gas.pressed) {
        tank.speed = gas.value * 500;
      }
      /*if (moveRight.pressed) {
        tank.angle += (Math.PI / 800);
      }
      if (moveLeft.pressed) {
        tank.angle -= (Math.PI / 800);
      }
      */
    }
  }

  function scangamepads() {
    var gamepads = navigator.getGamepads();
    for (var i = 0; i < gamepads.length; i++) {
      if (gamepads[i])
        gamepad = gamepads[i];
    }
  }
  /****************/
  //Creating enemies
  /****************/
  /*  function enemyFire(n) {
          var enemiesArray = [];
    
          for (var i=0; i < n; i++) {
            var enemy = {
              x: w-
            }
          }
      */
  var start = function() {
    fpsContainer = document.createElement('div');
    document.body.appendChild(fpsContainer);
    canvas = document.getElementById('myCanvas');
    w = canvas.width;
    h = canvas.height;
    ctx = canvas.getContext('2d');
    ctx.font = "20px Back to Black Demo";
    var slide = document.querySelector("#fps");
    slide.addEventListener('input', function(e) {
      if (enemy.speed > 0) {
        enemy.speed = slide.value * 1;
      } else {
        enemy.speed = slide.value * -1;
      }
    });

    // Listener for pressed keys
    window.addEventListener('keydown', function(evt) {
      if (evt.keyCode === 37) {
        inputStates.left = true;
      } else if (evt.keyCode === 38) {
        inputStates.up = true;
      } else if (evt.keyCode === 39) {
        inputStates.right = true;
      } else if (evt.keyCode === 40) {
        inputStates.down = true;
      } else if (evt.keyCode === 32) {
        inputStates.space = true;
      }
    }, false);

    // Listener for released keys
    window.addEventListener('keyup', function(evt) {
      if (evt.keyCode === 37) {
        inputStates.left = false;
      } else if (evt.keyCode === 38) {
        inputStates.up = false;
      } else if (evt.keyCode === 39) {
        inputStates.right = false;
      } else if (evt.keyCode === 40) {
        inputStates.down = false;
      } else if (evt.keyCode === 32) {
        inputStates.space = false;
      }
    }, false);

    canvas.addEventListener('mousemove', function(evt) {
      inputStates.mousePos = getMousePos(evt);
    }, false);

    canvas.addEventListener('mousedown', function(evt) {
      inputStates.mousedown = true;
      inputStates.mouseButton = evt.button;
    }, false);

    canvas.addEventListener('mouseup', function(evt) {
      inputStates.mousedown = false;
    }, false);

    startShooting();
    requestAnimationFrame(mainLoop);
  };

  return {
    start: start
  };
};
<span id="fps"></span>
<canvas id="myCanvas" width="250" height="150" />

0 个答案:

没有答案