Menu
CoddyTech

Développement d’un personnage de jeu

Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 64 sur 65.

challenge icon

Défi

Moyen

Créez les personnages d’un jeu de rôle : une classe abstraite Character, trois classes qui en héritent et les capacités que les personnages apprennent.

Character dans character.gd est une classe @abstract :

  • Propriétés : character_name (issu du constructeur), level 1, max_health et health 100.0, max_mana et mana 50, strength, intelligence et agility 10, defense 5, ainsi que abilities, un Array[Ability]. Les valeurs de santé sont des float, les autres statistiques des int.
  • Un signal defeated(character_name: String).
  • Méthodes abstraites class_title() -> String et attack_power() -> float.
  • level_up() -> String : niveau +1, santé maximale +10, mana maximale +5, force, intelligence, agilité et défense +1 ; la santé et le mana sont rétablis à leur maximum. Renvoie NAME reached level N!.
  • attack(target) : affiche NAME attacks TARGET, puis renvoie target.take_damage(attack_power()).
  • take_damage(amount) -> float : les dégâts sont de amount - defense * 0.5, avec un minimum de 1.0 ; la santé diminue de cette valeur et ne descend jamais en dessous de 0.0. Affiche NAME takes D damage (HP H) avec une décimale pour chaque valeur, émet le signal defeated lorsque cette attaque fait tomber la santé à 0 et renvoie les dégâts.
  • is_alive() : la santé est supérieure à 0. learn_ability(ability) ajoute la capacité à abilities.
  • use_ability(index, target) -> float : si l’index est en dehors de abilities, affiche NAME has no ability INDEX et renvoie 0.0 ; sinon, renvoie la valeur renvoyée par use() de la capacité.
  • _to_string() : NAME the TITLE (level L): HP H/MAX, mana M/MAX, STR S, INT I, AGI A, DEF D, avec une décimale pour la santé.

Chaque sous-classe appelle le constructeur parent, puis définit ses propres statistiques de départ (les autres conservent les valeurs de base), renvoie son nom de classe depuis class_title() et redéfinit level_up() avec super() :

  • Warrior : santé 150.0, mana 30, force 15, intelligence 5, défense 8 ; puissance d’attaque strength * 1.2 ; lors de la montée de niveau, gagne aussi +2 en force et +10 en santé maximale (santé rétablie).
  • Mage : santé 80.0, mana 150, force 5, intelligence 20, défense 3 ; puissance d’attaque intelligence * 0.4 ; après une attaque normale, récupère 5 points de mana (sans dépasser le maximum) ; lors de la montée de niveau, gagne aussi +2 en intelligence et +15 en mana maximale (mana rétabli).
  • Rogue : santé 100.0, mana 60, force 12, intelligence 8, agilité 18, défense 4 ; puissance d’attaque strength * 0.5 + agility * 0.7 ; lors de la montée de niveau, gagne aussi +2 en agilité.

Ability dans ability.gd : le constructeur prend ability_name, mana_cost (int) et damage (float). use(user, target) -> float affiche USER does not have enough mana for ABILITY et renvoie 0.0 lorsque le mana de l’utilisateur est inférieur au coût. Sinon, il dépense le mana, affiche USER casts ABILITY on TARGET et renvoie target.take_damage(damage + user.intelligence * 0.5).

Le code fourni se connecte au signal defeated de chaque personnage et affiche NAME is defeated!. Pour cette entrée :

hero warrior|Aragorn
hero rogue|Orc
attack Aragorn|Orc
attack Orc|Aragorn
level Aragorn
status Aragorn

la sortie est :

Aragorn attacks Orc
Orc takes 16.0 damage (HP 84.0)
Orc attacks Aragorn
Aragorn takes 14.6 damage (HP 135.4)
Aragorn reached level 2!
Aragorn the Warrior (level 2): HP 170.0/170.0, mana 35/35, STR 18, INT 6, AGI 11, DEF 9

Votre code doit se trouver dans character.gd, warrior.gd, mage.gd, rogue.gd et ability.gd. main.gd contient le code d’entrée/sortie fourni et ne peut pas être modifié.

Essayez vous-même

extends Node

func _ready():
	# Code d'entrée/sortie fourni : ne le modifiez pas

	var heroes := {}

	var line := OS.read_string_from_stdin()
	while line != "":
		var parts := line.split(" ", true, 1)
		var f: PackedStringArray = parts[1].split("|") if parts.size() > 1 else PackedStringArray()
		match parts[0]:
			"hero":
				var hero: Character
				match f[0]:
					"warrior":
						hero = Warrior.new(f[1])
					"mage":
						hero = Mage.new(f[1])
					"rogue":
						hero = Rogue.new(f[1])
				hero.defeated.connect(func(who): print(who, " is defeated!"))
				heroes[f[1]] = hero
			"learn":
				heroes[f[0]].learn_ability(Ability.new(f[1], int(f[2]), float(f[3])))
			"attack":
				heroes[f[0]].attack(heroes[f[1]])
			"cast":
				heroes[f[0]].use_ability(int(f[1]), heroes[f[2]])
			"level":
				print(heroes[f[0]].level_up())
			"status":
				print(heroes[f[0]])

		line = OS.read_string_from_stdin()

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur GDScript en ligne