Trying to shoot a circle of bullets

And I have made this bit of code to do it:
For some context a Node2D has this code in a script, and $BulletSpawnPoint is a Marker2D that is placed a small distance below the Node2D, and is a child of it.

var new_bullet
for i in 24:
	new_bullet = used_bullet_pool.pop_front()  #used_bullet_pool is an array
	new_bullet.wake($BulletSpawnPoint.global_position, rotation) #places the bullet in the markers position and sets the angle it should move at
	rotation_degrees += 15
	print(i)
	print(rotation_degrees)
	print($BulletSpawnPoint.global_position)

Its shooting a circle of bullets as I wanted, but it isn’t shooting 24 bullets spread every 15 degrees, its shooting 12 bullets spread by 30 degrees instead. Here is the text output from these print statements:

0
15.0000009536743
(626.059, 208.2963)
1
30.0000019073486
(614, 203.3013)
2
45
(603.6447, 195.3553)
3
60.0000038146973
(595.6987, 185)
4
75
(590.7037, 172.9409)
5
90
(589, 160)
6
105
(590.7037, 147.0591)
7
120.000007629395
(595.6987, 135)
8
135
(603.6447, 124.6447)
9
150
(614, 116.6987)
10
165
(626.059, 111.7037)
11
180
(639, 110)
12
195
(651.941, 111.7037)
13
210
(664, 116.6987)
14
225
(674.3553, 124.6447)
15
240.000015258789
(682.3013, 135)
16
255
(687.2963, 147.0591)
17
270
(689, 160)
18
285
(687.2963, 172.9409)
19
300
(682.3013, 185)
20
315
(674.3553, 195.3553)
21
330
(664, 203.3013)
22
345
(651.941, 208.2963)
23
360
(639, 210)

Here’s a picture (ignore the pink bullets in the corner)
12bullets

What’s going on here?

Can you add:

print(rad_to_deg(new_bullet.rotation))

I suspect you are doing a conversion wrong somewhere.

Also 360 divided by 30 is 12, not 15.

You may well have 30 bullets, with a lot of them on top of each other.

1 Like

Sure. I’ve changed the print statements to this

print(i)
print(new_bullet.rotation)  #Not actually changed, but printing as a sanity check
print(new_bullet.move_rotation)

Here’s the output

0
0
0
1
0
0.26179939508438
2
0
0.52359879016876
3
0
0.78539818525314
4
0
1.04719758033752
5
0
1.30899691581726
6
0
1.57079637050629
7
0
1.83259570598602
8
0
2.09439516067505
9
0
2.35619449615479
10
0
2.61799383163452
11
0
2.87979316711426
12
0
3.14159274101257
13
0
3.40339207649231
14
0
3.66519141197205
15
0
3.92699074745178
16
0
4.1887903213501
17
0
4.45058965682983
18
0
4.71238899230957
19
0
4.97418832778931
20
0
5.23598766326904
21
0
5.49778699874878
22
0
5.75958633422852
23
0
6.02138566970825

Also for context the bullets use this logic to move

position += Vector2.UP.rotated(move_rotation) * speed

Sorry, I thought you wanted 30 bullets. My mistake.

1 Like

If you know the number of bullets (24) you want to spawn in the circle, you can do 360/24 and you will have the degrees for each one with no calculation needed, and even better, you can have that 24 in a variable and change it if you are not happy with that number of bullets and you won’t need to change much in the code.

Set the division result in a variable to then use deg_to_rag() to multiply the counter with the degrees to know the rotation you need.

var next_bullet_rotation_in_rads = deg_to_rad(degree_division * i)

Hope these tips can help with the situation.

1 Like

Thanks, that’s definitely the plan for later! Stuff like that will be handy for difficulty modifiers and the like. But for now I just want to understand why the 24 circle is failing. Even though 360/24 = 15, and I’m doing rotation_degrees += 15 accordingly.

I tried getting hit by the bullets and seeing how many bullets I got hit by, but they don’t seem to be overlapping.

Can you put your bullets in array of 24 and print coordinates and angle after spawning all of them?
I’m not sure why its even work with single variable, but i may be wrong.

1 Like

So according to your prints, your rotations are correct and you have 24 angles to rotate to according to your positioning.

What about here, did you mean rotation to be move_rotation? Or maybe move_rotation * i? Is this for initiating the bullet?

new_bullet.wake($BulletSpawnPoint.global_position, rotation)

Your movement then is for the bullets to shout out from the center in these directions. I think we need to see more code. Where is move_rotation being calculated and where is it being used for instance. We definitely need more code.

1 Like

There is a trick you can do with nodes for doing this type of thing.
You can make godot to all the calculations using nodes.
You have your bullet location as one node. The a child is at the center of that node. With a child on that node. The last child is located at distance of 1.0 from the center.

Now with that setup all you need do is rotate the node to find all the spawn and directions. (EDIT the second child)

I use it all the time when doing stuff with my own CPU particles.

1 Like

I think I figured it out, I set it to print the ID of the bullets and I’m getting results like this

0
PinkEnemyBullet:<Sprite2D#52680460585>
1
PinkEnemyBullet:<Sprite2D#52680460585>
2
@Sprite2D@1000:<Sprite2D#52697237802>
3
@Sprite2D@1000:<Sprite2D#52697237802>

And I noticed that in the object pool initialization I was pushing each bullet twice (once when creating it and once in the bullet’s ready function).

Thanks for trying to help everyone

12bullets

3 Likes

Just wanted to quote Godot’s documentation about pop_front() function:

Note: This method shifts every other element’s index back, which may have a noticeable performance cost, especially on larger arrays.

In my experience it’s much cheaper (performance wise) just to iterate through full array instead of changing it (but only if it happens frequently).

2 Likes

Good catch, I should probably be popping from back instead of the front.