GameMaker Object Rotation about a point not working as intended

J

Josh Perkey

Guest
I'm creating a game where you control a fisherman and his boat. The boat is controlled with the left stick and the player movement and casting is controlled with the right stick. I'd like my character to be able to move around within the boat while also piloting the boat around the water. I'm having an issue with controlling the relative location of the fisher character inside of the boat. The following code is from my boat object. My approach is to update the relative location of the player within the boat whenever the boat is rotated. The code I have currently is working very strangely in that it's keeping the character within the boat as it is rotated, however, it isn't placing the character at the same exact relative location as I intended. Basically, the character is being rotated to the correct angle so it's in the boat, however if the character is off to the side, he is then rotated to the If you don't mind, please take a look at my code and let me know if you have any ideas of what's going wrong here! Thanks in advance!

key_lstickx = gamepad_axis_value(oFisher.controller, gp_axislh);
key_lsticky = gamepad_axis_value(oFisher.controller, gp_axislv);
if (abs(key_lstickx) || abs(key_lsticky)) var move = true; else move = false;

ldirection = direction; // Last direction
direction = point_direction(0, 0, key_lstickx, key_lsticky); // Direction from left stick for boat control
if (move) {
image_angle = direction - 180;
if (ldirection != direction) { // Check to see if the direction has changed since last frame
r = point_distance(x, y, oFisher.x, oFisher.y);
oFisher.x = x + (r*dcos(image_angle)); // option 2
oFisher.y = y - (r*dsin(image_angle)); // option 2;
}
}

hsp = (key_lstickx * bspeed) - xcurrent;
vsp = (key_lsticky * bspeed) - ycurrent;

x += hsp;
y += vsp;

oFisher.x += hsp;
oFisher.y += vsp;
 

obscene

Member
You forgot a word in your description so not sure what the problem was. Also it helps If you wrap your code in [ code ] tags so its indented.
 
The position of your character should be:

x = boat_x + offset_x * c + offset_y * s;
y = boat_y + offset_x * -s + offset_y * c;

boat_x,y is the position of the boat. offset_x,y is the position of the character relative to the boat (i.e., as if the boat were not rotated and were located at 0,0). s,c is the sine and cosine of the boat's angle. If either offset_x or offset_y is always zero, then you can remove those terms from the calculation.
 
J

Josh Perkey

Guest
The position of your character should be:

x = boat_x + offset_x * c + offset_y * s;
y = boat_y + offset_x * -s + offset_y * c;

boat_x,y is the position of the boat. offset_x,y is the position of the character relative to the boat (i.e., as if the boat were not rotated and were located at 0,0). s,c is the sine and cosine of the boat's angle. If either offset_x or offset_y is always zero, then you can remove those terms from the calculation.
Thanks for the suggestion. I've tried implementing that and it's just snapping my character to the middle of the boat. Here's what it looks like:
My exact code is [
key_lstickx = gamepad_axis_value(oFisher.controller, gp_axislh);
key_lsticky = gamepad_axis_value(oFisher.controller, gp_axislv);
if (abs(key_lstickx) > 0 || abs(key_lsticky) > 0) var move = true; else move = false;

var xoff = oFisher.x - x; var yoff = oFisher.y - y;
var ldirection = direction;
direction = point_direction(0, 0, key_lstickx, key_lsticky);
var c = cos(direction); var s = sin(direction);
if (move) { // Only rotate if receiving controller input
if (direction != ldirection) {
image_angle = direction;
oFisher.x = x + xoff * c + xoff * s;
oFisher.y = y + yoff * -s + yoff * c;
}
}
]

Thanks for your reply and your help so far!
 
J

Josh Perkey

Guest
Can anyone tell me why my original code isn't working?
[
key_lstickx = gamepad_axis_value(oFisher.controller, gp_axislh); // Controller Input
key_lsticky = gamepad_axis_value(oFisher.controller, gp_axislv);
if (abs(key_lstickx) > 0 || abs(key_lsticky) > 0) var move = true; else move = false;

ldirection = direction;
direction = point_direction(0, 0, key_lstickx, key_lsticky);
if (move) { // Only rotate if getting input
image_angle = direction; // Only rotate if angle has changed
if (ldirection != direction) {
r = point_distance(x, y, oFisher.x, oFisher.y);
p0 = point_direction(x, y, oFisher.x, oFisher.y);
p1 = p0 + angle_difference(p0, image_angle);
oFisher.x = x + lengthdir_x(r, p1); oFisher.y = y - lengthdir_y(r, p1);
}
}
]

Here's what it looks like:
Thanks in advance to anyone who can help!
 
Top