Menu
CoddyTech
flag Ar iconالعربيةdown icon

تطوير شخصية لعبة

جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 64 من 65.

challenge icon

التحدي

متوسط

أنشئ شخصيات للعبة تقمّص أدوار: صنفًا مجردًا Character، وثلاثة أصناف ترث منه، وقدرات تتعلمها الشخصيات.

Character في character.gd صنف @abstract:

  • الخصائص: character_name (من المُنشئ)، level 1، وmax_health وhealth 100.0، وmax_mana وmana 50، وstrength وintelligence وagility 10، وdefense 5، وabilities، وهي Array[Ability]. قيم الصحة من النوع float، أما الإحصاءات الأخرى فمن النوع int.
  • إشارة defeated(character_name: String).
  • الطريقتان المجردتان class_title() -> String وattack_power() -> float.
  • level_up() -> String: زيادة المستوى بمقدار +1، والصحة القصوى بمقدار +10، والمانا القصوى بمقدار +5، والقوة والذكاء والرشاقة والدفاع بمقدار +1؛ وتُستعاد الصحة والمانا إلى الحد الأقصى. تُرجع NAME reached level N!.
  • attack(target): تطبع NAME attacks TARGET، ثم تُرجع target.take_damage(attack_power()).
  • take_damage(amount) -> float: يكون الضرر amount - defense * 0.5، على ألا يقل عن 1.0؛ وتنخفض الصحة بمقداره، لكن لا تقل عن 0.0. تطبع NAME takes D damage (HP H) مع منزلة عشرية واحدة لكل قيمة، وتُصدر الإشارة defeated عندما تؤدي هذه الضربة إلى وصول الصحة إلى 0، ثم تُرجع الضرر.
  • is_alive(): الصحة أكبر من 0. وتضيف learn_ability(ability) القدرة إلى abilities.
  • use_ability(index, target) -> float: إذا كان الفهرس خارج نطاق abilities، تطبع NAME has no ability INDEX وتُرجع 0.0؛ وإلا فتُرجع ما تُرجعه use() الخاصة بالقدرة.
  • _to_string(): NAME the TITLE (level L): HP H/MAX, mana M/MAX, STR S, INT I, AGI A, DEF D، مع عرض الصحة بمنزلة عشرية واحدة.

يستدعي كل صنف فرعي مُنشئ الصنف الأب، ثم يضبط إحصاءاته الابتدائية (وتبقى الإحصاءات الأخرى على القيم الأساسية)، ويُرجع اسم صنفه من class_title() ويتجاوز level_up() باستخدام super():

  • Warrior: الصحة 150.0، والمانا 30، والقوة 15، والذكاء 5، والدفاع 8؛ قوة الهجوم strength * 1.2؛ وعند رفع المستوى تزداد القوة أيضًا بمقدار +2 والصحة القصوى بمقدار +10 (وتُستعاد الصحة).
  • Mage: الصحة 80.0، والمانا 150، والقوة 5، والذكاء 20، والدفاع 3؛ قوة الهجوم intelligence * 0.4؛ وبعد الهجوم العادي يستعيد 5 من المانا (من دون تجاوز الحد الأقصى)؛ وعند رفع المستوى يزداد الذكاء أيضًا بمقدار +2 والمانا القصوى بمقدار +15 (وتُستعاد المانا).
  • Rogue: الصحة 100.0، والمانا 60، والقوة 12، والذكاء 8، والرشاقة 18، والدفاع 4؛ قوة الهجوم strength * 0.5 + agility * 0.7؛ وعند رفع المستوى تزداد الرشاقة أيضًا بمقدار +2.

Ability في ability.gd: يأخذ المُنشئ ability_name وmana_cost (int) وdamage (float). تطبع use(user, target) -> float العبارة USER does not have enough mana for ABILITY وتُرجع 0.0 عندما تكون مانا المستخدم أقل من التكلفة. وإلا تخصم المانا، وتطبع USER casts ABILITY on TARGET، ثم تُرجع target.take_damage(damage + user.intelligence * 0.5).

يربط الكود المزوّد إشارة defeated لكل شخصية ويطبع NAME is defeated!. لهذا الإدخال:

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

يكون الناتج:

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

ضع التعليمات البرمجية في character.gd وwarrior.gd وmage.gd وrogue.gd وability.gd. يحتوي main.gd على كود الإدخال والإخراج المزوّد، ولا يمكن تعديله.

جرّب بنفسك

extends Node

func _ready():
	# كود الإدخال/الإخراج المقدَّم: أبقه كما هو

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

جميع دروس البرمجة كائنية التوجّه

تدرّب بنفسك: مترجم GDScript عبر الإنترنت