Outils pour utilisateurs

Outils du site


dindomoteur_creation_du_joueur

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
dindomoteur_creation_du_joueur [2022/03/20 18:17] Simon Deplatdindomoteur_creation_du_joueur [2022/03/27 19:24] (Version actuelle) Simon Deplat
Ligne 64: Ligne 64:
  
 ====Implémentation de la gravité==== ====Implémentation de la gravité====
 +
 +**[ NOTE ] : Comme discuté [[https://regakakobigman.netlify.app/godot/2019/10/09/how-to-use-delta.html|ici]], la gestion actuelle des accélérations est mal implémentée car elle n'est pas multipliée par delta.**
  
 Le joueur aura donc une masse et sera affecté par la gravité : Le joueur aura donc une masse et sera affecté par la gravité :
Ligne 70: Ligne 72:
 extends KinematicBody2D extends KinematicBody2D
  
-var _gravite = Global.gravite+var _gravite = 50
  
 var _masse = 1 var _masse = 1
  
 var _velocite = Vector2.ZERO var _velocite = Vector2.ZERO
 +
 +func _ready():
 + if get_tree().root.has_node("Global"):
 + _gravite = Global.gravite
  
 func _physics_process( _delta ): func _physics_process( _delta ):
Ligne 100: Ligne 106:
 extends KinematicBody2D extends KinematicBody2D
  
-var _gravite = Global.gravite+var _gravite = 50
  
 var _masse = 1 var _masse = 1
-var _forceSaut = 350+var _forceSaut = 1000
  
-var _forceSautActuelle 0+var _velocite Vector2.ZERO
  
-var _velocite Vector2.ZERO+func _ready(): 
 + if get_tree().root.has_node("Global"): 
 + _gravite Global.gravite
  
 func _physics_process( _delta ): func _physics_process( _delta ):
   
- traitementDuSaut() 
  entreeSaut()  entreeSaut()
   
  # Intégration de la gravité  # Intégration de la gravité
  _velocite.y += _gravite * _masse  _velocite.y += _gravite * _masse
- # Intégration de la vélocité de saut 
- _velocite.y -= _forceSautActuelle 
   
  _velocite = move_and_slide_with_snap(  _velocite = move_and_slide_with_snap(
Ligne 134: Ligne 139:
  if is_on_floor():  if is_on_floor():
  if Input.is_action_just_pressed("espace"):  if Input.is_action_just_pressed("espace"):
- _forceSautActuelle = _forceSaut + _velocite.y -= _forceSaut
- +
-# Gestion de la mécanique de saut +
-func traitementDuSaut(): +
- #Si le Joueur est au sol, mais a une vélocité de saut, +
- if is_on_floor() and _forceSautActuelle > 0: +
- # Remise à zéro de sa vélocité de saut +
- _forceSautActuelle = 0 +
- # Si le joueur n'est pas sur le sol mais saute +
- if not is_on_floor() and _forceSautActuelle > 0: +
- # Décroît de la vélocité de saut +
- _forceSautActuelle -= _gravite * _masse +
- # Remise à zéro si la vélocité de saut devient négative +
- if _forceSautActuelle < 0: +
- _forceSautActuelle = 0 +
 </code> </code>
  
 ====Ajout du déplacement latéral==== ====Ajout du déplacement latéral====
-Un simple algorithme qui permet de **déplacer le personnage sur l'axe horizontal**. Ici, le plus intéressant est la méthode //bouge()//, qui ne peut fonctionner qu'au clavier : le //nesting// permet de mettre en place plusieurs comportement différents en fonction de l'ordre dans lequel les touches sont appuyées/relâchées.+Un simple algorithme qui permet de **déplacer le Joueur sur l'axe horizontal**. Ici, le plus intéressant est la méthode //bouge()//, qui ne peut fonctionner qu'au clavier : le //nesting// permet de mettre en place plusieurs comportement différents en fonction de l'ordre dans lequel les touches sont appuyées/relâchées.
  
 Pas de phénomène d'accélération et d'inertie horizontale pour l'instant. Le déplacement pendant le saut est autorisé, et le restera probablement vu l'agréabilité de ce type de //gameplay//. Pas de phénomène d'accélération et d'inertie horizontale pour l'instant. Le déplacement pendant le saut est autorisé, et le restera probablement vu l'agréabilité de ce type de //gameplay//.
  
-//Personnage.gd// 
 <code> <code>
-class_name Personnage 
 extends KinematicBody2D extends KinematicBody2D
  
-var masse +var _gravite 50
-var gravite = Global.gravite +
-var forceSaut = 1 +
-var vitesse = 1+
  
-var forceSautActuelle = 0+var _masse = 1 
 +var _forceSaut = 1000 
 +var _vitesse = 300 
 + 
 +var _direction = 0
  
 var _velocite = Vector2.ZERO var _velocite = Vector2.ZERO
  
-# la fonction _physics_process héritée est appelée +func _ready(): 
-# après la fonction _physics_process parente + if get_tree().root.has_node("Global"): 
-func _physics_processdelta ): + _gravite Global.gravite 
- _velocite.y += gravite * masse * delta+ 
 +func _physics_process( _delta ):
   
- #Si le Joueur est au sol, et s'il est en train de sauter, + bouge() 
- if is_on_floor() and forceSautActuelle > 0: + entreeSaut() 
-Remise à zéro de sa vélocité de saut +  
- forceSautActuelle = 0 + Intégration du déplacement latéral 
-Si le joueur n'est pas sur le sol mais saute + _velocite.x = _direction * _vitesse 
- if not is_on_floor() and forceSautActuelle > 0: + # Intégration de la gravité 
-Décroît de la vélocité de saut + _velocite.y += _gravite * _masse 
- forceSautActuelle = forceSautActuelle - gravite * masse * delta +  
-Remise à zéro si la vélocité de saut devient négative + _velocite = move_and_slide_with_snap
- if forceSautActuelle < 0: + _velocite, 
- forceSautActuelle = 0+ Vector2.ZERO, Accroche au sol 
 + Vector2.UP, # Direction du sol ( Vector2.UP ) 
 + true, Ne glisse pas sur le sol en cas d'inactivité ? 
 + 4, Nombre de collisions traitées par cycle 
 + 0.9, # Angle maximum du sol en radians 
 + false Inertie infinie ? 
 + )
  
-</code>+# Appui sur le bouton de saut 
 +func entreeSaut(): 
 + # Mécanisme de saut 
 + if is_on_floor(): 
 + if Input.is_action_just_pressed("espace"): 
 + _velocite.y -= _forceSaut
  
-//Joueur.gd// +# Appui sur les boutons clavier de déplacement 
-<code> +func bouge(): 
-class_name Personnage + if Input.is_action_just_pressed("gauche"): 
-extends KinematicBody2D + _direction -
- + elif Input.is_action_just_pressed("droite"): 
-var masse = 1 + _direction 1
-var gravite = Global.gravite +
-var forceSaut = 1 +
-var vitesse = 1 +
- +
-var forceSautActuelle = 0 +
- +
-var _velocite = Vector2.ZERO +
- +
-# la fonction _physics_process héritée est appelée +
-# après la fonction _physics_process parente +
-func _physics_processdelta ): +
- _velocite.y +gravite * masse * delta+
   
- #Si le Joueur est au sol, et s'il est en train de sauter, + if Input.is_action_just_released("gauche"): 
- if is_on_floor() and forceSautActuelle > 0+ if not Input.is_action_pressed("droite"): 
- # Remise à zéro de sa vélocité de saut + _direction = 0 
- forceSautActuelle = 0 + else: 
- # Si le joueur n'est pas sur le sol mais saute + _direction 
- if not is_on_floor() and forceSautActuelle > 0+  
- # Décroît de la vélocité de saut + if Input.is_action_just_released("droite"): 
- forceSautActuelle forceSautActuelle - gravite * masse * delta ) + if not Input.is_action_pressed("gauche")
- # Remise à zéro si la vélocité de saut devient négative + _direction = 0 
- if forceSautActuelle < 0+ else: 
- forceSautActuelle = 0 + _direction = -1
 </code> </code>
  
Ligne 227: Ligne 215:
 Il y a maintenant nécessité pour le //Joueur// de **se mettre en mouvement et d'augmenter sa vitesse avant d'atteindre le maximum. Celui-ci met également un peu de temps à s'arrêter sur le sol. Cette décélération est absente lorsqu'il est en l'air.** Pour l'instant, être collé à un mur permet tout-de-même d'augmenter sa vitesse : cela sera réglé lors de l'appel à //is_on_wall()//. Il y a maintenant nécessité pour le //Joueur// de **se mettre en mouvement et d'augmenter sa vitesse avant d'atteindre le maximum. Celui-ci met également un peu de temps à s'arrêter sur le sol. Cette décélération est absente lorsqu'il est en l'air.** Pour l'instant, être collé à un mur permet tout-de-même d'augmenter sa vitesse : cela sera réglé lors de l'appel à //is_on_wall()//.
  
-//Personnage.gd// 
 <code> <code>
-class_name Personnage 
 extends KinematicBody2D extends KinematicBody2D
  
-var masse +var _gravite 50
-var gravite = Global.gravite +
-var forceSaut = 1 +
-var vitesse = 1+
  
-var acceleration 20 +var _masse 1 
-var deceleration = 20+var _forceSaut = 350 
 +var _vitesse = 300 
 +var _acceleration = 20 
 +var _deceleration = 10
  
-var forceSautActuelle = 0 +var _direction = 0 
-var vitesseActuelle = 0+var _vitesseActuelle = 0
  
 var _velocite = Vector2.ZERO var _velocite = Vector2.ZERO
- 
-# la fonction _physics_process héritée est appelée 
-# après la fonction _physics_process parente 
-func _physics_process( delta ): 
- _velocite.y += gravite * masse * delta 
-  
- #Si le Joueur est au sol, et s'il est en train de sauter, 
- if is_on_floor() and forceSautActuelle > 0: 
- # Remise à zéro de sa vélocité de saut 
- forceSautActuelle = 0 
- # Si le joueur n'est pas sur le sol mais saute 
- if not is_on_floor() and forceSautActuelle > 0: 
- # Décroît de la vélocité de saut 
- forceSautActuelle = forceSautActuelle - ( gravite * masse * delta ) 
- # Remise à zéro si la vélocité de saut devient négative 
- if forceSautActuelle < 0: 
- forceSautActuelle = 0 
- 
-</code> 
- 
-Joueur.gd 
-<code> 
-class_name Joueur 
-extends Personnage 
- 
-var _direction = 0 
  
 func _ready(): func _ready():
- masse = 100 + if get_tree().root.has_node("Global"): 
- forceSaut = 14000 + _gravite Global.gravite
- vitesse 400+
  
 func _physics_process( _delta ): func _physics_process( _delta ):
   
- # Vérification des entrées utilisateurs pour l'axe horizontal 
  bouge()  bouge()
 + entreeSaut()
 + traitementDuMouvement()
   
- # Vélocité horizontale+ # Intégration du déplacement latéral 
 + _velocite.x = _vitesseActuelle 
 + # Intégration de la gravité 
 + _velocite.y += _gravite * _masse 
 +  
 + _velocite = move_and_slide_with_snap( 
 + _velocite, 
 + Vector2.ZERO, # Accroche au sol 
 + Vector2.UP, # Direction du sol ( Vector2.UP ) 
 + true, # Ne glisse pas sur le sol en cas d'inactivité ? 
 + 4, # Nombre de collisions traitées par cycle 
 + 0.9, # Angle maximum du sol ( en radians ) 
 + false # Inertie infinie ? 
 +
 + 
 +# Appui sur le bouton de saut 
 +func entreeSaut(): 
 + # Mécanisme de saut 
 + if is_on_floor(): 
 + if Input.is_action_just_pressed("espace"): 
 + _velocite.y = _forceSaut 
 + 
 +# Appui sur les boutons clavier de déplacement 
 +func bouge(): 
 + if Input.is_action_just_pressed("gauche"): 
 + _direction = -1 
 + elif Input.is_action_just_pressed("droite"): 
 + _direction = 1 
 +  
 + if Input.is_action_just_released("gauche"): 
 + if not Input.is_action_pressed("droite"): 
 + _direction = 0 
 + else: 
 + _direction = 1 
 +  
 + if Input.is_action_just_released("droite"): 
 + if not Input.is_action_pressed("gauche"): 
 + _direction = 0 
 + else: 
 + _direction = -1 
 + 
 +# Gestion des accélérations/décélérations 
 +func traitementDuMouvement(): 
 +# Vélocité horizontale
  if _direction != 0:  if _direction != 0:
- vitesseActuelle += acceleration * _direction+ _vitesseActuelle += _acceleration * _direction
   
  # Restriction aux vitesses max  # Restriction aux vitesses max
- if vitesseActuelle < 0: + if _vitesseActuelle < 0: 
- if vitesseActuelle < -vitesse+ if _vitesseActuelle < -_vitesse
- vitesseActuelle = -vitesse+ _vitesseActuelle = -_vitesse
  else:  else:
- if vitesseActuelle vitesse+ if _vitesseActuelle _vitesse
- vitesseActuelle vitesse+ _vitesseActuelle _vitesse
  else:  else:
  # Décélération au sol  # Décélération au sol
  if is_on_floor():  if is_on_floor():
- if vitesseActuelle < 0: + if _vitesseActuelle < 0: 
- if vitesseActuelle < -deceleration+ if _vitesseActuelle < -_deceleration
- vitesseActuelle += deceleration+ _vitesseActuelle += _deceleration
  else:  else:
- vitesseActuelle = 0 + _vitesseActuelle = 0 
- elif vitesseActuelle > 0: + elif _vitesseActuelle > 0: 
- if vitesseActuelle deceleration+ if _vitesseActuelle _deceleration
- vitesseActuelle -= deceleration+ _vitesseActuelle -= _deceleration
  else:  else:
- vitesseActuelle = 0+ _vitesseActuelle = 0 
 +</code> 
 + 
 +====Affinage de l'algorithme de saut==== 
 +On ajoute deux mécanismes pour rendre les sauts plus agréables. 
 + 
 +Premièrement, **l'interruption d'un saut en relâchant la barre espace multiplie la vélocité par un ratio inférieur à 1 (ici 0.6) si celle-ci est négative, une fois par saut**. Le joueur peut donc sauter plus ou moins en haut en fonction du moment où il relâche le bouton. C'est notamment utilisé lors des passages de plate-formes où il y a des piques au-dessus du joueur. 
 + 
 +Deuxièmement, **la gravité contraire appliquée à la phase ascendante du saut est modifiée par un ratio qui peut nier tout ou partie de la gravité**. Au lieu d'un saut en cloche, la phase ascendant peut donc être plus rapide que la phase descendante. 
 + 
 +<code> 
 +extends KinematicBody2D 
 + 
 +var _gravite = 50 
 + 
 +var _masse = 2 
 +var _forceSaut = 2000 
 +var _vitesse = 300 
 +var _acceleration = 20 
 +var _deceleration = 10 
 +var _ratioDInterruptionDuSaut = 0.5 
 +var _ratioDGraviteSaut = 0.75 
 + 
 +var _direction = 0 
 +var _vitesseActuelle = 0 
 +var _forceSautActuelle = 0 
 + 
 +var _velocite = Vector2.ZERO 
 +var _saute = false 
 + 
 +func _ready(): 
 + if get_tree().root.has_node("Global"): 
 + _gravite = Global.gravite 
 + 
 +func _physics_process( _delta ):
   
- _velocite.x = vitesseActuelle+ bouge() 
 + entreeSaut() 
 + if _saute: 
 + if _velocite.y < 0: 
 + interruptionDuSaut() 
 + traitementDuMouvement()
   
-Mécanisme de saut +Intégration du déplacement latéral 
- if is_on_floor(): + _velocite._vitesseActuelle 
- if Input.is_action_just_pressed("espace"): +Intégration de la gravité 
- forceSautActuelle forceSaut + if _velocite.y < 0: 
-  + _velocite.y += _gravite * _masse * _ratioDGraviteSaut 
-Si le personnage a encore une vélocité de saut + else: 
- if forceSautActuelle > 0: + _velocite.y +_gravite _masse
- # Compensation de la gravité +
- _velocite.y -forceSautActuelle _delta+
   
  _velocite = move_and_slide_with_snap(  _velocite = move_and_slide_with_snap(
Ligne 328: Ligne 368:
  )  )
  
 +# Appui sur le bouton de saut
 +func entreeSaut():
 + # Mécanisme de saut
 + if is_on_floor():
 + if Input.is_action_just_pressed("espace"):
 + _velocite.y -= _forceSaut
 + _saute = true
 +
 +# Gestion de l'interruption du saut
 +func interruptionDuSaut():
 + if Input.is_action_just_released("espace"):
 + _velocite.y *= _ratioDInterruptionDuSaut
 + _saute = false
 +
 +# Appui sur les boutons clavier de déplacement
 func bouge(): func bouge():
  if Input.is_action_just_pressed("gauche"):  if Input.is_action_just_pressed("gauche"):
Ligne 346: Ligne 401:
  _direction = -1  _direction = -1
  
 +# Gestion des accélérations/décélérations
 +func traitementDuMouvement():
 +# Vélocité horizontale
 + if _direction != 0:
 + _vitesseActuelle += _acceleration * _direction
 +
 + # Restriction aux vitesses max
 + if _vitesseActuelle < 0:
 + if _vitesseActuelle < -_vitesse:
 + _vitesseActuelle = -_vitesse
 + else:
 + if _vitesseActuelle > _vitesse:
 + _vitesseActuelle = _vitesse
 + else:
 + # Décélération au sol
 + if is_on_floor():
 + if _vitesseActuelle < 0:
 + if _vitesseActuelle < -_deceleration:
 + _vitesseActuelle += _deceleration
 + else:
 + _vitesseActuelle = 0
 + elif _vitesseActuelle > 0:
 + if _vitesseActuelle > _deceleration:
 + _vitesseActuelle -= _deceleration
 + else:
 + _vitesseActuelle = 0
 </code> </code>
  
-====Affinage de l'algorithme de saut==== +====Ajout d'une Camera2D==== 
-On ajoute deux mécanismes pour rendre les sauts plus agréables.+ 
 +**L'ajout d'un nœud //Camera2D// permet de suivre facilement les déplacement du personnage.** 
 + 
 +À l'aide de l'inspecteur, j'ai simplement réglé son //offset// à [ 0, - 150 ], et coché la propriété //Current//
 + 
 +C'est suffisant pour le prototypage. 
 + 
 +====Changement de direction du personnage==== 
 + 
 +L'algorithme est tout bête, il suffit d'**inverser l'échelle du //Sprite// sur l'axe X lors de l'appel à la fonction //bouge()//** . Attention cependant, comme j'ai opté pour un déplacement spécifique lors de l'utilisation du clavier, à savoir de pouvoir reculer sans changer de sens en appuyant sur //Gauche// et //Droite// en même temps, le retournement ne se fait pas dans ce cas-ci. 
 + 
 +<code> 
 +# Appui sur les boutons clavier de déplacement 
 +func bouge(): 
 + if Input.is_action_just_pressed("gauche"): 
 + _direction = -1 
 + if not Input.is_action_pressed("droite"): 
 + $Sprite.set_scale( Vector2( -1, 1 ) ) 
 + elif Input.is_action_just_pressed("droite"): 
 + _direction = 1 
 + if not Input.is_action_pressed("gauche"): 
 + $Sprite.set_scale( Vector2( 1, 1 ) ) 
 + if Input.is_action_just_released("gauche"): 
 + if not Input.is_action_pressed("droite"): 
 + _direction = 0 
 + else: 
 + _direction = 1 
 + $Sprite.set_scale( Vector2( 1, 1 ) ) 
 +  
 + if Input.is_action_just_released("droite"): 
 + if not Input.is_action_pressed("gauche"): 
 + _direction = 0 
 + else: 
 + _direction = -1 
 + $Sprite.set_scale( Vector2( -1, 1 ) ) 
 +</code> 
 + 
 + 
 +====Animation du personnage==== 
 + 
 +Il ne manque à ce stade plus que d'**animer le personnage**. J'ai pour ce faire créé quatre //sprites// très simple. Le résultat n'est pas fabuleux mais permet de comprendre comment faire. Voici les texture utilisées : 
 + 
 +{{ ::dm_quatrelutins.png?357 |}} 
 + 
 +J'ai commencé par **ajouter un nœud //AnimationPlayer//** à la scène, auquel j'ai rajouté **3 pistes, nommées //repos//, // saut//, et //marche//**. Pour chacune d'elles, j'ai simplement **modifié la texture** du //Sprite//. //repos// et //saut// ne consistent qu'en une seule clef, //marche// boucle sur 4 textures. 
 + 
 +J'ai activé **la //lecture automatique au chargement// de l'animation //repos//**, et activé **la //lecture en boucle// de l'animation //marche//**. 
 + 
 +**J'ai dû rajouter un nœud //RayCast2D// pour que l'animation du saut se fasse correctement.** 
 + 
 +Ma première idée était d'utiliser //is_on_floor()// pour détecter si le personnage était en train de sauter. Cependant, **lorsque le //KinematicBody2D// glisse le long d'une pente, il lui arrive de se décoller légèrement lorsque que la pente ascendante passe sur un plan horizontal**. Dans ce cas, //is_on_floor()// passe à //false// et déclenche l'animation, ce qui n'est pas joli à voir. 
 + 
 +À la place, j'ai mis un //RayCast2D// sous les pieds du //Joueur//, dont la propriété //Cast To// a été réglée à Vector2( 0, 20 ). J'ai coché le paramètre //enabled// pour l'activer, et changer le //masque de collision//
 + 
 +Cependant, cela pose le problème inverse lorsque que le personnage passe une plate-forme à sens unique en sautant. Alors qu'il est sensé être en saut, le //RayCast2D// détecte la plate-forme et lance l'animation. Il faut donc, pendant le saut, désactiver le //RayCast2D//
 + 
 +Le tout est ensuite appelé au sein d'une fonction dédiée : 
 + 
 +<code> 
 +func _physics_process( _delta ): 
 + [...] 
 + animer() 
 + 
 +[...] 
 + 
 +# Appui sur le bouton de saut 
 +func entreeSaut(): 
 + # Mécanisme de saut 
 + if is_on_floor(): 
 + if not $RayCast2D.enabled: 
 + $RayCast2D.set_enabled( true ) 
 + if Input.is_action_just_pressed("espace"): 
 + _velocite.y -= _forceSaut 
 + _saute = true 
 + $RayCast2D.set_enabled( false ) 
 + 
 + 
 +[...] 
 +# Animation du personnage : 
 +func animer(): 
 + # Vérifier si le personnage est au sol : 
 + if $RayCast2D.enabled: 
 + if $RayCast2D.is_colliding(): 
 + # S'il bouge 
 + if _velocite.x != 0: 
 + $AnimationPlayer.play("marche"
 + # Sinon 
 + else: 
 + $AnimationPlayer.play("repos"
 + else: 
 + $AnimationPlayer.play("saut"
 +</code> 
 + 
 + 
 +====Contrôle du personnage à la manette==== 
 + 
 +Avant de terminer, je souhaite simplement que l'on puisse également **contrôler le personnage à l'aide d'une manette**. 
 + 
 +Dans cette optique, je décide de changer la fonction //bouge()// affin qu'elle se comporte différemment en fonction d'un contrôle au clavier ou à la manette. Trois types de contrôles sont possibles, à la manette, au clavier, et au clavier et à la souris. Cependant, le déplacement du personnage étant restreint à la main gauche au clavier, il sera le même pour les deux derniers modes. 
 + 
 +Je rajoute donc **un paramètre d'entrée et de zone morte pour le **joystick**, et change l'algorithme de déplacement** : 
 + 
 +<code> 
 +extends KinematicBody2D 
 + 
 +var _typeEntree = "clavier" 
 +var _zoneMorte = 0.3 
 + 
 +var _gravite = 50 
 + 
 +var _masse = 2 
 +var _forceSaut = 2000 
 +var _vitesse = 400 
 +var _acceleration = 20 
 +var _deceleration = 10 
 +var _ratioDInterruptionDuSaut = 0.5 
 +var _ratioDGraviteSaut = 0.75 
 + 
 +var _direction = 0 
 +var _vitesseActuelle = 0 
 +var _forceSautActuelle = 0 
 + 
 +var _velocite = Vector2.ZERO 
 +var _saute = false 
 + 
 +func _ready(): 
 + if get_tree().root.has_node("Global"): 
 + _typeEntree = Global.typeEntree 
 + _zoneMorte = Global.zoneMorte 
 + _gravite = Global.gravite 
 + 
 +func _physics_process( _delta ): 
 +  
 + bouge() 
 + entreeSaut() 
 + if _saute: 
 + if _velocite.y < 0: 
 + interruptionDuSaut() 
 + traitementDuMouvement() 
 +  
 + # Intégration du déplacement latéral 
 + _velocite.x = _vitesseActuelle 
 + # Intégration de la gravité 
 + if _velocite.y < 0: 
 + _velocite.y += _gravite * _masse * _ratioDGraviteSaut 
 + else: 
 + _velocite.y += _gravite * _masse 
 +  
 + _velocite = move_and_slide_with_snap( 
 + _velocite, 
 + Vector2.ZERO, # Accroche au sol 
 + Vector2.UP, # Direction du sol ( Vector2.UP ) 
 + true, # Ne glisse pas sur le sol en cas d'inactivité ? 
 + 4, # Nombre de collisions traitées par cycle 
 + 0.9, # Angle maximum du sol ( en radians ) 
 + false # Inertie infinie ? 
 +
 +  
 + animer() 
 + 
 +# Appui sur le bouton de saut 
 +func entreeSaut(): 
 + # Mécanisme de saut 
 + if is_on_floor(): 
 + if not $RayCast2D.enabled: 
 + $RayCast2D.set_enabled( true ) 
 + if Input.is_action_just_pressed("espace"): 
 + _velocite.y -= _forceSaut 
 + _saute = true 
 + $RayCast2D.set_enabled( false ) 
 + 
 +# Gestion de l'interruption du saut 
 +func interruptionDuSaut(): 
 + if Input.is_action_just_released("espace"): 
 + _velocite.y *= _ratioDInterruptionDuSaut 
 + _saute = false 
 + 
 +# Appui sur les boutons clavier de déplacement 
 +func bouge(): 
 + if _typeEntree == "manette": 
 + var entree = Input.get_axis("gauche", "droite"
 + if entree < -_zoneMorte: 
 + _direction = -1 
 + $Sprite.set_scale( Vector2( -1, 1 ) ) 
 + elif entree > _zoneMorte: 
 + _direction = 1 
 + $Sprite.set_scale( Vector2( 1, 1 ) ) 
 + else: 
 + _direction = 0 
 + else: 
 + if Input.is_action_just_pressed("gauche"): 
 + _direction = -1 
 + if not Input.is_action_pressed("droite"): 
 + $Sprite.set_scale( Vector2( -1, 1 ) ) 
 + elif Input.is_action_just_pressed("droite"): 
 + _direction = 1 
 + if not Input.is_action_pressed("gauche"): 
 + $Sprite.set_scale( Vector2( 1, 1 ) ) 
 + if Input.is_action_just_released("gauche"): 
 + if not Input.is_action_pressed("droite"): 
 + _direction = 0 
 + else: 
 + _direction = 1 
 + $Sprite.set_scale( Vector2( 1, 1 ) ) 
 +  
 + if Input.is_action_just_released("droite"): 
 + if not Input.is_action_pressed("gauche"): 
 + _direction = 0 
 + else: 
 + _direction = -1 
 + $Sprite.set_scale( Vector2( -1, 1 ) ) 
 + 
 +# Gestion des accélérations/décélérations 
 +func traitementDuMouvement(): 
 +# Vélocité horizontale 
 + if _direction != 0: 
 + _vitesseActuelle += _acceleration * _direction 
 +  
 + # Restriction aux vitesses max 
 + if _vitesseActuelle < 0: 
 + if _vitesseActuelle < -_vitesse: 
 + _vitesseActuelle = -_vitesse 
 + else: 
 + if _vitesseActuelle > _vitesse: 
 + _vitesseActuelle = _vitesse 
 + else: 
 + # Décélération au sol 
 + if is_on_floor(): 
 + if _vitesseActuelle < 0: 
 + if _vitesseActuelle < -_deceleration: 
 + _vitesseActuelle += _deceleration 
 + else: 
 + _vitesseActuelle = 0 
 + elif _vitesseActuelle > 0: 
 + if _vitesseActuelle > _deceleration: 
 + _vitesseActuelle -= _deceleration 
 + else: 
 + _vitesseActuelle = 0 
 + 
 +# Animation du personnage : 
 +func animer(): 
 + # Vérifier si le personnage est au sol : 
 + if $RayCast2D.enabled: 
 + if $RayCast2D.is_colliding(): 
 + # S'il bouge 
 + if _velocite.x != 0: 
 + $AnimationPlayer.play("marche"
 + # Sinon 
 + else: 
 + $AnimationPlayer.play("repos"
 + else: 
 + $AnimationPlayer.play("saut"
 +</code> 
 + 
 + 
 + 
 +====Notes de fin==== 
 + 
 +Et voilà pour cette première étape de personnage. Je décide de m'arrêter ici car **nous avons un personnage jouable pour un jeu simple**. En fait nous avons quasiment le personnage de //Super Mario Bros 3// : celui-ci se déplace latéralement, saute, est affecté par l'inertie, et rentre en collision avec l'environnement. 
 + 
 +Il pourra servir de base pour des jeux n'ayant pas besoin de contrôles supplémentaires. 
 + 
 +Au cas où, voici à quoi ressemble ma scène dans l'éditeur :
  
-Premièrement, **l'interruption d'un saut en relâchant la barre espace multiplie la vélocité du saut par un ration inférieur à 1** (ici 0.6). Le joueur peut donc sauter plus ou moins en haut en fonction du moment où il relâche le bouton. C'est notamment utilisé lors des passages de plate-formes où il y a des piques au-dessus du joueur.+{{ ::dm_joueursimpleediteur.jpg?600 |}}
  
-**[EN CONSTRUCTION]**+Notez que je n'ai pas renommé les noeuds (sauf le parent) pour que vous les identifiiez plus facilement ici, mais qu'il est tout-de-même conseillé de les renommer lors de ses projets propres.
  
 +Je créé par ailleurs **une copie autonome de ce //Joueur// dans le dossier //src/JoueurSimple/// **, en stockant l'ensemble des ressources à l'intérieur même du dossier afin de faciliter l'importation de la scène dans d'autres projets. La dépendance à //Global// n'étant pas forte, le seul paramétrage à faire est d'associer les bonnes entrées utilisateurs dans les //Paramètres du projet//.
 {{tag>godot dindomoteur jeu vidéo}} {{tag>godot dindomoteur jeu vidéo}}
dindomoteur_creation_du_joueur.1647800278.txt.gz · Dernière modification : 2022/03/20 18:17 de Simon Deplat