Assets: https://www.kenney.nl/assets/pixel-shmup
A small shooter in Godot 4. The player node extends Area2D, bullets come from their own scene, and the enemy travels on a PathFollow2D.
Player
# Player
extends Area2D
@onready var screen_size = get_viewport_rect().size
var speed = 500
var cooldown_active = false
var cooldown = 0.5
func move(delta):
var input_direction = Input.get_axis("ui_left","ui_right")
var velocity = Vector2() # (0,0)
velocity.x = input_direction
position += speed * delta * velocity
position.x = clamp(position.x, 0, screen_size.x)
func shoot():
if cooldown_active:
return
cooldown_active = true
var cooldown_timer = Timer.new()
cooldown_timer.wait_time = cooldown
cooldown_timer.one_shot = true
add_child(cooldown_timer)
cooldown_timer.timeout.connect(_on_cooldown_timeout)
cooldown_timer.start()
var bullet = Bullet.generate_bullet()
var current_scene = get_tree().get_current_scene()
bullet.position = self.global_position
current_scene.add_child(bullet)
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if Input.is_action_pressed("ui_accept"):
shoot()
move(delta)
func _on_cooldown_timeout():
cooldown_active = false
Bullet
# Bullet
class_name Bullet
extends Area2D
@export var bullet_speed = -800
const BulletScene = preload("res://scenes/bullet.tscn")
static func generate_bullet():
var bullet = BulletScene.instantiate()
return bullet
func move(delta):
var velocity = Vector2.ZERO
velocity.y +=1
position += velocity * bullet_speed * delta
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
move(delta)
PathFollow2D
# PathFollow2D
extends PathFollow2D
var reverse = 1
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
progress_ratio += 0.1 * delta * reverse
if (progress_ratio == 0 or progress_ratio == 1):
reverse = reverse * -1
func _on_enemy_area_area_entered(area):
print("hit")