3
votes

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

Correct

Incorrect

IncorrectIncorrect

2
What is your question?Jacob Lambert
Sorry, my brain checked out after I finished that much. I'm about to add picturesterpak
0,0 the center of the character and 30,28 would be the end of the gun barrel, correct?Jacob Lambert
Yes, the sprite faces right at 0 degres by default and from that position, it is 30,28. Technically 30,-28 but y increases downwardsterpak

2 Answers

6
votes

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;
0
votes

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.