Question
I am new to gamedev, and am starting with a simple game in Godot. I do not have a problem with my code yet, but I am asking a general question about how you would structure this code, so that I can get used to the programming paradigms in Godot and common practices in gamedev in general.
My game:
I am creating a simple game where I am shooting objects from a character toward (eventually) another character. Right now I am working on the code dealing with the logic of spawning this projectile.
Right now, my player has a state machine, which alternates between idle, walking, and shooting. The player state machine is a node in the player scene with multiple children nodes.
Player
- State Machine
- IdleState
- WalkState
- ShootState
The “Shoot” state is entered from either the walk or idle state whenever I click down on the left mouse. While holding down the mouse, this “charges up” the shot, and whenever the left mouse is released, the shoot state is exited. This creates a new projectile instance and then invokes its “fire” method as below:
shoot_state.gd
@onready var shot_projectile: PackedScene = preload("res://shot_projectile.tscn")
var charge_level: int
func exit() → void:
self.player.shot_arrow.visible = false
var shot_type = null # Different types will be implemented later
var rotation: float = self.player.shoot_arrow.rotation
var new_shot = shot_projectile.instantiate()
root_scene.add_child(new_shot)
new_shot.fire(shot_type, self.player.global_position, charge_level)
In the projectile scene, this is how the shot fire is implemented
shot_projectile.gd
func fire(type, position: Vector2, charge_level: int) -> void:
var dest: Vector2 = get_global_mouse_position()
distance_to_target = position.distance_to(dest)
creation_time = Time.get_ticks_msec()
var direction: Vector2 = position.direction_to(dest)
self.visible = true
self.position = position
self.scale *= Vector2(charge_level, charge_level)
velocity = direction * speed
process_mode = Node.PROCESS_MODE_ALWAYS
func _process(delta: float) -> void:
var distance_moved: Vector2 = velocity * delta
self.position += distance_moved
distance_to_target -= distance_moved.length()
if distance_to_target <=0 or Time.get_ticks_msec() - creation_time >= LIVE_TIME:
destroy()
I want to see if there are any obvious ways of doing this better, and I would like to stimulate some conversation about changes I should make in order to make this more tolerant to future feature additions, bug fixing etc. Basically I am just wanting to know how you would make this functionality and why.