Menu
CoddyTech

Pengembangan Karakter Game

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GDScript di Coddy. Pelajaran 64 dari 65.

challenge icon

Tantangan

Sedang

Buat karakter untuk game bermain peran: sebuah Character abstrak, tiga class yang memperluasnya, dan ability yang dipelajari karakter.

Character di character.gd adalah class @abstract:

  • Property: character_name (dari constructor), level 1, max_health dan health 100.0, max_mana dan mana 50, strength, intelligence dan agility 10, defense 5, dan abilities, sebuah Array[Ability]. Nilai health bertipe float, sedangkan statistik lainnya bertipe int.
  • Sebuah signal defeated(character_name: String).
  • Method abstrak class_title() -> String dan attack_power() -> float.
  • level_up() -> String: level bertambah +1, health maksimum bertambah +10, mana maksimum bertambah +5, strength, intelligence, agility, dan defense masing-masing bertambah +1; health dan mana diisi kembali hingga nilai maksimumnya. Mengembalikan NAME reached level N!.
  • attack(target): mencetak NAME attacks TARGET, lalu mengembalikan target.take_damage(attack_power()).
  • take_damage(amount) -> float: damage dihitung dengan amount - defense * 0.5, tetapi minimal 1.0; health berkurang sebesar nilai tersebut dan tidak pernah kurang dari 0.0. Method ini mencetak NAME takes D damage (HP H) dengan satu angka desimal untuk setiap nilai, memancarkan signal defeated saat serangan ini menurunkan health hingga 0, dan mengembalikan damage.
  • is_alive(): health lebih dari 0. learn_ability(ability) menambahkan ability ke abilities.
  • use_ability(index, target) -> float: jika index berada di luar abilities, mencetak NAME has no ability INDEX dan mengembalikan 0.0; jika tidak, mengembalikan nilai yang dikembalikan oleh use() milik ability tersebut.
  • _to_string(): NAME the TITLE (level L): HP H/MAX, mana M/MAX, STR S, INT I, AGI A, DEF D, health ditampilkan dengan satu angka desimal.

Setiap subclass memanggil constructor induk, lalu menetapkan statistik awalnya sendiri (statistik lainnya tetap menggunakan nilai dasar), mengembalikan nama class-nya dari class_title(), dan menimpa level_up() dengan super():

  • Warrior: health 150.0, mana 30, strength 15, intelligence 5, defense 8; attack power strength * 1.2; saat naik level, strength juga bertambah +2 dan health maksimum bertambah +10 (health diisi kembali).
  • Mage: health 80.0, mana 150, strength 5, intelligence 20, defense 3; attack power intelligence * 0.4; setelah melakukan serangan biasa, mana bertambah kembali sebanyak 5 (tidak pernah melebihi nilai maksimum); saat naik level, intelligence juga bertambah +2 dan mana maksimum bertambah +15 (mana diisi kembali).
  • Rogue: health 100.0, mana 60, strength 12, intelligence 8, agility 18, defense 4; attack power strength * 0.5 + agility * 0.7; saat naik level, agility juga bertambah +2.

Ability di ability.gd: constructor menerima ability_name, mana_cost (int), dan damage (float). use(user, target) -> float mencetak USER does not have enough mana for ABILITY dan mengembalikan 0.0 jika mana pengguna kurang dari biayanya. Jika tidak, method ini mengurangi mana, mencetak USER casts ABILITY on TARGET, lalu mengembalikan target.take_damage(damage + user.intelligence * 0.5).

Kode yang disediakan menghubungkan signal defeated pada setiap karakter dan mencetak NAME is defeated!. Untuk input ini:

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

output-nya adalah:

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

Tulis kodemu di character.gd, warrior.gd, mage.gd, rogue.gd, dan ability.gd. main.gd berisi kode input/output yang disediakan dan tidak dapat diedit.

Coba sendiri

extends Node

func _ready():
	# Kode input/output yang disediakan: biarkan apa adanya

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

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler GDScript online