Hi, I’m using Godot 4.3 and I have one last problem with my shootemup minigame. When I destroy all the enemies in the level, the player controls are supposed to be disabled so I can’t move or shoot, but the controls are still usable when all the enemies are killed.
Here is the link to the video that illustrates the problem.
Here is the player ship code.
extends Area2D
@export var speed: float = 300.0
@export var laser_scene: PackedScene
@export var laser_sound: AudioStream = preload("res://musiqueetson/amiral3000lasersound.wav")
@export var boom_texture: Texture = preload("res://alienminigames/boomtexture.png")
var can_fire: bool = true
var controls_enabled: bool = true # Contrôle local qui conditionne le déplacement et le tir
var initial_y: float = 0.0 # Pour maintenir le joueur sur une ligne fixe
# Gestion des vies
var player_lives: int = 3
var life_sprites: Array = []
# Variables pour gérer l'explosion
var is_exploding: bool = false
var original_texture: Texture # Pour sauvegarder le sprite normal
var original_scale: Vector2 # Pour sauvegarder l'échelle d'origine
func _ready() -> void:
# Pour la compatibilité en Godot 4.3, on peut définir la propriété "pause_mode" via le setter générique
# Mais ici nous allons plutôt désactiver localement le traitement dès que le niveau se termine.
# Par ailleurs, on conserve _ready() tel quel.
set("pause_mode", 1) # On essaie de définir le mode pause pour stopper si la pause globale est activée
initial_y = position.y
if not laser_scene:
laser_scene = preload("res://lasertest.tscn")
var level_scene = get_tree().current_scene
life_sprites = [
level_scene.get_node("vievaisseau1"),
level_scene.get_node("vievaisseau2"),
level_scene.get_node("vievaisseau3")
]
original_texture = $Sprite2D.texture
original_scale = $Sprite2D.scale
connect("area_entered", Callable(self, "_on_area_entered"))
func _physics_process(delta: float) -> void:
# Pour déboguer, on affiche l'état de controls_enabled
# print("Physics process, controls_enabled =", controls_enabled)
if not is_exploding and controls_enabled:
var velocity: Vector2 = Vector2.ZERO
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
if Input.is_action_pressed("ui_right"):
velocity.x += 1
if velocity.length() > 0:
velocity = velocity.normalized() * speed
position.x += velocity.x * delta
position.x = clamp(position.x, 60, 1220)
position.y = initial_y
if Input.is_action_just_pressed("fire") and can_fire and controls_enabled:
fire_laser()
# Sinon, ne traite rien.
func fire_laser() -> void:
var laser_instance = laser_scene.instantiate()
laser_instance.global_position = $Projectile.global_position
get_tree().current_scene.add_child(laser_instance)
laser_instance.add_to_group("player_laser")
can_fire = false
laser_instance.connect("laser_removed", Callable(self, "_on_laser_removed"))
if laser_sound:
$AudioStreamPlayer.stream = laser_sound
print("Lecture du son du laser")
$AudioStreamPlayer.play()
else:
print("Aucun son de laser assigné!")
func _on_laser_removed() -> void:
can_fire = true
func _on_area_entered(area: Area2D) -> void:
if area.is_in_group("enemy_laser"):
if not is_exploding:
take_damage()
area.queue_free()
func take_damage() -> void:
if is_exploding:
return
if player_lives > 0:
player_lives -= 1
life_sprites[player_lives].hide()
print("Joueur touché ! Vies restantes : " + str(player_lives))
start_explosion()
else:
die()
func start_explosion() -> void:
is_exploding = true
$Sprite2D.texture = boom_texture
$Sprite2D.scale = original_scale * 0.7
$ExplosionPlayer.play()
if not $ExplosionPlayer.is_connected("finished", Callable(self, "_on_explosion_finished")):
$ExplosionPlayer.connect("finished", Callable(self, "_on_explosion_finished"))
func _on_explosion_finished() -> void:
if player_lives == 0:
die()
else:
$Sprite2D.texture = original_texture
$Sprite2D.scale = original_scale
is_exploding = false
func die() -> void:
get_tree().call_deferred("change_scene_to_file", "res://gameover.tscn")
# --- Nouvelle version de disable_controls() ---
func disable_controls() -> void:
print("disable_controls() appelée - le vaisseau doit être figé.")
controls_enabled = false
can_fire = false
# Désactiver explicitement le processus de ce node
set_process(false)
set_physics_process(false)
set_process_input(false)
disable_all_lasers()
func disable_all_lasers() -> void:
for laser in get_tree().get_nodes_in_group("player_laser"):
laser.queue_free()
for laser in get_tree().get_nodes_in_group("enemy_laser"):
laser.queue_free()