- 最后登录
- 2019-12-25
- 注册时间
- 2012-8-24
- 阅读权限
- 90
- 积分
- 71088
- 纳金币
- 52336
- 精华
- 343
|
用过魔兽争霸编辑器的同学都知道 用 T 可以对魔兽争霸游戏进行触发事件
至于 Jass 就是纯代码了 这里不深究
例如 :
事件 : 单位被攻击
条件 : 被攻击者 的所有者 是 玩家 1
动作 : 攻击者的生命值 -10
这种思想我一直觉得在全局上的把控比较好 只需在另一个地方编辑事件 而不用在现有设计好的代码中添加或更改
这种触发器不用说 一定和事件有关 而且满地都是事件
所以为了运用这个思想 转换成了 c# 代码 简单的模拟
设计上吗 主体就是事件系统 在每个单位上绑定事件 每个单位都会发送事件到事件管理处 在事件管理处进行全局控制
其中 为了简化代码 在初始化中用了反射
话不多说 代码放上 模拟刚才的例子:- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Threading.Tasks;
- namespace TriggerTest
- {
- class Program
- {
- static void Main(string[] args)
- {
- List<Trigger> triggerList = new List<Trigger>();
- //模拟一个触发:主角被攻击的时候 如果主角生命值在 200 以下 那么对攻击者进行伤害 数值为真实伤害 10
- EventStart eventS = new EventStart(0, EventStartType.Unit_BeHurt);
- EventCondition eventC = new EventCondition(0, EventConditionType.Unit_Health, () =>
- {
- Player p = eventS.eventSender as Player;
- return p.name == "player" && p.health < 200;
- });
- EventOperation eventO = new EventOperation(0, EventOperationType.Unit_DamageUnits, () =>
- {
- (eventS.eventRelationer as Player).health -= 10;
- });
- TriggerManager.Instance.AddTrigger(new Trigger(eventS, eventC, eventO));
- //designer
- Player player = new Player("player", 11, 100);
- Player enemy = new Player("enemy", 20, 100);
- TriggerManager.Instance.BindEvent(player);
- enemy.AttackTarget(player);
- Console.WriteLine($"{enemy.health}");
- }
- }
- public class Player
- {
- public event Action<object, object> Unit_BeHurt;
- public string name;
- public float attack;
- public float health;
- public Player(string name, float attack, float health)
- {
- this.name = name;
- this.attack = attack;
- this.health = health;
- }
- public void BeHurt(int damage, object attacker)
- {
- Unit_BeHurt?.Invoke(this, attacker);
- this.health -= damage;
- }
- public void AttackTarget(Player emp)
- {
- emp.BeHurt((int)this.attack, this);
- }
- }
- public class Trigger
- {
- public EventStart start;
- public EventCondition condition;
- public EventOperation operation;
- public Trigger(EventStart start, EventCondition condition, EventOperation operation)
- {
- this.start = start;
- this.condition = condition;
- this.operation = operation;
- start.trigger = this;
- condition.trigger = this;
- operation.trigger = this;
- }
- }
- public enum EventStartType
- {
- Time_TimeOver,
- Unit_BeHurt,
- }
- public enum EventConditionType
- {
- Unit_Health,
- }
- public enum EventOperationType
- {
- Unit_DamageUnits,
- Unit_ChangeHealth,
- }
- public class EventStart
- {
- public Trigger trigger;
- public int id;
- public EventStartType type;
- public object eventSender;//事件发起者
- public object eventRelationer;//事件关系者
- public EventStart(int id, EventStartType type)
- {
- this.id = id;
- this.type = type;
- }
- }
- public class EventCondition
- {
- public Trigger trigger;
- public int id;
- public EventConditionType type;
- public Func<bool> conditionFunc;
- public EventCondition(int id, EventConditionType type, Func<bool> func)
- {
- this.id = id;
- this.type = type;
- conditionFunc = func;
- }
- public bool IsTrue()
- {
- return conditionFunc == null ? false : conditionFunc();
- }
- }
- public class EventOperation
- {
- public Trigger trigger;
- public int id;
- public EventOperationType type;
- public Action action;
- public EventOperation(int id, EventOperationType type, Action action)
- {
- this.id = id;
- this.type = type;
- this.action = action;
- }
- public object[] Run()
- {
- action?.Invoke() ;
- return null;
- }
- }
- public class TriggerManager
- {
- private static TriggerManager instance;
- public Dictionary<EventStartType, List<Trigger>> dic = new Dictionary<EventStartType, List<Trigger>>();
- public static TriggerManager Instance
- {
- get
- {
- if (instance == null)
- {
- instance = new TriggerManager();
- }
- return instance;
- }
- set => instance = value;
- }
- private TriggerManager()
- {
- dic.Add(EventStartType.Time_TimeOver, new List<Trigger>());
- dic.Add(EventStartType.Unit_BeHurt, new List<Trigger>());
- }
- public void AddTrigger(Trigger t)
- {
- dic[t.start.type].Add(t);
- }
- //监听 单位事件 只要是 Player 类 都可以绑定 (这里可以用反射 可以将所有类都可以用这个绑定函数 前提是保证这个类中有该事件)
- public void BindEvent(Player player)
- {
- var events = player.GetType().GetEvents();
- foreach (var child in events)
- {
- child.AddEventHandler(player, new Action<object, object>((sender, relations) =>
- {
- var eventStartType = (EventStartType)Enum.Parse(typeof(EventStartType), child.Name);
- SendEvent(eventStartType, sender, relations);
- }));
- }
- }
- public void SendEvent(EventStartType eventType, object sender, object relations)
- {
- List<Trigger> list = dic[eventType];
- list.ForEach(e =>
- {
- e.start.eventSender = sender;
- e.start.eventRelationer = relations;
- if (e.condition.IsTrue())
- {
- e.operation.Run();
- }
- });
- }
- }
-
- }
复制代码 在枚举中增加事件类型 在单位中事件也要创建 名称要一样
这样 几行代码就可以创建一个触发器
之后的时间里 可能会写一个运用这个模拟 简单AI战斗 的脚本 AI处只需写逻辑和事件 其他的都交由触发器来完成 先立个 flag 。。。
來自: 随幻Kaller
|
|