đ Leçon IntermĂ©diaire : Mouvement PNJ avec pause et animation
Niveau : IntermĂ©diaire â CatĂ©gorie : âDĂ©placements guidĂ©sâ
On ajoute du réalisme : animations + pause avecawait
eten_pause
đđïž
đ± Objectif
Faire en sorte quâun PNJ marche entre deux points :
- đŁ En jouant une animation
walk
- đ Puis sâarrĂȘte 3 secondes avec une animation
idle
- Et reparte dans lâautre sens, en boucle !
𧰠Pré-requis
Tu dois déjà avoir :
- Un PNJ dans ta scĂšne (ex:
Fermier.tscn
) - Deux
Node2D
(PointA
etPointB
) dans la scĂšne principale (PAS dans le PNJ !) - Un
AnimatedSprite2D
avec au moins 4 animations :walk_right
,walk_left
,idle_right
,idle_left
đĄ Concepts nouveaux Ă comprendre
đ§ 1. await
et les fonctions asynchrones
Quand tu utilises await
, tu dois ĂȘtre dans une fonction asynchrone, câest-Ă -dire qui accepte lâattente sans bloquer le reste du moteur.
đ await
ne fonctionne pas bien dans _physics_process()
, car cette fonction est appelée à chaque frame.
â
Solution : on crée une fonction séparée (attendre_et_changer
) dans laquelle on utilise await
.
đ§ 2. Le piĂšge du mouvement pendant lâattente
Si tu ne bloques pas le mouvement du PNJ manuellement, il va continuer de bouger mĂȘme pendant lâattente. đŹ
â
Solution : on utilise une variable en_pause
pour désactiver le mouvement tant que la pause est active.
đ§âđ» Script complet avec commentaires et emojis âš
extends CharacterBody2D
@export var point_a: Node2D
@export var point_b: Node2D
@export var speed := 40.0
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
var direction
var en_pause: bool = false
var current_target_node: Node2D
func _ready():
current_target_node = point_a
func _physics_process(delta):
if en_pause or current_target_node == null:
velocity = Vector2.ZERO
return
var target_pos = current_target_node.global_position
direction = (target_pos - global_position).normalized()
velocity = direction * speed
move_and_slide()
if global_position.distance_to(target_pos) < 2.0:
en_pause = true
await attendre_et_changer()
animation()
func animation():
if direction.x > 0:
animated_sprite_2d.play("walk_right")
elif direction.x < 0:
animated_sprite_2d.play("walk_left")
func attendre_et_changer() -> void:
if direction.x > 0:
animated_sprite_2d.play("idle_right")
else:
animated_sprite_2d.play("idle_left")
await get_tree().create_timer(3.0).timeout
if current_target_node == point_a:
current_target_node = point_b
else:
current_target_node = point_a
en_pause = false
đ§Ș Astuces et piĂšges Ă Ă©viter
- Ne jamais mettre
await
dans_physics_process()
â toujours crĂ©er une fonction dĂ©diĂ©e - Nâoublie pas de tester dans la scĂšne principale ! Sinon,
PointA
ouPointB
vaudrontnull
- Tu peux ajuster la distance de déclenchement (ici
2.0
) pour quâil ne sâarrĂȘte pas trop tĂŽt
đ Bonus sonore : ajouter un bruit de pas
đ Pourquoi un son de pas ?
Tu veux que ton personnage ne glisse pas en silence, mais laisse entendre ses pas dans lâherbe ou sur les cailloux ? VoilĂ comment ajouter un son rĂ©aliste đŸđż
đ§ Ătape 1 â RĂ©cupĂ©rer un son
Télécharge un son libre sur :
đ https://pixabay.com/sound-effects/
Cherche : grass footsteps
, walk
, step
, etc.
Dépose-le dans ton projet :
assets/audio/footstep_grass.wav
đ§© Ătape 2 â Ajouter un AudioStreamPlayer2D
- Dans ton PNJ, ajoute un enfant :
AudioStreamPlayer2D
- Dans lâinspecteur :
- Associe ton fichier son Ă
Stream
- Ne coche
Loop
que si le son est trĂšs court â - Sinon, il se relance manuellement
- Associe ton fichier son Ă
Tu peux le nommer footstep_pnj
âïž Ătape 3 â Lancer et arrĂȘter le son dans le script
@onready var footstep_pnj = $AudioStreamPlayer2D
func _physics_process(delta):
if en_pause:
velocity = Vector2.ZERO
footstep_pnj.stop() # â Stop quand en pause
return
# ...
move_and_slide()
if not footstep_pnj.playing:
footstep_pnj.play()
đĄ Astuces sonores
- Si ton son est dĂ©jĂ complet (genre 1â2 secondes), pas besoin de loop
- Tu peux jouer le son toutes les 0.3â0.5 sec avec un
Timer
- Pour aller plus loin : changer le son selon le sol (herbe, pierre, plancherâŠ)
đ Et voilĂ ! Tu entends ton personnage marcher đŸ
Tu veux quâon ajoute un bruit diffĂ©rent selon les tuiles ou des effets mĂ©tĂ©o aprĂšs ? đ§ïžđ”