Search code examples
rotationgame-maker

Spawn bullet at barrel of gun


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

Incorrect Incorrect


Solution

  • 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;