从零开发游戏需要学习的c#模块,第七章(委托与事件,上)
假设你在做一个 RPG 游戏,有以下系统:
-
战斗系统:玩家杀死敌人时,要播放击杀特效
-
成就系统:累计击杀数达标时,解锁成就
-
音效系统:击杀时要播放音效
-
任务系统:击杀特定敌人时,更新任务进度
如果不用事件,你的击杀代码会变成这样:
void KillEnemy()
{
// 击杀逻辑...
PlayKillEffect(); // 特效
PlayKillSound(); // 音效
achievement.Check(); // 成就
quest.Update(); // 任务
}
问题:战斗系统需要知道所有其他系统的存在。每加一个新系统(比如统计面板),就要改战斗代码。这违反了封装原则,代码会越来越臃肿。
解决方案:战斗系统只负责广播一条消息——“敌人被杀了!”。谁关心这条消息,谁自己来订阅。这就是事件的威力。
1. 委托——方法的“快递单”
在理解事件之前,必须先理解委托。
比喻:委托就像一张“快递单”,上面写着收件地址(方法的签名)。你可以把这张单子交给任何人,让他按照地址去送货(调用方法)。
通俗定义:委托是一个变量,但它存的不是数据,而是方法的地址。
定义和使用委托
// 定义一个委托类型:可以指向“无参数、无返回值”的方法
delegate void SimpleDelegate();
class Program
{
static void SayHello()
{
Console.WriteLine("你好!");
}
static void SayGoodbye()
{
Console.WriteLine("再见!");
}
static void Main(string[] args)
{
// 创建委托实例,绑定 SayHello 方法
SimpleDelegate myDelegate = SayHello;
// 通过委托调用方法
myDelegate(); // 输出:你好!
// 重新绑定到另一个方法
myDelegate = SayGoodbye;
myDelegate(); // 输出:再见!
Console.ReadKey();
}
}
关键点:
-
myDelegate是一个变量,存的是方法的地址。 -
你可以随时换绑,让它指向不同的方法。
-
调用委托
myDelegate()时,它去执行当前绑定的方法。
2. 多播委托——一个快递单,多个收件人
委托可以一次绑定多个方法,调用时所有方法都会执行。这就叫多播委托。
delegate void NotifyDelegate();
class Program
{
static void MethodA() { Console.WriteLine("A 执行了"); }
static void MethodB() { Console.WriteLine("B 执行了"); }
static void MethodC() { Console.WriteLine("C 执行了"); }
static void Main(string[] args)
{
NotifyDelegate notifier = MethodA;
notifier += MethodB; // 用 += 添加方法
notifier += MethodC; // 再添加一个
notifier(); // 三个方法都会执行!
// 输出:
// A 执行了
// B 执行了
// C 执行了
Console.WriteLine("\n移除 B 后:");
notifier -= MethodB; // 用 -= 移除方法
notifier();
// 输出:
// A 执行了
// C 执行了
Console.ReadKey();
}
}
核心操作:
-
+=:把方法“订阅”到委托上 -
-=:把方法“取消订阅” -
调用委托时,所有订阅的方法按添加顺序依次执行
3. 事件——安全的广播系统
事件是对委托的封装。委托太自由了——外部代码可以直接把委托设为 null,或者直接调用它。事件则加了保护:
-
外部只能用
+=和-=来订阅/取消订阅 -
外部不能直接调用事件
-
外部不能把事件设为
null
语法:在委托类型前加 event 关键字。
// 定义一个事件
public event Action OnSomethingHappened;
Action 是什么?
C# 内置了一些泛型委托类型,不用你自己定义:
-
Action:无参数、无返回值 -
Action<int>:一个 int 参数、无返回值 -
Action<string, int>:两个参数、无返回值 -
Func<int>:无参数、返回 int -
Func<string, int>:string 参数、返回 int
游戏开发中,Action 是最常用的事件委托类型。
关注我,下期更精彩
(预告下期内容,简单的实战练习)
更多推荐
所有评论(0)