3

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

terpak
  • 1,131
  • 3
  • 17
  • 35

2 Answers2

6

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;
Dmi7ry
  • 1,777
  • 1
  • 13
  • 25
0

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.

Jacob Lambert
  • 7,449
  • 8
  • 27
  • 47
  • Now it works around Quadrant 2, but all other quadrants are incorrect. Here's the angle code I used: `var flash_angle = direction - radtodeg(arctan2(bullet_offset_y, bullet_offset_x));` and I then replaced all instances of `direction` with `flash_angle` – terpak Oct 10 '14 at 21:59
  • With, y increasing down, try `flash_angle = direction + radtodeg(arctan2(bullet_offset_y, bullet_offset_x));`. Also, I forgot that if the rotation is between 90 and 270 degrees, you need to add `pi` to the flash_angle. Note, this angle does not give the direction that the flash needs to point, it is only used to get the x and y offsets – Jacob Lambert Oct 10 '14 at 22:27
  • Since flash_angle is in degrees, would that mean add 180 instead? – terpak Oct 10 '14 at 22:37
  • Lol all good. It doesn't seem to be working, but the math all looks right. I'm going to try and calculate a longhand formula myself and see if that works, then use yours to try and simplify it. I feel like it's just a quirk with GameMaker with how they handle direction or movement. – terpak Oct 10 '14 at 23:54