Evan_Sherlock
Evan_Sherlock

Reputation: 13

Allegro and C++ - Difficulty with mouse position logic

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

Answers (2)

Baldrickk
Baldrickk

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:

  1. removed the 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).
  2. added calculation of the angle to the mouse
  3. calculated position of the fist at maximum reach

In 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

Adrian May
Adrian May

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

Related Questions