• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED Make bullet orbit around the moving player

For context, it's a bullet hell game. So what I'm trying to achieve is have four bullets orbit around the player at all times until a timer hits 0, in which they will spring back and then shoot straight at the player.

The code I have now works for orbiting the player, but as soon as the player moves (the player's position changes), the orbiting gets thrown off.

GML:
//initially set spawn points, so that each bullet is in a different starting position (N S E W)
if spawn{
    x = player.x + new_x; //new x, new_y controlled in object creation code, they're either -40, 0, or 40
    y = player.y + new_y; //new x, new_y controlled in object creation code, they're either -40, 0, or 40
    spawn = false; //the bullets have been spawned, don't reset them
}
else{
    //distance from focal point
    radius = 40;

    phase = point_direction(player.x, player.y, x, y);

    //speed of orbit
    phase += 2;

    //orbit the player
    x = player.x + radius * dcos(phase);
    y = player.y - radius * dsin(phase);
}

//always point toward the player
image_angle = point_direction(x,y,player.x,player.y);
I'm not sure why the orbiting messes up once the player moves... I also don't know how to go about having the bullets "spring back" and then shoot at the player. I'm not great with sin and cosin.
 

Slyddar

Member
Use a state machine for the bullets, so you can control which state they are in. Will make life easier. Use lengthdir_x/y to eliminate your dislike for sin and cosin. Lengthdir_x/y can also be used for the springback state.
 
Use a state machine for the bullets, so you can control which state they are in. Will make life easier. Use lengthdir_x/y to eliminate your dislike for sin and cosin. Lengthdir_x/y can also be used for the springback state.
That still doesn't explain why the orbit messes up once the player's position changes.
I did manage to get the spring back working, however when I try to get them to then shoot at the player, they refuse to move.
I tried using move_towards_point, didn't work. Tried direction and speed. Didn't work. They refuse to budge from their spring back state.

Step event:
GML:
else if event && counter <= 4{
    counter += 1;
    if counter < 4{
        if x < player.x{
            x -= spring/2; //spring is 10
        }
        if x > player.x{
            x += spring/2;
        }
        if y < player.y{
            y -= spring/2;
        }
        if y > player.y{
            y += spring/2;
        }
        if alarm[0] == -1{
        alarm_set(0,room_speed*.5);
        }
    }
    else{
        stop_rot = true;
    }
}

if !stop_rot{
//always point toward the player
image_angle = point_direction(x,y,player.x,player.y);
}
Alarm 0:
GML:
speed = 4;
direction = point_direction(x,y,player.x,player.y);
show_debug_message("worked");
show_debug_message(speed);
I know the alarm is working because the debug messages are showing accordingly. But the bullets refuse to move.

Regular circling:

1596486193628.png

Spring back:

1596486172149.png

UPDATE: Checked my room properties. Physics world was on. However, the objects themselves aren't physics objects... turning this off fixed the second problem.
 
Last edited:
Found a much easier way of doing this that actually works!

Create:
GML:
trg = obj_player_battle;
spd = 3 //speed of orbit;
lng = 30; //size of orbit, distance from central point
Step:
GML:
x = trg.x + lengthdir_x(lng,plc);
y = trg.y + lengthdir_y(lng,plc);
plc += spd;
You set plc in each bullet's creation code. I set mine as follows: 0, 90, 180, 270 so that they orbit equal distances apart.
 
Top