Reputation: 12718
I am making a game, and the player moves by clicking on a point on the map. I then use a function to calculate angle to click point which sends them on the trajectory towards that click point.
var angle = player.angleToPoint(new me.Vector2d(e.gameX, e.gameY));
player.vel.set(Math.cos(angle) * 2, -Math.sin(angle) * 2);
This works.
The issue is, I want the player to stop moving, and change to "stand" animation, once they've reached that click point. The location of the click point and the player are given in decimals:
log(clickPointX + " , " + clickPointY + ", " + player.x + ", " + player.y) gives:
2491.830945558739 , 627.4212034383954, 4894.160772981247, 813.5879189245883
In my update function, I wanted to check if it equals, but the velocity increment size will never allow it to equal. If I check <= or >=,
if (player.x == clickPointX && player.y == clickPointY) {
player.vel.x = 0;
player.vel.y = 0;
player.setCurrentAnimation("stand");
}
else {
if (!player.isCurrentAnimation("walk")) {
player.setCurrentAnimation("walk");
}
}
This doesn't seem to work. Is there a better way to check if the player has arrived at the click point location? Perhaps check if the player's location is within the range of the click location?
Upvotes: 0
Views: 739
Reputation: 9858
As (in your example) the player moves by 2 pixels at a time you could check whether the player is within 2 pixels of the target. If precision is important to you, you might then want to add something so that the player moves to the exact pixel position in the next step (although, because of how floating point numbers are stored and manipulated, the coordinates are still unlikely to be exactly the same, but only the same to the nearest whole number).
var xdist = player.x - clickPointx,
ydist = player.y - clickPointy,
sqDist = xdist * xdist + ydist * ydist;
if (sqDist >= .25 && sqDist < 4) { // close but not quite there
player.vel.x = -xdist; // cover the remaining distance in the next step
player.vel.y = -ydist;
} else if (sqDist < .25) { // close enough to stop
player.vel.x = 0;
player.vel.y = 0;
}
Alternatively use parseInt
to check if the whole-number coordinates are the same.
if (parseInt(player.x, 10) == parseInt(clickPointx, 10)
&& parseInt(player.y, 10) == parseInt(clickPointy, 10)) {
player.vel.x = 0;
player.vel.y = 0;
} else if(Math.pow(player.x - clickPointx, 2)
+ Math.pow(player.y - clickPointy, 2) < 4) {
player.vel.x = clickPointx - player.x;
player.vel.y = clickPointy - player.y;
}
Upvotes: 1
Reputation: 96
Your player will almost never land exactly on the click point, so I would check that the difference between player X and click X, and between player Y and click Y, are both less than the speed the player is moving. So if it's X += 5 and Y += 10, then those are the values you should use in your proximity check.
When the player is within range, you can optionally adjust him to the exact location of the click point, unless that doesn't matter for your game.
Consider wrapping all values in parseInt(val, 10). If you're drawing on the HTML5 canvas, decimal values can trigger anti-aliasing and cause images to blur, which might not be what you want.
Upvotes: 0