从零开发游戏需要学习的c#模块,第八章(简单的战斗系统)
实战:完整的击杀事件系统
我们来做一套完整的系统,让你彻底理解事件的用法。
步骤一:创建 Enemy.cs,定义敌人基类和事件
using System;
namespace MyGame
{
class Enemy
{
public string name;
private int hp;
public int Hp
{
get { return hp; }
set
{
if (value < 0) hp = 0;
else hp = value;
}
}
public int attackPower;
// ★ 核心:定义一个事件。当敌人死亡时触发
public event Action<Enemy> OnEnemyKilled;
public Enemy(string enemyName, int enemyHp, int enemyAttack)
{
name = enemyName;
Hp = enemyHp;
attackPower = enemyAttack;
}
public void TakeDamage(int damage)
{
Hp = Hp - damage;
Console.WriteLine(name + " 受到了" + damage + "点伤害!剩余HP:" + Hp);
if (Hp <= 0)
{
Die();
}
}
private void Die()
{
Console.WriteLine(name + " 被消灭了!");
// ★ 触发事件!通知所有订阅者
// 先检查事件是否为 null(有没有人订阅)
if (OnEnemyKilled != null)
{
OnEnemyKilled(this); // this 就是当前这个敌人对象
}
}
public virtual void Attack()
{
Console.WriteLine(name + " 发动攻击,造成" + attackPower + "点伤害!");
}
}
}
注意
-
public event Action<Enemy> OnEnemyKilled;:定义了一个事件,它带一个Enemy参数,告诉订阅者“谁被杀了”。 -
if (OnEnemyKilled != null):必须检查!如果没人订阅,事件是 null,直接调用会报错。 -
OnEnemyKilled(this):触发事件,把当前敌人对象传出去。
步骤二:创建三个独立的系统,各自订阅事件
AchievementSystem.cs —— 成就系统
using System;
using System.Collections.Generic;
namespace MyGame
{
class AchievementSystem
{
private int killCount = 0;
private List<string> unlockedAchievements = new List<string>();
// 这个方法签名必须和 Action<Enemy> 匹配:无返回值,一个 Enemy 参数
public void OnEnemyKilled(Enemy enemy)
{
killCount++;
Console.WriteLine("[成就系统] 累计击杀:" + killCount);
if (killCount >= 5 && !unlockedAchievements.Contains("新手杀手"))
{
unlockedAchievements.Add("新手杀手");
Console.WriteLine("🏆 解锁成就:新手杀手!");
}
if (killCount >= 10 && !unlockedAchievements.Contains("屠戮者"))
{
unlockedAchievements.Add("屠戮者");
Console.WriteLine("🏆 解锁成就:屠戮者!");
}
}
}
}
SoundSystem.cs —— 音效系统
using System;
namespace MyGame
{
class SoundSystem
{
public void OnEnemyKilled(Enemy enemy)
{
// 根据敌人名字播放不同音效(这里用打印模拟)
if (enemy.name.Contains("史莱姆"))
{
Console.WriteLine("[音效系统] 🔊 噗叽!");
}
else
{
Console.WriteLine("[音效系统] 🔊 啊——!");
}
}
}
}
QuestSystem.cs —— 任务系统
using System;
namespace MyGame
{
class QuestSystem
{
private int slimeKillCount = 0;
private int requiredKills = 3;
public void OnEnemyKilled(Enemy enemy)
{
if (enemy.name.Contains("史莱姆"))
{
slimeKillCount++;
Console.WriteLine("[任务系统] 击杀史莱姆进度:" + slimeKillCount + "/" + requiredKills);
if (slimeKillCount >= requiredKills)
{
Console.WriteLine("[任务系统] ✅ 任务完成:讨伐史莱姆!");
}
}
}
}
}
步骤三:在 Main 里把它们串起来
Program.cs:
using System;
using System.Collections.Generic;
namespace MyGame
{
class Program
{
static void Main(string[] args)
{
// 1. 创建三个独立系统
AchievementSystem achievement = new AchievementSystem();
SoundSystem sound = new SoundSystem();
QuestSystem quest = new QuestSystem();
// 2. 生成一堆敌人
List<Enemy> enemies = new List<Enemy>();
for (int i = 1; i <= 12; i++)
{
Enemy slime = new Enemy("绿色史莱姆" + i, 20, 5);
// ★ 核心:把各个系统的方法订阅到敌人死亡事件上
slime.OnEnemyKilled += achievement.OnEnemyKilled;
slime.OnEnemyKilled += sound.OnEnemyKilled;
slime.OnEnemyKilled += quest.OnEnemyKilled;
enemies.Add(slime);
}
Console.WriteLine("=== 开始战斗 ===\n");
// 3. 依次击杀所有敌人
foreach (Enemy enemy in enemies)
{
Console.WriteLine("--- 遭遇 " + enemy.name + " ---");
// 攻击直到死亡
while (enemy.Hp > 0)
{
enemy.TakeDamage(10); // 每次打10点伤害
}
Console.WriteLine();
}
Console.WriteLine("=== 所有敌人已消灭 ===\n");
Console.ReadKey();
}
}
}
📊 运行效果预览

-
Enemy类完全不知道成就、音效、任务的存在。 -
它只管在死亡时触发事件。
-
各个系统独立存在,互不干扰。
-
将来要加新系统(如统计面板),只需写一个新类并订阅事件,无需修改任何现有代码。
这就是解耦,是制作大型游戏的核心架构思想。
明白了吗?
关注我,下一期更精彩。
更多推荐
所有评论(0)