0
votes

I am trying to build a game, where you have a cannnon image that will constantly point towards your mouse, and on clicking, will fire a ball in the direction of the cannon. I understood that the math for the ball movement should be so: vx= -vi * cos(θ) vy= vi * sin(θ). I got the image to point towards the mouse, but when it fires the ball, it seems (to me) to go in a random direction. Code Snippet:

var ball = {
  x: 20,
  y: 20,
  vx: 0,
  vy: 0
}
setInterval(move_ball, 100);
var degree;

function rotate(e, elt) {
  var offset = elt.offset();
  var center_x = (offset.left) + (elt.width() / 2);
  var center_y = (offset.top) + (elt.height() / 2);
  var mouse_x = e.pageX;
  var mouse_y = e.pageY;
  var radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
  degree = (radians * (180 / Math.PI) * -1);
  if (degree < 90 && degree > 0) {
    degree = 90
  }
  if (degree > -180 && degree < 0) {
    degree = 179
  }
  $(elt).css('-moz-transform', 'rotate(' + degree + 'deg)');
  $(elt).css('-webkit-transform', 'rotate(' + degree + 'deg)');
  $(elt).css('-o-transform', 'rotate(' + degree + 'deg)');
  $(elt).css('-ms-transform', 'rotate(' + degree + 'deg)');
  document.getElementById('out').innerHTML = degree;
}


document.onmousemove = function(e) {
  rotate(e, $('#img'));
}
document.onclick = function() {
  document.getElementById('ball').style.right = '20px';
  document.getElementById('ball').style.bottom = '20px';
  ball.vx = 5 * Math.cos(degree);
  ball.vy = 5 * Math.sin(degree);
}

function move_ball() {
  ball.x = parseInt(document.getElementById('ball').style.right.substring(0, document.getElementById('ball').style.right.length - 3));
  ball.y = parseInt(document.getElementById('ball').style.bottom.substring(0, document.getElementById('ball').style.bottom.length - 3));
  ball.x += Math.abs(ball.vx);
  ball.y += Math.abs(ball.vy * -1);
  document.getElementById('ball').style.right = ball.x.toString() + 'px';
  document.getElementById('ball').style.bottom = ball.y.toString() + 'px';
}
/*
vx= -vi*cos(θ)
vy= vi*sin(θ)
θ= sprite direction
*/
#img {
  width: 20px;
  height: 40px;
  position: absolute;
  bottom: 15px;
  right: 15px;
}

#ball {
  width: 10px;
  height: 10px;
  position: absolute;
  bottom: 20px;
  right: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="img" src="https://lh3.googleusercontent.com/FF_QMZJ187zosdjWPzrnzJKlHl8UvtPjIJr3Uma7LEgPCz22_KN5wqJ_Auka3z3-x3YvCw=s85" />
<img id="ball" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Circle_-_black_simple_fullpage.svg/1000px-Circle_-_black_simple_fullpage.svg.png">
<div id="out"></div>
1

1 Answers

1
votes

You forgot to transform the degree angle back into a radians angle. Math.cos(degree); Math.sin(degree); will indeed return randomly seeming results.


Of course, you have to reverse the full computation of

 degree = -180/pi*atan2(x,y)

as in

  var radians = -degree*Math.PI/180;
  ball.vx = 5 * Math.sin(radians);
  ball.vy = 5 * Math.cos(radians);

Note that the calling convention to get the angle of the cartesian point (x,y) is atan2(y,x), while you used atan2(x,y), which forces to exchange sin and cos in the velocity computation.