Menu
CoddyTech

游戏角色开发

本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 64 课,共 65 课。

challenge icon

挑战

中等

构建角色扮演游戏中的角色:一个抽象的 Character、三个扩展它的类,以及角色可以学习的技能。

character.gd 中的 Character 是一个 @abstract 类:

  • 属性:character_name(来自构造函数)、level 1、max_health 和 health 100.0、max_mana 和 mana 50、strength、intelligence 和 agility 10、defense 5,以及作为 Array[Ability] 的 abilities。生命值是 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),其中数值均保留一位小数;如果这次攻击使生命值降至 0,则发出 defeated 信号,并返回伤害值。
  • 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() 返回自己的类名,并使用 super() 重写 level_up():

  • 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.gd 中的 Ability:构造函数接收 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 在线编译器