Reputation: 13
I'm making a simple game which is meant to use the computer's mouse to control an object within it, and I'm having difficulty with getting it to function as I'd like. The object (labelled 'fist' in this instance) is meant to follow the mouse's position on the screen until a certain constant ('reach'), where it will then continue to follow the mouse, but only then within the bounds of the maximum reach. Basically the guy's hand follows your mouse to a point but won't rip off from his shoulder if your mouse goes too far away. The code that I have so far for the function is this:
void FistPosition(int& player_x,int& player_y, int& fist_x, int& fist_y){ //Start
ALLEGRO_MOUSE_STATE mousepos;
al_get_mouse_state(&mousepos); //Get the mouse's x and y position
const int REACH = 150; //Define the maximum distance the fist can go.
int playerc_x = player_x + 62; //Define the x and y center of the player object
int playerc_y = player_y + 92;
double x_dist = abs(playerc_x - mousepos.x); //get the x and y distance between
double y_dist = abs(playerc_y - mousepos.y); //body and mouse
int mousedist = sqrt((x_dist * x_dist) + (y_dist * y_dist)); //define mouse distance
if (mousedist < REACH){ //If within bounds of reach, follow the mouse position exactly
fist_x = mousepos.x;
fist_y = mousepos.y;
}
else{
fist_x = mousepos.x - (mousepos.x - fist_x); //Otherwise it cannot leave the
fist_y = mousepos.y - (mousepos.y - fist_y); //maximum reach
}
return;
}
The main problem that I'm having right now is that as the character moves through the level, the hand stays behind and gets locked in place when the player goes too far away. I'd also like the fist object to keep moving after the distance hits REACH, but to stay within the defined distance 'circle' following the relative mouse position, but I'm having a hard time creating the logic for that in my head. Any help you more experienced guys can give is very much appreciated!
Upvotes: 1
Views: 611
Reputation: 4409
void FistPosition(int& player_x,int& player_y, int& fist_x, int& fist_y){ //Start
ALLEGRO_MOUSE_STATE mousepos;
al_get_mouse_state(&mousepos); //Get the mouse's x and y position
const int REACH = 150; //Define the maximum distance the fist can go.
int playerc_x = player_x + 62; //Define the x and y center of the player object
int playerc_y = player_y + 92;
double x_dist = mousepos.x - playerc_x; //get the x and y distance between
double y_dist = mousepos.y - playerc_y; //body and mouse
int mousedist = sqrt((x_dist * x_dist) + (y_dist * y_dist)); //define mouse distance
if (mousedist < REACH){ //If within bounds of reach, follow the mouse position exactly
fist_x = mousepos.x;
fist_y = mousepos.y;
}
else{
double angle = atan2(y_dist/xdist); //work out the angle to the mouse
fist_x = playerc_x + REACH*cos(angle);
fist_x = playerc_y + REACH*sin(angle);
}
return;
}
I have made a couple of changes:
abs()
function and changed the order of terms in x_dist
and y_dist
assignments. The absolute value wasn't needed (x*x
is always positive) and it now represents distance and direction (+x is to the right etc).fist
at maximum reachIn detail:
2: atan2
unlike the standard atan
function returns an angle that represents the sector the inputs describe. This allows us to use angles like '135 degees' instead of having to work out where the angle is (2nd sector clockwise from origin) and add 90 degrees for each sector.
3: Just calculating position at radius = REACH
using sin and cos
Using these the fist
should keep moving.
It didn't before as with:
fist_x = mousepos.x - (mousepos.x - fist_x);
fist_y = mousepos.y - (mousepos.y - fist_y);
the mousepos
terms cancel out so it is really just:
//this line: mousepos.x - (mousepos.x - fist_x);
//is the same as: mousepos.x - mousepos.x + fist_x;
fist_x = fist_x;
fist_y = fist_y;
Upvotes: 1
Reputation: 2182
It's probably better to think in polar coordinates. Compare the mouse position with the shoulder position to get a desired angle and radius. Clamp the radius to REACH, then convert back to rectangular coordinates.
Upvotes: 0