Menu
CoddyTech

Sviluppo di un personaggio di gioco

Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 64 di 65.

challenge icon

Sfida

Medio

Crea i personaggi di un gioco di ruolo: una classe astratta Character, tre classi che la estendono e le abilità che i personaggi imparano.

Character in character.gd è una classe @abstract:

  • Proprietà: character_name (dal costruttore), level 1, max_health e health 100.0, max_mana e mana 50, strength, intelligence e agility 10, defense 5 e abilities, un Array[Ability]. I valori della salute sono float, le altre statistiche sono int.
  • Un segnale defeated(character_name: String).
  • Metodi astratti class_title() -> String e attack_power() -> float.
  • level_up() -> String: livello +1, salute massima +10, mana massimo +5, forza, intelligenza, agilità e difesa +1; salute e mana vengono ripristinati al massimo. Restituisce NAME reached level N!.
  • attack(target): stampa NAME attacks TARGET, poi restituisce target.take_damage(attack_power()).
  • take_damage(amount) -> float: il danno è amount - defense * 0.5, ma almeno 1.0; la salute diminuisce di questa quantità e non scende mai sotto 0.0. Stampa NAME takes D damage (HP H) con un decimale per ciascun valore, emette defeated quando questo colpo porta la salute a 0 e restituisce il danno.
  • is_alive(): la salute è maggiore di 0. learn_ability(ability) aggiunge l'abilità a abilities.
  • use_ability(index, target) -> float: se l'indice è al di fuori di abilities, stampa NAME has no ability INDEX e restituisce 0.0; altrimenti restituisce il valore ritornato da use() dell'abilità.
  • _to_string(): NAME the TITLE (level L): HP H/MAX, mana M/MAX, STR S, INT I, AGI A, DEF D, salute con un decimale.

Ogni sottoclasse chiama il costruttore della classe genitore, poi imposta i propri valori iniziali delle statistiche (le altre mantengono i valori della classe base), restituisce il nome della propria classe da class_title() e sovrascrive level_up() usando super():

  • Warrior: salute 150.0, mana 30, forza 15, intelligenza 5, difesa 8; potenza d'attacco strength * 1.2; quando sale di livello, ottiene anche forza +2 e salute massima +10 (la salute viene ripristinata).
  • Mage: salute 80.0, mana 150, forza 5, intelligenza 20, difesa 3; potenza d'attacco intelligence * 0.4; dopo un attacco normale recupera 5 mana (senza superare il massimo); quando sale di livello, ottiene anche intelligenza +2 e mana massimo +15 (il mana viene ripristinato).
  • Rogue: salute 100.0, mana 60, forza 12, intelligenza 8, agilità 18, difesa 4; potenza d'attacco strength * 0.5 + agility * 0.7; quando sale di livello, ottiene anche agilità +2.

Ability in ability.gd: il costruttore accetta ability_name, mana_cost (int) e damage (float). use(user, target) -> float stampa USER does not have enough mana for ABILITY e restituisce 0.0 quando il mana dell'utente è inferiore al costo. Altrimenti consuma il mana, stampa USER casts ABILITY on TARGET e restituisce target.take_damage(damage + user.intelligence * 0.5).

Il codice fornito si collega al segnale defeated di ogni personaggio e stampa NAME is defeated!. Per questo input:

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

l'output è:

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

Il tuo codice va inserito in character.gd, warrior.gd, mage.gd, rogue.gd e ability.gd. main.gd contiene il codice fornito per input/output e non può essere modificato.

Provalo tu

extends Node

func _ready():
	# Codice di input/output fornito: lascialo così com'è

	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()

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore GDScript online