Menu
CoddyTech

Phát triển nhân vật trò chơi

Thuộc phần Lập trình hướng đối tượng trong hành trình GDScript của Coddy. Bài học 64 trên 65.

challenge icon

Thử thách

Trung bình

Xây dựng các nhân vật trong một trò chơi nhập vai: lớp trừu tượng Character, ba lớp kế thừa từ lớp này và các kỹ năng mà nhân vật học được.

Character trong character.gd là một lớp @abstract:

  • Thuộc tính: character_name (từ hàm khởi tạo), level 1, max_health và health 100.0, max_mana và mana 50, strength, intelligence và agility 10, defense 5 và abilities, một Array[Ability]. Giá trị sức khỏe là float, các chỉ số khác là int.
  • Tín hiệu defeated(character_name: String).
  • Các phương thức trừu tượng class_title() -> String và attack_power() -> float.
  • level_up() -> String: tăng cấp +1, sức khỏe tối đa +10, mana tối đa +5, sức mạnh, trí thông minh, sự nhanh nhẹn và phòng thủ đều +1; sức khỏe và mana được hồi đầy đến mức tối đa. Trả về NAME reached level N!.
  • attack(target): in ra NAME attacks TARGET, sau đó trả về target.take_damage(attack_power()).
  • take_damage(amount) -> float: sát thương bằng amount - defense * 0.5, nhưng tối thiểu là 1.0; sức khỏe giảm đi lượng sát thương đó và không bao giờ thấp hơn 0.0. Phương thức in ra NAME takes D damage (HP H) với mỗi số có một chữ số thập phân, phát tín hiệu defeated khi đòn đánh này làm sức khỏe giảm xuống 0, rồi trả về lượng sát thương.
  • is_alive(): sức khỏe lớn hơn 0. learn_ability(ability) thêm vào abilities.
  • use_ability(index, target) -> float: nếu chỉ số nằm ngoài phạm vi của abilities, in ra NAME has no ability INDEX và trả về 0.0; nếu không, trả về giá trị mà use() của kỹ năng trả về.
  • _to_string(): NAME the TITLE (level L): HP H/MAX, mana M/MAX, STR S, INT I, AGI A, DEF D, sức khỏe có một chữ số thập phân.

Mỗi lớp con gọi hàm khởi tạo của lớp cha, sau đó đặt các chỉ số khởi đầu riêng (các chỉ số còn lại giữ nguyên giá trị của lớp cơ sở), trả về tên lớp từ class_title() và ghi đè level_up() bằng super():

  • Warrior: sức khỏe 150.0, mana 30, sức mạnh 15, trí thông minh 5, phòng thủ 8; sức tấn công strength * 1.2; khi lên cấp, tăng thêm sức mạnh +2 và sức khỏe tối đa +10 (hồi đầy sức khỏe).
  • Mage: sức khỏe 80.0, mana 150, sức mạnh 5, trí thông minh 20, phòng thủ 3; sức tấn công intelligence * 0.4; sau một đòn tấn công thông thường, hồi lại 5 mana (không vượt quá mức tối đa); khi lên cấp, tăng thêm trí thông minh +2 và mana tối đa +15 (hồi đầy mana).
  • Rogue: sức khỏe 100.0, mana 60, sức mạnh 12, trí thông minh 8, sự nhanh nhẹn 18, phòng thủ 4; sức tấn công strength * 0.5 + agility * 0.7; khi lên cấp, tăng thêm sự nhanh nhẹn +2.

Ability trong ability.gd: hàm khởi tạo nhận ability_name, mana_cost (int) và damage (float). use(user, target) -> float in ra USER does not have enough mana for ABILITY và trả về 0.0 khi mana của người dùng thấp hơn mức tiêu hao. Nếu không, phương thức trừ mana, in ra USER casts ABILITY on TARGET và trả về target.take_damage(damage + user.intelligence * 0.5).

Code được cung cấp kết nối với tín hiệu defeated của từng nhân vật và in ra NAME is defeated!. Với đầu vào này:

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

đầu ra là:

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

Đặt code của bạn trong character.gd, warrior.gd, mage.gd, rogue.gd và ability.gd. main.gd chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.

Tự làm thử

extends Node

func _ready():
	# Đoạn code đầu vào/đầu ra đã có sẵn: giữ nguyê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()

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch GDScript online