从拳皇97中浅谈C#委托与事件

先看看下列代码:

protected void Page_Load(object sender, EventArgs e)
{

}

protected void btnSearch_Click(object sender, ImageClickEventArgs e)
{

}

是不是很眼熟呢?其中的参数(sender,e)到底是代表的是什么呢?这就要涉及到C#的委托与事件。

 

那我们首先来看一下比较正统的感念吧:

 

事件是类在发生其关注的事情时用来提供通知的一种方式。

 

事件的发生一般都牵扯2个角色

 

事件发行者(Publisher):一个事件的发行者,也称作是发送者(参数:sender),其实就是个对象,这个对象会自行维护本身的状态信息(参数:e),当本身状态信息变动时,便触发一个事件,并通知说有的事件订阅者。

 

事件订阅者(Subscriber):对事件感兴趣的对象,也称为Receiver,可以注册感兴趣的事件,在事件发行者触发一个事件后,会自动执行这段代码。

 

委托就好比:现实生活中的中介机构,比如我们通过租房的中介,我们把租房的需求告诉给他们,然后他们去帮我们去找住所。我们只需要关心自己的能够承担多少的价格或者环境什么之类的,并不参与找房子这个过程.

事件就好比:很多人都去找租房的中介去租房子,根据不同的需求找到了不同的住所,然后同时通知所有的人,让他们去看房子。比如说 张三 李四 王二麻子,他们三兄弟,其中 张三和李四对住房的条件不是很挑剔,王二麻子就很日怪,他就喜欢潮湿一点的房子, 然后他们一起找到了中介公司(发送委托),中介公司了解到了他们的需求,全部都记录在自己的笔记本上(添加事件),以便对自己的房源进行筛选(过滤),最后中介公司分别通知他们去看房子(执行事件)。

所以从本质上来说 :  事件 等价于 委托链

  比如拳皇97中,当我们在控制一个角色的时候,输入不同的有效键位,会出来不同的动作。每一个角色都有自己的技能(类似上面的租房需求),但是什么时候触发这个技能(交给委托,角色自己不关心),就是在我们正确的按键了过后,才能够执行(完成委托).

下面从一个简单的demo中来理解这个概念:(有两个角色 :八神庵,草稚京)

 先定义一个类SkillEventArgs ,用来保存用户输入的状态信息。

///所有订阅者【Subscriber】,也就是e,都要继承微软的EventArgs(这是一种。net的规范)
//本例中订阅者【也称观察者】八神庵,草稚京 他们感兴趣的e对象,就是【action】 ,也就是我们输入的键位保存在这里
    class SkillEventArgs : EventArgs
    {
        public string Action { get; set; }
        public SkillEventArgs(string action)
        {
            this.Action = action;
        }
    }

 

 接着定义一个类Publish,作为中介机构.

// 发布者【Publisher】
    class Publisher
    {
        public delegate void InputKeyboardEventHandler(object sender, SkillEventArgs e); // 定义委托,只处理 观察者感兴趣的e对象,所以作为参数传入.   sender 也就是监视对象,本例中就是Publisher
        public event InputKeyboardEventHandler InputKeyboardEvent;  // 定义事件,保存所有的委托链.

        protected virtual void OnInputKeyboard(SkillEventArgs e)  // 事件只能在方法里触发,这里是触发对应角色的技能输出。
        {
            if (InputKeyboardEvent != null)
            {
                //Sender = this,也就是Publisher
                InputKeyboardEvent(this,e);    
            } 
            //InputKeyboardEvent?.Invoke(this, e);   等价于 上面的代码
        }
        public void UseSkill(string skill)   // 实列对外的函数调用。
        {
            SkillEventArgs skills = new SkillEventArgs(skill);
            OnInputKeyboard(skills);
        }
    }

 

 定义一个抽象类 Person类: 其中有一个字典类型的Skills属性,保存的是触发的组合键,以及对应的技能名称. 还有一个是 UseSkill的抽象方法. 以及继承Person类的 八神类 和 草稚京类

abstract class Person
    {
        public static Dictionary<string, string> Skills { get; set; }
        public abstract void UseSkill(object sender, SkillEventArgs e);
    }

class Iori : Person
    {
        static Iori()
        {
            Skills = new Dictionary<string, string>();
            Skills.Add("k", "百式·鬼燃烧");
        }

        public override void UseSkill(object sender, SkillEventArgs e)
        {
            if (Skills.ContainsKey(e.Action))
            {
                Console.WriteLine(Skills[e.Action]);
            }
            else
            {
                Console.WriteLine("我 八神庵 没有此技能!!");
            }
        }
    }

    class Kyo : Person
    {
        static Kyo()
        {
            Skills = new Dictionary<string, string>();
            Skills.Add("k", "里百八式·大蛇雉");
        }
        public override void UseSkill(object sender, SkillEventArgs e)
        {
            if (Skills.ContainsKey(e.Action))
            {
                Console.WriteLine(Skills[e.Action]);
            }
            else
            {
                Console.WriteLine("我 草稚京 没有此技能!!");
            }
        }
    }

最后在Main函数上输出:

static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("选择你要控制的角色:");
                Console.WriteLine("a:八神庵");
                Console.WriteLine("b:草稚京");
                string role = Console.ReadLine();
                if (role == "a") { Console.WriteLine("正在使用八神庵"); }
                else if (role == "b") { Console.WriteLine("正在使用草稚京"); }
                else { Console.WriteLine("没有此角色"); continue; };
                while (true)
                {
                    Console.WriteLine("请出招:");
                    string skill = Console.ReadLine();
                    Publisher p = new Publisher();
                    if (role == "a")
                    {
                        p.InputKeyboardEvent += new Iori().UseSkill; //绑定事件
                    }
                    else
                    {
                        p.InputKeyboardEvent += new Kyo().UseSkill;
                    }
                    p.UseSkill(skill);
                }
            }
        }

 效果:

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/yezhizhen/p/8467103.html

自己做自己玩 为了好玩才做 namespace KOF { public partial class Form1 : Form { Int32 num; public Form1() { InitializeComponent(); } public Int32 random() { Random r = new Random(); Int32 d1 = r.Next(50); Int32 d2 = r.Next(50); Int32 d3 = r.Next(50); return (d1 + d2 + d3) / 3; } public String KUSANAGI(Int32 i) { if (i == 50) { return "最终决战奥义“无式”"; } if (i >= 45) { return "秘奥义里百八式·大蛇剃"; } if (i >= 40) { return "四百壹式·罪咏"; } if (i >= 35) { return "贰百拾贰式·琴月阳"; } if (i >= 30) { return "七拾七式·独乐屠"; } if (i >= 25) { return "百式·鬼烧"; } if (i >= 20) { return "百拾四式·荒咬"; } if (i >= 15) { return "重拳,重脚"; } if (i >= 10) { return "轻脚,轻拳"; } if (i > 0) { return "八神庵防住了你的招式!"; } else { return "八神庵完美的闪开你的招式!"; } } public String YAGAMI(Int32 i) { if (i == 50) { return "*禁千二百十一式·八稚女: ……哭吧,叫吧,然后就死吧! "; } if (i >= 45) { return "*里百八式·八酒杯: ……每逢看到月亮就会想起我!"; } if (i >= 40) { return "百二十七式·葵花"; } if (i >= 35) { return "二百十二式·琴月阴"; } if (i >= 30) { return "屑风"; } if (i >= 25) { return "百式·鬼燃烧"; } if (i >= 20) { return "百八式·暗勾手"; } if (i >= 15) { return "重拳,重脚"; } if (i >= 10) { return "轻脚,轻拳"; } if (i > 0) { return "草剃京防住了你的招式!"; } else { return "草剃京完美的闪开你的招式!"; } } private void button1_Click(object sender, EventArgs e) { if (Convert.ToInt32(label2.Text) != 0 && Convert.ToInt32(label1.Text) != 0) { if (num == 0) { Int32 r = random(); Int32 l2 = Convert.ToInt32(label2.Text) - r * 10; if (l2 < 0) { progressBar2.Value = 0; label2.Text = Convert.ToString(0); label4.Text = YAGAMI(r); button2.Visible = true; button2.Text = ("八神庵 WIN!"); } else { progressBar2.Value = l2; label2.Text = Convert.ToString(l2); label4.Text = YAGAMI(r); } num++; label5.Text = ""; } else { label5.Text = ("轮到草剃京出手了!"); } } else { MessageBox.Show("已经分出胜负!请进行下一场的比试吧。"); } } private void button3_Click(object sender, EventArgs e) { if (Convert.ToInt32(label2.Text) != 0 && Convert.ToInt32(label1.Text) != 0) { if (num == 1) { Int32 r = random(); Int32 l1 = Convert.ToInt32(label1.Text) - r * 10; if (l1 < 0) { progressBar1.Value = 0; label1.Text = Convert.ToString(0); label4.Text = KUSANAGI(r); button2.Visible = true; button2.Text = ("草剃京 WIN!"); } else { progressBar1.Value = l1; label1.Text = Convert.ToString(l1); label4.Text = KUSANAGI(r); } num--; label5.Text = ""; } else { label5.Text = ("轮到八神庵出手了!"); } } else { MessageBox.Show("已经分出胜负!请进行下一场的比试吧。"); } } private void button2_Click(object sender, EventArgs e) { progressBar1.Value = 1000; progressBar2.Value = 1000; label1.Text = Convert.ToString(1000); label2.Text = Convert.ToString(1000); button1.Visible = true; button2.Visible = false; button3.Visible = true; label4.Visible = true; label4.Text = "go!go!go!"; Random r1 = new Random(); num = (Int32)Math.Round(r1.NextDouble()); if (num == 1) { label5.Text = ("草剃京抢占了先机!"); } else { label5.Text = ("八神庵抢占了先机!"); } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值