A Space Rocks Issue -- incorrect bullet angle

jbutler27

Member
I'm using GML on GameMaker Studio 2 IDE v2.3.0.529

I apologize if this issue has been discussed elsewhere, but after prowling forums and Google and YouTube, I still cannot find a satisfactory answer to explain why the bullets will not shoot straight out of the end of my ship while it's in motion. For reference, I'm following along with FriendlyCosmonaut's GML Space Rocks tutorial on YouTube. I've been playing around with GML for several hours a day, every day, for the last three weeks (switched over from DnD after I got a better grasp of coding logic). I realize there are concepts that are still way over my head, but I'm open to learning and experimenting.

Anyway. When the game starts, if I rotate in place while shooting, my ship fires bullets fine; the angle matches the angle of the ship exactly, and you wouldn't notice anything more than the slight listing which occurs when the ship is in full rotation, due to centrifugal force.

The problem asserts itself when the ship has some momentum. There doesn't seem to be any apparent pattern to the angle error, either: sometimes the bullet angle slips ~10-20 degrees to the right or left of the ship's nose, and other times the angle is significantly more dramatic, causing the bullet to discharge 90 degrees or more off center. If I test long enough, I'll notice the bullets (while the ship is in motion), begin to move in a stuttered, cc/clockwise manner, as if each subsequent shot is attempting to realign with the ship's nose (but it won't, so long as the ship is in motion). And if I can manage to slow the ship down and come to a dead stop, the firing angle returns to the desired norm.

I've researched the issue of bullets, shooting, image_angle, direction, "with" statements, etc., from nearly every obvious source I could get my hands on--and while the advice I found was useful in its own right, none of the applied "fixes" made much, if any, difference at all to my problem. (The main solution, I've found, requires the interpolation of image_angle/direction variables into the instance creation, but those did nothing except break the firing further.) I've tried scrapping the script and using an internal event instead; firing a differently named bullet at the same time, with only a speed property, and it whizzed off in a completely different direction than the regular bullet; using different variables and functions (such as locking the mouse in place to act as a reticle, or using lengthdir_x/y and lerp) all to no avail. I diddled around with the code for 8 hours yesterday, and ended up right where I started.

Frustrated, I looked back at all the tutorial videos I'd been watching so I could troubleshoot from the ground up.

That's when I noticed something I hadn't noticed before: From go, the bullets aren't shooting straight out of the nose of the ship. There isn't a whole lot of a footage of her flying through space and shooting, but of the footage available, it's apparent that there is an angle issue included in her code as well. (Absolutely no disrespect meant -- FC has been an enormous help to me, and I would be completely clueless without her instruction to get me going and to broaden my understanding.) I don't know whether this is a limitation of the GameMaker engine, but it seems unlikely (but what do I know?) or if it's purely a failure of the user to implement a viable solution.

### In the obj_ship Step event:

if(keyboard_check_pressed(vk_space)){
create_bullet(image_angle, bulletSpd, faction, id);
}

### In the create_bullet script:

function create_bullet(_dir,_spd,_fac,_creator){

var inst = instance_create_layer(x,y, "Instances", obj_bullet);
audio_play_sound(snd_zap, 1, false);

with(inst)
{
direction = _dir;
speed = _spd;
faction = _fac;
creator = _creator;
}
}

Everything works fine; this isn't a script or coding issue. It's just that the bullet, when the ship is in motion, is somehow discharged at an angle that is independent of the ship's angle. I've included some screenshots to help illustrate the problem.

2020-10-18 (1).png 2020-10-18 (7).png 2020-10-18 (9).png

Thank you for taking the time to read this. Any help at all would be greatly appreciated!
 

Nidoking

Member
What are the chances that the ship is changing direction or image_angle (probably both) in the same step that you're shooting the bullet? Or that something in the ship's movement is causing the direction or image_angle to change? You might consider using the debugger, putting a breakpoint in the shot portion of the event, and seeing what the variables are compared to what you feel they should be.
 

TheouAegis

Member
You create the bullet at (x,y). Your ship's direction is different than its image_angle, so the bullet is firing right, but it is coming out the sides because the ship moved that way. If you set the bullet to spawn at something like x+lengthdir_x(8,_dir)) and y+lengthdir_y(8,_dir), the issue should "go away".
 

jbutler27

Member
I ran the breakpoint, and took a look at the output. From the looks of it, the bullet is having trouble assigning a creator id. I'm not sure if that matters as much as a new discovery. To test out the turning/direction idea you mentioned, @Nidoking, I turned off the asteroids and enemies, then zoomed through the open room, spun in a circle, and fired shots as fast as I could. Oddly enough, it appears as if the bullets are traveling along trajectories correlative more to a three-dimensional, cone-shaped space (positioned birds-eye over the ship, point down) rather than along simple 2-dimensional planes. I know that sounds super strange, but it's the only way I can explain the phenomena. When moving strictly up or down, with no sideways movement, the 90 and 270 angles behave typically. But for every angle between these, the bullets' behavior do not appear to conform to the conventional laws of two-dimensional physics.

Here's a link to the video:
 

FrostyCat

Redemption Seeker
The shooting angles actually look correct to me. It's just that because of the time it takes to get from the middle of the sprite to the outer tip's radius, if you are continuously moving or rotating, the bullet will not line up with the tip. If you want to start the bullet at the tip, pre-calculate that position using lengthdir functions.
GML:
function create_bullet(_dir,_spd,_fac,_creator) {
    var tipRadius = _creator.sprite_width/2; //Adjustable, this is only a starter
    var inst = instance_create_layer(x+lengthdir_x(tipRadius, _dir), y+lengthdir_y(tipRadius, _dir), "Instances", obj_bullet);
    ...
}
 

jbutler27

Member
You create the bullet at (x,y). Your ship's direction is different than its image_angle, so the bullet is firing right, but it is coming out the sides because the ship moved that way. If you set the bullet to spawn at something like x+lengthdir_x(8,_dir)) and y+lengthdir_y(8,_dir), the issue should "go away".
I tried interpolating this way, and I got the exact same result. I can't help but feel that there must be some setting I'm not seeing.
 

jbutler27

Member
The shooting angles actually look correct to me. It's just that because of the time it takes to get from the middle of the sprite to the outer tip's radius, if you are continuously moving or rotating, the bullet will not line up with the tip. If you want to start the bullet at the tip, pre-calculate that position using lengthdir functions.
GML:
function create_bullet(_dir,_spd,_fac,_creator) {
    var tipRadius = _creator.sprite_width/2; //Adjustable, this is only a starter
    var inst = instance_create_layer(x+lengthdir_x(tipRadius, _dir), y+lengthdir_y(tipRadius, _dir), "Instances", obj_bullet);
    ...
}
That's a nifty fix! Thanks for the advice. It does indeed /look/ nicer that way, but it makes me wonder something. If the movement of the ship is correctly offsetting the angle of the bullet (as seems appropriate to a moving object), is there some formula that would match the velocity of new bullets to the velocity of the ship? In Newtonian physics these objects would--assuming the bullets are "resting" on board the ship--share a relative velocity. Perhaps there is a way to "store" the bullets on the ship so they can adopt its speed/velocity before being discharged? I can see how this could cause excessive bullet speed issues, but I figure it can't hurt to ask some more knowledgeable members.

Maybe this sounds like nitpicking, but I'm just genuinely curious what the GameMaker engine is capable of accomplishing.
 
Top