Movement based on mouse click XNA
Movement based on mouse click XNA
I'm making a server/client game with movement similar to strategy games like Warcraft 1/2/3 etc.. where the player moves by right clicking on somewhere on the area and the character tries to move there. I'm trying to make the character always go in a straight line towards the point until it gets there (or close enough). The code I'm using now gets the character there but in a weird way.
When I click somewhere under the character (higher Y coordinate) it moves in a straight line, but when I click above it (lower Y coordinate), the character moves like it's making a circle while moving, but it still gets there, only not the way I want it to.
Here's the code that runs every update to move it.
if (this.order == "Move")
{
if (Math.Abs(this.orderPos.X - this.warlockPos.X) < this.moveSpeed && Math.Abs(this.orderPos.Y - this.warlockPos.Y) < this.moveSpeed)
{
this.warlockPos = this.orderPos;
this.order = "None";
this.orderPos = Vector2.Zero;
}
else
{
delta = this.orderPos - this.warlockPos;
if (delta.Y == 0)
{
if (delta.X < 0)
angle = -90;
else
angle = 90;
}
else
{
if (delta.Y < 0)
angle = 180 + Math.Atan(delta.X / delta.Y);
else
angle = Math.Atan(delta.X / delta.Y); ;
}
this.warlockPos = new Vector2(this.warlockPos.X + this.moveSpeed * (float)Math.Sin(angle), this.warlockPos.Y + this.moveSpeed * (float)Math.Cos(angle));
}
}
this.order == move means the client's last order was to move.
orderPos is the place where the client last told the server the character should move.
warlockPos is the current position of the character (where it was by the end of the previous update).
moveSpeed is just the speed at which it moves.
I use delta and angle to figure out where the character should move in this update.
So, what's making the character move in a circular way when the point it's moving towards is above it?
1 Answer
1
I see a few problems with this code originating from the use of angles. It's not that you can't use angles, but the code becomes more complicated with this approach and prone to error. Instead, I used some vector methods such as Length()
to check if the warlock is close to his destination, and Normalize()
when I covert the delta vector into a unit vector in the same direction and with the magnitude of his moveSpeed (in order to move him that far). Here is what I came up with:
Length()
Normalize()
if (order == "Move")
{
Vector2 delta = orderPos - warlockPos;
if (delta.Length() < moveSpeed)
{
warlockPos = orderPos;
order = "None";
orderPos = Vector2.Zero;
}
else
{
delta.Normalize();
delta *= moveSpeed;
warlockPos += delta;
}
}
I'd also recommend not use the this
keyword if it isn't necessary (only if there is another local variable or parameter with the same name). I apologize if this was an intentional style choice. Also, I'd recommend using an enumeration instead for the order variable (for example order == Orders.Move
).
this
order == Orders.Move
No problem! Ah, understandable. Happy XNAing!
– Ideae
Jan 4 '15 at 12:27
Sorry, but could you please help me with something else (This code works perfectly btw ty)? How do I calculate the place(vector2) where a warlock will be knocked towards if he is knocked away from a nearby warlock. So if point A is near point B and point B knocks point A away from itself, towards what point will point A be moving? (I know how to make it move to that point thanks to the code you already gave me but I have no idea how to find that point)
– RontoKing
Jan 5 '15 at 23:24
Sure. You'd use a similar approach by finding the direction you want him to travel, normalizing that vector, and multiplying it by the distance you want him to be pushed. After that, all you need to do is add that vector to his starting position. So:
Vector2 dir = aPos - bPos; dir.Normalize(); dir *= pushDistance; Vector2 endPoint = aPos + dir;
– Ideae
Jan 6 '15 at 0:23
Vector2 dir = aPos - bPos; dir.Normalize(); dir *= pushDistance; Vector2 endPoint = aPos + dir;
I just had an idea. Would this work? 1. Find the delta vector to move the warlock towards the other one as if he was ordered to go there. 2. Get the opposite of that vector 3. Use -delta to move the warlock This way I'm just using what you already gave me last time I'm about to try to do it like this, so I'll tell you if it works! But thanks for helping again!
– RontoKing
Jan 6 '15 at 0:45
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thank you, that worked perfectly :D! By the way, I had to add this. to everything, but that's because the code is inside a function within a class so there are parameters.
– RontoKing
Jan 4 '15 at 12:25