Menu
CoddyTech

Oyun Karakteri Geliştirme

Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 64 / 65.

challenge icon

Görev

Orta

Bir rol yapma oyununun karakterlerini oluştur: soyut bir Character, onu genişleten üç sınıf ve karakterlerin öğrendiği yetenekler.

character.gd dosyasındaki Character, bir @abstract sınıfıdır:

  • Özellikler: character_name (yapıcıdan alınır), level 1, max_health ve health 100.0, max_mana ve mana 50, strength, intelligence ve agility 10, defense 5 ve bir Array[Ability] olan abilities. Sağlık değerleri float, diğer istatistikler int türündedir.
  • defeated(character_name: String) sinyali.
  • class_title() -> String ve attack_power() -> float soyut metotları.
  • level_up() -> String: seviye +1, maksimum sağlık +10, maksimum mana +5, güç, zekâ, çeviklik ve savunma +1 artar; sağlık ve mana maksimum değerlerine doldurulur. NAME reached level N! döndürür.
  • attack(target): NAME attacks TARGET yazdırır, ardından target.take_damage(attack_power()) değerini döndürür.
  • take_damage(amount) -> float: hasar amount - defense * 0.5 kadardır, ancak en az 1.0 olur; sağlık bu miktar kadar azalır ve asla 0.0 değerinin altına düşmez. Her değeri bir ondalık basamakla NAME takes D damage (HP H) yazdırır, bu darbe sağlığı 0 değerine düşürdüğünde defeated sinyalini gönderir ve hasarı döndürür.
  • is_alive(): sağlık 0 değerinden büyükse. learn_ability(ability), yeteneği abilities listesine ekler.
  • use_ability(index, target) -> float: dizin abilities sınırlarının dışındaysa NAME has no ability INDEX yazdırır ve 0.0 döndürür; aksi takdirde yeteneğin use() metodunun döndürdüğü değeri döndürür.
  • _to_string(): NAME the TITLE (level L): HP H/MAX, mana M/MAX, STR S, INT I, AGI A, DEF D; sağlık değeri bir ondalık basamakla gösterilir.

Her alt sınıf üst sınıfın yapıcısını çağırır, ardından kendi başlangıç istatistiklerini ayarlar (diğerleri temel sınıftaki değerlerde kalır), class_title() metodundan sınıf adını döndürür ve level_up() metodunu super() kullanarak geçersiz kılar:

  • Warrior: sağlık 150.0, mana 30, güç 15, zekâ 5, savunma 8; saldırı gücü strength * 1.2; seviye atladığında ayrıca güç +2 ve maksimum sağlık +10 artar (sağlık doldurulur).
  • Mage: sağlık 80.0, mana 150, güç 5, zekâ 20, savunma 3; saldırı gücü intelligence * 0.4; normal bir saldırıdan sonra 5 mana geri kazanır (maksimum değeri aşmaz); seviye atladığında ayrıca zekâ +2 ve maksimum mana +15 artar (mana doldurulur).
  • Rogue: sağlık 100.0, mana 60, güç 12, zekâ 8, çeviklik 18, savunma 4; saldırı gücü strength * 0.5 + agility * 0.7; seviye atladığında ayrıca çeviklik +2 artar.

ability.gd dosyasındaki Ability: yapıcı ability_name, mana_cost (int) ve damage (float) değerlerini alır. use(user, target) -> float, kullanıcının manası maliyetin altındaysa USER does not have enough mana for ABILITY yazdırır ve 0.0 döndürür. Aksi takdirde manayı harcar, USER casts ABILITY on TARGET yazdırır ve target.take_damage(damage + user.intelligence * 0.5) değerini döndürür.

Verilen kod her karakterin defeated sinyaline bağlanır ve NAME is defeated! yazdırır. Bu girdi için:

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

çıktı şöyledir:

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

Kodunu character.gd, warrior.gd, mage.gd, rogue.gd ve ability.gd dosyalarına yaz. main.gd, verilen girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

extends Node

func _ready():
	# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın

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

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online GDScript derleyicisi