moving character diagonally, instead of walking x direction first, then y...
red-dragon

Hey guys,
I've made more progress. Little Link can now move to the spot where the user left clicks. However, it's not the most sophisticated way. As it stands, I compute how many units on the x axis he has to move, then how many y. Then, I make him move, say +5 units on x axis, and then -5 on y. So, Little Link walks to the right, then up.

I would like to change this so that he moves diagonally to that point. If user has left-clicked in northeast direction, I want him to move directly in that direction. Hope I'm being clear here.

In updatesprite I have this:

1...
2..
3.
4 //Note: num2 = 3;
5 
6 //northeast
7 case 5:
8 mario->x += num2;
9 mario->y -= num2;
10 break;
11
12 //souteast
13 case 6:
14 mario->x += num2;
15 mario->y += num2;
16 break;
17
18 //southwest
19 case 7:
20 mario->x -= num2;
21 mario->y += num2;
22 break;
23
24 //northwest
25 case 8:
26 mario->x -= num2;
27 mario->y -= num2;
28 break;

Part of calculate_position:

     if(mario->x < x)  //&& (mario->y > y))
     {          
          if(mario->y > y)
          {
                      //Link will move northeast
                      ydir = 5;
                      ynew = mario->y - y;                      
          }
...
..
.

In while loop in main, if left-click is detected, do this:

1...
2..
3.
4 else if(mario->dir == 5)
5 ynew = ynew/3;
6
7 for(y1 = 0; y1<ynew; y1++)
8 {
9 erasesprite(screen, mario);
10 updatesprite(mario);
11 move_character();
12 acquire_screen();
13 draw_character_mario();
14 release_screen();
15 rest(50);
16 }

OK, so variable names might not make sense since I'm changing code, i.e. Mario should be Link, ynew will be changed to new_dir if I can make this diagonal thing work.

If I run this code, Link walks a perfect diagonal line, even though the cursor might be might be ten units to the left.

Make sense? Hope so; if not, ask away. Or just give me general advice at least ;)

Rick

Try vector movement. Do a forums search for vector movement.

Steve Terry

Simple trig should give you the direction angle, from there you can calculate deltax and deltay.

ImLeftFooted
double x, y;
double direction, speed;
...
x += sin(direction) * speed;
y += cos(direction) * speed;

direction ranges 0 to (2 * M_PI)
speed ranges 0 to some big number (probably less then 5 or so)

red-dragon

hey Steve, it's been a long time for me since I did simple trig.

Dustin, thanks for the help. Though for the sin, cos, and M_PI (that's pi, right, ha?), is there a library I need to include? If I'm missing the point, please elaborate. Really appreciate your help, thanks.

ImLeftFooted

Use

#include <cmath>

red-dragon

Dustin,
I've put this code in, but it's not working properly. At best, when I clicked northeast, Link walked straight then a little curve. Weird.

So, here come the questions:
double x, y: this is Link's x, y coords, right?

"direction rangest 0 to (2 * M_PI)"... I'm a bit lost here. In my code I have the normal 8 directions.

Sorry if I seem a bit dense. Explain away.

ImLeftFooted

sin and cos return a number ranging 0 to 1
sin and cos take an input value ranging 0 to (2 * M_PI). *
If you input 0 for sin you get 1 and cos you get 0. If you imagine the value of 0 as 'going right', this is correct. The x should increment and the y should not.
If you input (M_PI / 2) sin will give you 0 and cos will give you 1. Remember we're incrementing x by sin and y by cos. So this means 'go up'.
If you keep going in increments of (M_PI / 4), you'll head in four straight forward directions, right, up, left, and down.

The beauty of this system is that it takes care of all the in-between values, so (M_PI / 4) will go up and right.

Be careful though, cause the screen is actually upside down (ie quadrant 4). Up might easily come out as down.

Quote:

"direction rangest 0 to (2 * M_PI)"... I'm a bit lost here. In my code I have the normal 8 directions.

ok so if directions is a value ranging 0 to 8, you can pass it into sin and cos like so:

x += sin(directions * (2 * M_PI) / 8) * some_value;
y += cos(directions * (2 * M_PI) / 8) * some_valie;

[disclaimer]

  • you can actually pass values above (2 * M_PI) and below 0 and sin / cos will be just fine with it, but its easier conceptually to pretend they can only be in that range.

[edit]
I mixed up the return values for sin / cos, they're wrong.

Owell, hopefully this will clarify why you do that anyway.

Paul whoknows

Can you post your code? or perhaps a binary? so we can see what you are doing.
I am not sure what you really need, but if I am not wrong, perhaps the Distance formula between 2 points is what you need.
Like I said, post your code or a binary file! that will help a lot!

ImLeftFooted
Quote:

Can you post your code? or perhaps a binary? so we can see what you are doing.
I am not sure what you really need, but if I am not wrong, perhaps the Distance formula between 2 points [purplemath.com] is what you need.
Like I said, post your code or a binary file! that will help a lot!

I believe he wants to move his character by an arbitrary angle, which the distance formula cant do.

Distance formula is usefull for spherical collision detection.

Paul whoknows

sorry!, I meant the secant line between 2 points, using it little link would walk in a straight line from his current position to where the user left clicks.

ImLeftFooted

Ah yes, it would be usefull for that too :)

red-dragon

Paul,
are you talking about the d = sqrt(((x2-x1)^2) + ((y2-y1)^2)) formula?

ok, so that gives me d.... where would I go from here? ...what do I do with it? how will little ol' link walk diagonally?

I have code right here: code
It might not compile right now, but only kuz I'm cleaning code up a bit. He moves in x, then y. You'll see.

Steve Terry

double x, y;
double direction, speed;
...
x += sin(direction) * speed;
y += cos(direction) * speed;

Here all you need to determine is direction which you can get in radians if you use the nice little function atan2.

#include <math.h>
double direction = atan2(mouse_y - characterY, mouse_x - characerX);

Hope that helps, basically atan2 will return in radians the angle between two given points. Of course give a good speed variable, something less than 1.0 that will move your character smoothly between the two points. Now you have an angle in radians you can also convert that to a fixed point degree angle to pass into rotate_sprite so your character rotates at that angle as well.

ImLeftFooted
Quote:

d = sqrt(((x2-x1)^2) + ((y2-y1)^2)) formula?

Instead, you should use this code:

#ifdef MSVC
#define hypot _hypot
#endif
...
d = hypot(x2 - x1, y2 - y1);

Some CPUs may implement hypot as an instruction which would be way faster then the 6 or so instructions of the pre-mentioned method.

Paul whoknows
Quote:

Paul,
are you talking about the d = sqrt(((x2-x1)^2) + ((y2-y1)^2)) formula?

No no, I meant the secant line between 2 points

{"name":"96215157b42adf1a03b4da860ca80770.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/e\/de5da42bd94caec2d100fcc40dcfb8ef.png","w":261,"h":39,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/e\/de5da42bd94caec2d100fcc40dcfb8ef"}96215157b42adf1a03b4da860ca80770.png

Thread #588108. Printed from Allegro.cc