3

Okay, so I want to make a javascript/html canvas game where the player is being followed by some enemies, and after a little bit of 'research' her is the most important part of my Monster (enemy) class:

  this.UpdateAngle = function() {
    this.dx = this.x - player.x;
    this.dy = this.y - player.y;
    this.angle = Math.atan2(this.dy, this.dx) * 180 / Math.PI;
    if (this.angle < 0) {
      this.angle += 2 * Math.PI;
    }
  }
  this.UpdateSpeed = function() {
    this.speedX = this.speed * Math.cos(this.angle);
    this.speedY = this.speed * Math.sin(this.angle);
  }
  this.Move = function() {
    this.UpdateAngle();
    this.UpdateSpeed();
    this.x += this.speedX;
    this.y += this.speedY;
  }

So what I meant to do here, was to calculate the angle from the enemy to the player with atan2() and then calculate how much I should move in the x and y axis by using cos() and sin(), the speed and the angle I calculated, and then just moved the calculated pixels.

This all seems to work well, until I move the player, then the enemies start to move in weird directions. I have no idea whats wrong, it would be awesome if someone could learn me how this is meant to be done. :D

You can see it in action here. *I have updated the code with PremierBromanov's suggestion.

ziggystar
  • 28,410
  • 9
  • 72
  • 124
  • I don't know the solution (I've long since forgotten the trigonometry I once knew), but as a means to debug I would suggest drawing a line extending from each entity in its current direction of movement, along with text to show its current speed. – Jordan Running Dec 17 '14 at 19:39
  • I can't help you... but instead I found another glitch. Sorry! :D If you move (to force an angle recalculation) horizontally when you happen to be exactly at the same height than an enemy, it starts running _from you_ instead of _towards you_ :) – AJPerez Dec 17 '14 at 19:42
  • As for finding the cause of why they act weird while the player is pressing the keys... I would add a lot of `console.log()` calls, at least once for each function, and probably one too each time you recalculate speedX, speedY, or angle. Analyze the trace log and compare what happens when moving. – AJPerez Dec 17 '14 at 19:49

2 Answers2

2

It may have something to do with this block

this.angle = Math.atan2(this.dy,this.dx) * 180 / Math.PI;
    if (this.angle < 0) {
      this.angle += 2 * Math.PI;

You are using Math.atan2 which outputs the angle in radians, then you are converting to degrees with * 180 / Math.PI; After that, you're checking to see if it's less than zero and adding 2Pi to the angle to make sure it's correctly calculating it's actual angle of a full circle minus the angle. BUT, you are using radians here instead of degrees. So when your code is negative, you're adding 2Pi to the degree, which isn't very much, but sometimes causes it to go positive. This is why your dots are spinning when you move. If you notice, the dots spin slower when you are farther away, meaning the negative angle is larger than 2Pi and so doesn't circle around right away.

in short, try changing it to this

if (this.angle < 0) {
      this.angle += 360;
    }
Premier Bromanov
  • 429
  • 6
  • 15
  • 1
    Isn't order irrelevant for multiplication and division? num1*(num2/num3) = (num1*num2)/num3 – NewbornCodeMonkey Dec 17 '14 at 20:02
  • 1
    No, you're right, it is irrelevant. It's just a habit i suppose, keeping fractions together. It's more useful when you're adding fractions and things like that, although most compilers are smart enough to multiply and divide before adding things, but I like to rule out any possibility of order of operations being wrong in my code so if it breaks I know exactly why – Premier Bromanov Dec 17 '14 at 20:12
  • Thanks, that helps, but they still seem to go in circles and weird directions sometimes. (i have updated the code on the site) –  Dec 18 '14 at 09:27
  • 1
    Seeing how it works when the player isnt moving, i think we need more information from your code. Also, if im reading Atan2 correcntly, it already checks for negative angles, so you may have some redundant code, which i didn't realize before – Premier Bromanov Dec 18 '14 at 17:54
  • 1
    Also, take a look at this [question](http://stackoverflow.com/questions/13849185/moving-an-object-along-a-straight-line-at-a-constant-speed-from-point-a-to-b?rq=1). While your math looks alright to me, it's possible it's not correct – Premier Bromanov Dec 18 '14 at 18:04
1

Ok, so it was actually Premier Bromanov who answered this, thanks, but I can't accept a comment, which it was, so I will just do this to make it more clear, if anyone should come by and want the answer too. The math i did was a bit wrong, and here is how my code ended up looking like:

this.UpdateAngle = function() {
  this.dx = player.x - this.x;
  this.dy = player.y - this.y;
  this.distance = Math.sqrt((this.dx*this.dx) + (this.dy*this.dy));
  this.angle = Math.atan2(this.dy,this.dx) * 180 / Math.PI;
}
  this.UpdateSpeed = function() {
  this.speedX = this.speed * (this.dx/this.distance);
  this.speedY = this.speed * (this.dy/this.distance);
}
this.Move = function() {
  this.UpdateAngle();
  this.UpdateSpeed();
  this.x += this.speedX;
  this.y += this.speedY;
}

Thanks again to Premier Bromanov, this is his answer, and also to everyone else, this was my first post and i am glad how fast i got a response! (I was the slowest one here) :D