View on GitHub

Journal de développement - Mon RPG Zelda

Suivi du développement de mon jeu de type Zelda avec Godot Engine

🎓 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 avec await et en_pause đŸ›‘đŸŽžïž


đŸŒ± Objectif

Faire en sorte qu’un PNJ marche entre deux points :


🧰 PrĂ©-requis

Tu dois déjà avoir :


💡 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


🌟 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

  1. Dans ton PNJ, ajoute un enfant : AudioStreamPlayer2D
  2. Dans l’inspecteur :
    • Associe ton fichier son Ă  Stream
    • Ne coche Loop que si le son est trĂšs court ⛔
    • Sinon, il se relance manuellement

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


🌈 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 ? đŸŒ§ïžđŸŽ”