Enemy bullet at player

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Halfpixel

Hello,
I’m working on a 2d platformer and I’m trying shoot from my enemy bullet at my player.
Enemy could be on top of player like a laser on ceiling or on ground (same y-axis as player)
I’m having trouble with:
a) Understanding how to access player position from the bullet scene.
(I have a player scene, enemy scene, bullet scene and main/level 1 scene)
b) how to shoot bullet at player without bullet following player (ceiling enemy)
c) how to shoot bullet at player with chasing bullet

(Bullet scene)
extends Area2D

var speed = 150
var velocity = Vector2()
var target = Vector2()

onready var player = preload(“res://Scenes/Player.tscn”)

func _ready():
pass

func _physics_process(delta):

position = global_position (commented out)

target = player.position (commented out)

velocity = position.direction_to(target) * speed
translate(velocity*delta)

func _on_VisibilityNotifier2D_screen_exited():
queue_free()

func _on_Redlaser_body_entered(body):
queue_free()

just saying if you select all the code then press “ctrl + k” it makes it easer to read
when dealing with position from different nodes you should use global_position

lewis glasgow | 2021-12-30 10:54

:bust_in_silhouette: Reply From: aengus126

Let’s start with question a. Your code shows that you have a variable for the player scene. That’s logical, however, that preloaded scene is different from the player scene that’s actually instanced into the world. In order to get a reference to the correct player scene, you should use get_node(). If your bullet scene is a child of the world, and the player is also a child of the world, then from the bullet you can write get_parent.get_node(player scene path). Once you have the player scene, you can find it’s position, which I assume you know how to do.

B). To get the bullet to shoot at the player, use the look_at(position) method, which rotates the bullet towards the given position. Then in physics process, move the bullet normally, except rotate the speed vector2 with .rotated(the bullets rotation).

C). If you want the bullet to move towards the player continuously then just keep calling the look_at() method in physics process.

Sorry this answer is kind of bad if you need me to help further tell me and I can when I get to my desktop.

Thank you.
I have a main scene and I’m instancing the player scene and the enemy scene into this scene, would (get parent) still work? I’m guessing no but please correct me if I’m mistaken.
For the bullet explanation, a further explanation would be appreciated.
Edited…

Halfpixel | 2021-12-30 20:06

Yes. get_parent() is what I was talking about, it will reference the bullet’s parent, in this case the world, and then you use .get_node() on the world reference to get a reference to the the player. Once you have a reference to the player, you can access it’s properties, for example, it’s position.

when you call look_at() method, it does some alien magic code that makes the node rotate so that is is pointing towards the desired location (depending on how the node is rotated before .rotated() is called, the rotated result could appear lopsided because I believe .rotated() tries to get the positive x coordinate to point in the desired location [long story short if it’s rotated incorrectly then just rotate it in the editor]). Once the bullet is pointing towards the the player, we just need it to move in the direction that it is pointing. In your code, all you have to do is velocity = velocity.rotated(rotation) before you call the translate method. Basically, what it does is more alien magic code that rotates the velocity vector2 itself so that it will make the bullet move in the direction that it’s pointed in.

That would result in the bullet going linear and not changing path based on the players changing position. If you wanted to make the bullet follow the player, you would have to make it constantly update the bullet’s rotation so that it’s always pointing at the player, and therefore because of the rest of the code it would also be following the player. All you have to do to do that is take the look_at() method out of the ready() function and move it into the physics_process().

I speak on behalf of the community when I say that I thank you for using Godot and asking questions. It 1) grows the community 2) Makes YOU a smarter person 3) now when somebody runs into the same problem as you in a couple years from now, they might google this and find it as an answer, and it would make their day.

If you have any more questions, just ask (but google them if you can, first.)

aengus126 | 2021-12-31 03:27

thank you for your detailed answer.

Halfpixel | 2021-12-31 13:02