While on the Godot Engine Facebook page, I saw another request asking for some assistance with a 2D shooter game.
This one felt like it may be simple, so I gave it a try. It seemed like the Camera2D
would be a child of the player Node2D
, and the crosshair may be another Node2D
, but maybe a child of the Camera2D
, so that if the Camera2D
rotates, the crosshair rotates with it. After some experimentation, this did not work as expected.
In the end, my scene tree looked like this for the player node:
- A
ColorRect
to serve as the player sprite - A
Camera2D
to follow the player around as they moved - A
Crosshairs
node, which is a simpleNode2D
with aSprite
child node so we can see the crosshair
The scripting was the harder part, and it took a lot of trial and error to figure out a solution that worked.To be honest, it made me feel stupid.
First things first, we need to track the mouse movement, so I used the built-in _input
function, which is called whenever there is input from the user (keyboard press, mouse click, mouse move, tap gesture, etc).
- I get the
global_position
of the Player node, which is the x,y coordinate of the player in the scene. - I grab the mouse scene coordinates (
event.global_position
) and subtract it from theglobal_position
coordinate from step 1- Note: subtracting two coordinates gives you the Vector or Line between them
- Using the
Vector2
from the previous step, I can easily get the angle between the two coordinates.- Note: I add the
camera.rotation
to the angle so that I can properly keep track of where the mouse is, in relation to the center of the player. If I did not account for the camera rotation, the angle between the mouse position and the center of the player would be wrong! When rotating the camera, that has not effect on the coordinates of where the mouse is on the screen.
- Note: I add the
- I call my custom function to move the crosshairs to match the given angle (see below)
Great, so now as I move my mouse around, the crosshairs follows:
Now I need to rotate the camera when I press the Q
or E
keys. That should be simple enough. It’s best to track long presses of keys in the built-in _process
function, which is called once per frame.
- I use the built-in
Input
class to see if the “rot_left” action I defined was triggered. For this example, pressing “Q” fires therot_left
and pressing “E” fires therot_right
. They are defined in my project settings. - I rotate the camera by 10 degress every time the
rot_right
(orrot_left
) action is pressed - I also want to make sure I apply a rotation to the crosshairs
- My custom
move_crosshairs_to_angle
function I will show below
It’s a fairly simple calculation to take the incoming angle (in radians) and convert it to an x,y coordinate. I wanted the crosshair to appear to rotate around the player in a circle shape that has a radius of 100pixels. So, to convert an angle to an x,y coordinate on a 100-pixel radius circle, you simple use sin
and cos
on the angle, and multilply it by the radius of the circle!
You will also see that I’m still puzzled over that magical “75 pixels” I have to add to the x-coordinate. I still don’t know why this is the case, but it’s an approximation to get the crosshair rotating around the center of the player. If you can figure it out, please drop me a line. I will leave a link to the project files below.
Final result:
Download the Godot project files located here
Background image from the example is from OpenGameArt