moving a character diagonally

Started by
7 comments, last by Splinter of Chaos 15 years, 9 months ago
When the player presses the left or right key, the character moves 3 points horizontally. When the player presses up or down, the character moves 3 points vertically. How do I figure out how many points horizonally and vertically a player moves when moving diagonally???
Advertisement
Can you give some context?

Surely if you have a start position, e.g. (0,0) and a finish position, (2,1), then you can get the difference easily by subtracting e.g. 2 horizontal units and 1 vertical unit.

Or if you only know the horizontal distance A and vertical distance B, the diagonal length is sqrt( A^2 + B^2 ) by Pythagorus' Theorem.
Well, as your post did not give enough information and it's posted under "for beginners", I suppose you are using a 2D array. If that is the case, you can NOT directly move diagonally towards a goal, you can use different techniques to reach the goal as "diagonally" as possible.

As an example , have a look at:
[Source]static void Move(int y, int x){                if ((y > gypos) && (x < gxpos)) { pypos--; pxpos++; }                if ((y > gypos) && (x > gxpos)) { pypos--; pxpos--; }                if ((y < gypos) && (x < gxpos)) { pypos++; pxpos++; }                if ((y < gypos) && (x > gxpos)) { pypos++; pxpos--; }                if ((y < gypos) && (x == gxpos)) pypos++;                if ((y > gypos) && (x == gxpos)) pypos--;                if ((y == gypos) && (x < gxpos)) pxpos++;                if ((y == gypos) && (x > gxpos)) pxpos--;}[/Source]


x and y are basicly the player's position , somewhat the same as pXpos and pYpos ( only these suffer some modifications ).

Now what you do is check every possible position of the "player" ( pXpos, pYpos ) in reference to "goal" ( gXpos, gYpos ). Using the above code, the 'player' will move in a diagonal way and once it reaches the same line as the target just goes straight for it...

Now if you are talking about 2D movements, some trigonometry should solve the problem and the above mentioned theorem


Hope it helped
sin, cos and tan functions

for example, in a 2D game:

C = characterD = destinationHD = normal distance when traveling in a horizontal line     D    /|   / |  /  | /   |/    |C--------HD


The line from HD to D should be the same.
Because the character is moving in a diagonal line (= 45 degrees = PI / 4 radians)
so the vertical movement should be sin(rotation) * movement
In your case: sin(PI / 4) * 3 = 2.121

the horizontal movement should be cos(rotation) * movement
In your case: cos(PI / 4) * 3 = 2.121

well, if one unit diagonally is roughly the same distance as one unit to each side, diagonal movement would also be 3 units as well. Otherwise, I'd say to scale it so that the distance you'd be moving diagonally is roughly equivalent to the distance you'd be moving sideways (it may need some rounding)

[edit:] didn't realize the problem was math, sorry about that.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
Well, as I understand, your problem is math... I'm not sure.

However, if you are moving diagonally you move like this:

y|  /| /|/) - - -  x


So, in order to get how much you move you would do this:

x = (distance) * (cosine of the angle)
y = (distance) * (sine of the angle)

being the angle the one formed between the x axis and the line (marked with a ")")

Edit: :) looks like MadMax1992 got ahead of me... lol
------------------------------"Carpe Diem!""Failure is the prequel of success"_.-:Jimbo:-._
Why limit yourself to eight directions? By using floats or doubles for x and y speed and position, you can go in practically infinite direction. You'll also get more accuracy when trying to move the same amount of distance each frame, even if you DO limit it to eight directions.

And, if you're not too keen on trig (NOTE: This only works in eight directions):
D is the amount of Distance the sprite moves in one frame. D should be the same every time, unless it's zero.X is the number of pixels moved horizontally.Y is like X, but vertical.According to the distance formula: D = sqrt( X^2 + Y^2 )If you are moving the same number of pixels on the X and Y direction, then:          D        = sqrt( 2 * X^2 ) = sqrt( 2 * Y^2 )          D^2      =       2 * X^2   =       2 * Y^2         (D^2)/2   =           X^2   =           Y^2   sqrt( (D^2)/2 ) =           X     =           YFind X and Y by setting them equal to sqrt( (D^2)/2 ).

I tested this with Google calculator and it should work, but we warned that if X and Y are 3, the answer returned is 4.24264069 and if you're using ints for position and x and y speed, you'll always be moving slightly slower than D because everything after the decimal will get cut off.

Also, if you use this, you'll have to make X and Y negative, when appropriate, your self because this equation doesn't factor that in.
Quote:Original post by ed209
When the player presses the left or right key, the character moves 3 points horizontally. When the player presses up or down, the character moves 3 points vertically. How do I figure out how many points horizonally and vertically a player moves when moving diagonally???


As others have said, trigonometry is your friend. I suggest you learn it if you want to pursue games programming :). Computer Graphics is just maths that looks cool.

However, as Splinter of Chaos said, integer truncation (4.46334 -> 4), will make your guy go slower. To solve this, seperate the on-screen position from the world-position. This is often a problem I see people have, especially with 2D games where the correlation is much higher. Calculate his velocity/acceleration/position, etc, in world coordinations, then transform this final position into screen coordinates. World-coordinates are nearly always one with a floating point type (you haven't specified a language, but it's probably a float, :D). If it's a simple game, it's probably just a cast from the float to the integer, and banging it up on screen. Immediately, you've solved the diagonal problem, because now the floating point position is being updated correctly, so if he moves 2.5f ever frame, after to frames he'll be at 5, and not 4. Finally, if you ever intend to support widescreen, you'll find this separation very, very, useful.

[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
Just a note:

I messed up. When D should b 3, X and Y should be 2.12132034, not 4.24264069, which really doesn't make sense.

This topic is closed to new replies.

Advertisement