问题
I'm making a top-down shooter and the player's gun is offset from the coordinates of the object. I'm using GameMaker:Studio, so the x and y coords are the center of the object. The offset of the image is set here:
bullet_offset_x = 30;
bullet_offset_y = 28;
And here is the code for shooting the gun:
var xpos = x + (bullet_offset_x * cos(degtorad(direction))) - (bullet_offset_y * sin(degtorad(direction)));
var ypos = y + (bullet_offset_x * sin(degtorad(direction))) + (bullet_offset_y * cos(degtorad(direction)));
var flash = instance_create(xpos, ypos, obj_flash);
with (flash){
direction = other.direction;
image_angle = other.direction;
}
I'm using the following formula for placing the muzzle flash:
x' = xcos(angle) - ysin(angle)
y' = xsin(angle) + ycos(angle)
Therefore:
xpos = x + x' and ypos = x + y'
However, when I run the code, the muzzle flash is correctly positioned when the angle is 0/360, but is off otherwise. Am I calculating this wrong?
IMAGES:
Correct
Incorrect
回答1:
You need to use lengthdir_x
and lengthdir_y
functions, like:
var xpos = x + lengthdir_x(offset_distance, offset_angle + image_angle); // or direction
var ypos = y + lengthdir_y(offset_distance, offset_angle + image_angle);
var flash = instance_create(xpos, ypos, obj_flash);
flash.direction = direction;
flash.image_angle = direction;
little example here
To calculate the values to be substituted into the formula, you can use this program. Originally it was made in Russian, but I have translated it into English. My English is terrible, but I hope you will be able to understand it.
upd: Example with offsets:
var delta_x = 60;
var delta_y = -70;
var angle = point_direction(0, 0, delta_x, delta_y);
var distance = point_distance(0, 0, delta_x, delta_y);
var xpos = x + lengthdir_x(distance, image_angle + angle);
var ypos = y + lengthdir_y(distance, image_angle + angle);
var obj = instance_create(xpos, ypos, obj_flash);
obj.image_angle = image_angle;
回答2:
When your sprite has an angle of 0, your muzzle flash still at an angle of invtan(28/30)
in relation to the sprite. Therefore, the angle that the flash must be placed at in relation to the rotation of the sprite can be given by
flashRotation = spriteRotationDegrees - invtan(28/30) \\you can change this to radians
Once that is found, the positions can be found by:
var x_pos = sprite_x_pos + Math.Sqrt(28^2 + 30^2)cos(flashRotation);
var y_pos = sprite_y_pos + Math.Sqrt(28^2 + 30^2)sin(flashRotation);
The actual angle of rotation of the flash (which way it points) will be the same angle as the sprite. You may need to play with the flashRotaion equation depending upon which way is counted as a positive rotation.
来源:https://stackoverflow.com/questions/26308138/spawn-bullet-at-barrel-of-gun