Menu
CoddyTech

Hệ thống 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 Dart của Coddy. Bài học 109 trên 110.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống nhân vật trong game kết hợp tất cả các khái niệm OOP bạn đã nắm vững! Bạn sẽ tạo các lớp nhân vật khác nhau với kỹ năng, chỉ số và cơ chế chiến đấu riêng, mô phỏng cách các nhân vật có thể hoạt động trong một game thực tế.

Hệ thống của bạn sẽ được tổ chức trong sáu tệp:

  • character.dart: Tạo một lớp trừu tượng Character làm nền tảng cho mọi loại nhân vật. Mỗi nhân vật có name (String), _health (int) riêng tư, attackPower (int) và defense (int). Thêm getter cho health và các phương thức sau:
    • takeDamage(int damage) - giảm health theo damage - defense (lượng sát thương nhận vào tối thiểu là 1, health không thể thấp hơn 0). In ra name takes X damage! Health: Y
    • bool isAlive() - trả về true nếu health lớn hơn 0
    • Một phương thức trừu tượng String attack() mà các lớp con triển khai để tạo phong cách tấn công riêng
    Ghi đè toString() để trả về name [Class] - HP: health, ATK: attackPower, DEF: defense, trong đó Class lấy từ runtimeType.
  • abilities.dart: Tạo hai mixin cung cấp các kỹ năng đặc biệt:
    • CanHeal - cung cấp phương thức heal(int amount). Vì mixin không thể truy cập trực tiếp các trường riêng tư, mixin này nên định nghĩa phương thức trừu tượng void restoreHealth(int amount) để lớp nhân vật triển khai. Phương thức heal() gọi restoreHealth(amount) và in ra name heals for amount HP!
    • CanCastSpells - cung cấp int mana (mặc định là 100) và phương thức castSpell(String spellName, int manaCost), giảm mana nếu đủ, in ra name casts spellName! rồi trả về true. Nếu không đủ mana, in ra Not enough mana! và trả về false.
  • warrior.dart: Tạo lớp Warrior kế thừa Character. Các Warrior là những đấu sĩ chịu đòn với khả năng phòng thủ cao. Khởi tạo với 150 health, 20 attack power và 15 defense. Triển khai attack() để trả về name swings a mighty sword!
  • mage.dart: Tạo lớp Mage kế thừa Character và sử dụng các mixin CanCastSpells và CanHeal. Mage yếu ớt nhưng mạnh mẽ. Khởi tạo với 80 health, 35 attack power và 5 defense. Triển khai attack() để trả về name hurls a fireball!. Triển khai restoreHealth(int amount) để tăng health (tối đa là 80).
  • archer.dart: Tạo lớp Archer kế thừa Character. Archer là những đấu sĩ cân bằng. Khởi tạo với 100 health, 25 attack power và 10 defense. Triển khai attack() để trả về name fires a precise arrow!
  • main.dart: Minh họa hệ thống nhân vật bằng cách tạo một nhân vật thuộc mỗi loại: một Warrior tên là Thorin, một Mage tên là Gandalf và một Archer tên là Legolas. In ra từng nhân vật bằng toString(). Sau đó mô phỏng một trận chiến theo trình tự:
    1. In ra thông báo tấn công của Thorin
    2. Gandalf nhận 30 sát thương
    3. Gandalf dùng phép Healing Light (tốn 25 mana)
    4. Gandalf hồi 20 HP
    5. In ra thông báo tấn công của Gandalf
    6. Thorin nhận 40 sát thương
    7. In ra thông báo tấn công của Legolas
    8. In ra trạng thái sống của từng nhân vật theo định dạng: name alive: true/false

Đầu ra mong đợi:

Thorin [Warrior] - HP: 150, ATK: 20, DEF: 15
Gandalf [Mage] - HP: 80, ATK: 35, DEF: 5
Legolas [Archer] - HP: 100, ATK: 25, DEF: 10
Thorin swings a mighty sword!
Gandalf takes 25 damage! Health: 55
Gandalf casts Healing Light!
Gandalf heals for 20 HP!
Gandalf hurls a fireball!
Thorin takes 25 damage! Health: 125
Legolas fires a precise arrow!
Thorin alive: true
Gandalf alive: true
Legolas alive: true

Tự làm thử

import 'warrior.dart';
import 'mage.dart';
import 'archer.dart';

void main() {
  // TODO: Tạo một Warrior tên là "Thorin"

  // TODO: Tạo một Mage tên là "Gandalf"

  // TODO: Tạo một Archer tên là "Legolas"

  // TODO: In ra từng nhân vật bằng toString()

  // TODO: Mô phỏng trình tự trận đấu:
  // 1. In ra thông báo tấn công của Thorin
  // 2. Gandalf chịu 30 sát thương
  // 3. Gandalf dùng phép "Healing Light" (tốn 25 mana)
  // 4. Gandalf hồi 20 HP
  // 5. In ra thông báo tấn công của Gandalf
  // 6. Thorin chịu 40 sát thương
  // 7. In ra thông báo tấn công của Legolas
  // 8. In ra trạng thái còn sống của từng nhân vật: "name alive: true/false"
}

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 Dart online