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:
ColorRectto serve as the player sprite
Camera2Dto follow the player around as they moved
Crosshairsnode, which is a simple
Spritechild 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_positionof 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 the
global_positioncoordinate from step 1
- Note: subtracting two coordinates gives you the Vector or Line between them
- Using the
Vector2from the previous step, I can easily get the angle between the two coordinates.
- Note: I add the
camera.rotationto 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
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
Inputclass to see if the “rot_left” action I defined was triggered. For this example, pressing “Q” fires the
rot_leftand pressing “E” fires the
rot_right. They are defined in my project settings.
- I rotate the camera by 10 degress every time the
rot_left) action is pressed
- I also want to make sure I apply a rotation to the crosshairs
- My custom
move_crosshairs_to_anglefunction 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
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.
Background image from the example is from OpenGameArt