Godot Version
4.2
Question
hey Godot fam, I’m working on a 2d bullet hell project, hopefully the first I finish and share, and I was wondering if someone could help me understand why the solution to a problem I had worked.
func spawn_bullets():
for i in bullet_count:
var arc = 270
var b1 = bullet_scene.instantiate()
b1.position = self.position
b1.rotation = rotation + deg_to_rad(randf_range(0,arc))
b1.dir = Vector2(1,0).rotated(b1.rotation - deg_to_rad(arc/6))
My goal was to have an enemy shoot bullets in an arc based of the direction the sprite was facing. It’s a 270 degree arc, with a “blind spot” of no bullet directly to its rear. I got my code working and had it shooting with the blind spot in all sorts of directions but I couldn’t get the correct facing until I divided it by arc by 6 in the last line.
My first thought was that modifying b1.rotation by arc/2 would lead to it rotating the distance required but that was pretty far off. After experimenting with positive and negative values, negative 6 got the desired effect. I’m hoping this formula works with any value for arc however, I may have just gotten close enough for it to work.
I’m sure you can tell but I’m only a couple months into programing and it’s been years since I studied math but it’s been a lot of fun experience learning all these new skills.
I’ve attached of a visual of the arc I thought I was trying to make. Top image is what I visualized as an arc from 0-270 degrees, then bottom image was the arc after being rotated to face forward. The hashed out area is the blind spot.
Thanks for any input!
Not sure what b1.dir
is supposed to be, assuming it’s the direction the bullet travels I belive you want to rotate by it’s rotation, since you’ve already applied the arc to it.
b1.dir = Vector2.RIGHT.rotated(b1.rotation)
Depends on where “forward” is too, are your bullet sprites facing DOWN, RIGHT, LEFT, or UP? punch that into the equation.
1 Like
B.dir is a variable in the bullet script. It should be Vector2(1,0) but now that I look at the above code again I’m setting it to be that again so I’ll fix that later, thanks for flagging.
b1.dir = Vector2(1,0).rotated(b1.rotation - deg_to_rad(arc/6))
This code rotates the arc to where I want it to be, I guess my question is why? The deg2rad portion of that line is rotating my arc to where I want it to be but I’m confused as to why the magic number was 6.
I believe all my orientations start looking towards the right.
Sorry if this is confusing or it’s not explained correctly.
you end up rotating it about 45° counter-clockwise, what do you mean it rotates the arc? your variable arc
is always equal to 270
so one sixth of that is 45
. You are rotating a RIGHT vector by a value. I think your bullet sprite is diagonal? could you post that bullet asset? The angle you want to rotate it is dependant on the orientation of the image.
1 Like
Hey Gert,
here’s the code with a screen shot of an enemy shooting in the desired arc.
My goal with the spawn_bullet function on enemy was to be able to change the size of the arc while always having the center of which pointing in the direction it faces. I did a test and as is if I change the value of arc, it does not stay centered (straight down). So i guess my question is how do make that function always point straight down, regardless of the size of arc?
Here’s the code for my enemy:
#extends Node2D
@export var speed = 25
@onready var bullet_cd = .5
@onready var bullet_count = 5
var bullet_scene = preload("res://scenes/bullet.tscn")
@onready var player := get_parent().get_parent().get_node("Player")
func _ready():
get_parent().get_node("Player")
#screen entry
var tween = get_tree().create_tween()
var target = Vector2(self.position.x, self.position.y + 150)
tween.tween_property(self, "position", target, .5).set_trans(tween.TRANS_QUINT)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
#rotate(5 * delta)
position.y += (speed * randf_range(.9,3.5) * delta)
func spawn_bullets():
for i in bullet_count:
var arc = 270
var b1 = bullet_scene.instantiate()
b1.position = self.position
b1.rotation = rotation + deg_to_rad(randf_range(0,arc))
b1.dir = b1.dir.rotated(b1.rotation - deg_to_rad(arc/6))
func _on_visible_on_screen_notifier_2d_screen_exited():
queue_free()
func _on_visible_on_screen_notifier_2d_screen_entered():
bullet_cd += (randf_range(-.1,.5))
$Timer.set_wait_time(bullet_cd)
$Timer.start()
print("bullet CD", bullet_cd)
func _on_timer_timeout():
spawn_bullets() >
And code from my bullet:
extends Node2D
class_name Bullet
@onready var bullet_sfx = $AudioStreamPlayer2D
@export var b_speed := 400
@export var max_collisions := 6
@export var damage := 10.0
var dir = Vector2(1,0)
var collision_count := 0
#func _ready():
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
self.position += dir * b_speed * delta
below is a screen shot of the bullets coming how I want them too with arc = 270.
