用一个汽车游戏的例子来介绍一下事件(Event)

 

这次的代码更恐怖,一个字 长,二个字 够长,三个子 真是长,哈哈,不过你仔细研究一下还挺有意思的:)


None.gif using  System;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
enum  MoveRequestType  dot.gif {FastForward, SlowForward, Reverse} ;
None.gif
None.gif
class  MoveRequestEventArgs : EventArgs
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private MoveRequestType request;
InBlock.gif
InBlock.gif    
public MoveRequestEventArgs(MoveRequestType initRequest) : base()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        request 
= initRequest;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
public MoveRequestType Request
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
get
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return request;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
class  Car
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private int distance;
InBlock.gif    
private int speedParam;
InBlock.gif    
private string name;
InBlock.gif    
InBlock.gif    
public Car(int initSpeedParam, string initName)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        speedParam 
= initSpeedParam;
InBlock.gif        distance 
= 0;
InBlock.gif        name 
= initName;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
public void Subscribe(GameController controller)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        controller.OnMoveRequest 
+= new GameController.MoveRequest(MoveRequestHandler);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
public void Unsubscribe(GameController controller)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        controller.OnMoveRequest 
-= new GameController.MoveRequest(MoveRequestHandler);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
public void MoveRequestHandler(object sender, MoveRequestEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
switch (e.Request)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
case MoveRequestType.SlowForward:
InBlock.gif                distance 
+= speedParam;
InBlock.gif                Console.WriteLine(
"Car name: " + name + " Moving slowly. Distance: " + distance);
InBlock.gif            
break;
InBlock.gif            
case MoveRequestType.FastForward:
InBlock.gif                distance 
+= speedParam * 2
InBlock.gif                Console.WriteLine(
"Car name: " + name + " Moving fast. Distance: " + distance);
InBlock.gif            
break;
InBlock.gif            
case MoveRequestType.Reverse:
InBlock.gif                distance 
-= 5;
InBlock.gif                Console.WriteLine(
"Car name: " + name + " Reversing. Distance: " + distance);
InBlock.gif            
break;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
public override string ToString()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return name;   
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}

None.gif
None.gif
class  GameController
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public delegate void MoveRequest(object sender, MoveRequestEventArgs e);
InBlock.gif    
InBlock.gif    
public event MoveRequest OnMoveRequest;
InBlock.gif    
InBlock.gif    Car[] gameCars 
= new Car[10];
InBlock.gif    
string carName;
InBlock.gif    
int speedParam = 0;
InBlock.gif    
int carCounter = 0;
InBlock.gif    
int carNumber = 0;
InBlock.gif    
InBlock.gif    
public void Run()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
string answer;
InBlock.gif        Console.WriteLine(
"Please select from the following menu: ");
InBlock.gif        Console.WriteLine(
"A)dd new car");
InBlock.gif        Console.WriteLine(
"C)ar. Subscribe to events");
InBlock.gif        Console.WriteLine(
"U)nsubscribe from events");
InBlock.gif        Console.WriteLine(
"L)ist cars in current game");
InBlock.gif        Console.WriteLine(
"F)ast forward");
InBlock.gif        Console.WriteLine(
"S)low forward");
InBlock.gif        Console.WriteLine(
"R)everse");
InBlock.gif        Console.WriteLine(
"T)erminate");
InBlock.gif
InBlock.gif        
do
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Console.WriteLine(
"Select new option:");
InBlock.gif            answer 
= Console.ReadLine().ToUpper();
InBlock.gif            
InBlock.gif            
switch(answer)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case "A":
InBlock.gif                    Console.Write(
"Enter name of the new car: ");
InBlock.gif                    carName 
= Console.ReadLine();
InBlock.gif                    Console.Write(
"Enter car speed parameter of the new car: ");
InBlock.gif                    speedParam 
= Convert.ToInt32(Console.ReadLine());
InBlock.gif                    gameCars[carCounter] 
= new Car(speedParam, carName);
InBlock.gif                    carCounter
++;
InBlock.gif                
break;
InBlock.gif                
case "C":
InBlock.gif                    Console.Write(
"Enter array index of car you want to subscribe to events: ");
InBlock.gif                    carNumber 
= Convert.ToInt32(Console.ReadLine());
InBlock.gif                    gameCars[carNumber].Subscribe(
this);
InBlock.gif                
break;
InBlock.gif                
case "U":
InBlock.gif                    Console.Write(
"Enter array index of car you want to unsubscribe from events: ");
InBlock.gif                    carNumber 
= Convert.ToInt32(Console.ReadLine());
InBlock.gif                    gameCars[carNumber].Unsubscribe(
this);
InBlock.gif                
break;
InBlock.gif                
case "L":
InBlock.gif                    
for(int i=0; i < carCounter; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        Console.WriteLine(gameCars[i]);
ExpandedSubBlockEnd.gif                    }

InBlock.gif                
break;
InBlock.gif                
case "F":
InBlock.gif                    
if (OnMoveRequest != null)
InBlock.gif                        OnMoveRequest(
thisnew MoveRequestEventArgs(MoveRequestType.FastForward));
InBlock.gif                
break;
InBlock.gif                
case "S":
InBlock.gif                    
if (OnMoveRequest != null)
InBlock.gif                        OnMoveRequest(
thisnew MoveRequestEventArgs(MoveRequestType.SlowForward));
InBlock.gif                
break;
InBlock.gif                
case "R":
InBlock.gif                    
if (OnMoveRequest != null)
InBlock.gif                        OnMoveRequest(
thisnew MoveRequestEventArgs(MoveRequestType.Reverse));
InBlock.gif                
break;
InBlock.gif                
case "T":
InBlock.gif                
break;
InBlock.gif                
default:
InBlock.gif                    Console.WriteLine(
"Invalid choice. Please try again");
InBlock.gif                
break;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }
 while(answer != "T");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
class  Tester
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        GameController controller 
= new GameController();
InBlock.gif        controller.Run();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

先瞧瞧我们做了什么?一个事件驱动的汽车游戏。当然是简化版13.gif

这个辆汽车能做什么?它目前只能快进,慢进,后退(为了简化的目的)。不过已经够用了。

后面的MoveRequestEventArgs类是用来给预定器(subscriber)(预定器是什么呢,看下去就知道了)传递特定的有关事件信息的。

然后是我们的Car类,三个字段distancespeedparamname,这三个字段在构造函数里进行初始化,然后有一个Subscribe方法用来增加我们需要预定的GameController,而其后的Unsubscribe则反之。

接下去往下看就是我们的事件操作方法(MoveRequestHandler)了,这个我想大家已经很熟悉了,在VS.NET里,我们为一个控件写事件操作方法,就是在这样的一个方法里写。这里我们根据我们得到的Request来做一些事(快进,慢进,后退),这个Request从哪里来呢,就是我们上面写的MoveRequestEventArgs得到的。

在接下来就是重写了ToString方法,返回汽车的名字。

然后就进入我们的GameController类。

我们注意到我们定义了一个MoveRequest的委托,根据它的参数跟返回值,我们可以猜想到它是用来封装Car类里的事件操作方法(MoveRequestHandler)的,然后我们用这个委托声明一个事件OnMoveRequest,跟普通委托不同,这里我们用到了关键字event

然后我们准备了一个最多能有10辆车的数组(难道我们要赛车:)),并准备了一些相关属性。

做完了准备工作,我们就写了一个好长好长的Run方法。

首先打印一个菜单供大家选择,然后等待大家的选择,根据选择,就在do循环里做一些工作了。

选项A:增加一辆车。对了,我们还没有车,肯定要先加一些车才能操作嘛。

选项C:我们要对车做一些事情了,那么么多车,让哪几辆做这些事呢?由你来订吧。

选项U:哦!天哪,我订错了,我不想让那几辆车做这些事了,怎么办呢?没关系,车还没开呢,取消掉刚才预定的车不就行了:)

选项L:列出现在拥有的车。

选项F:订好的车快进!怎么快进?担心什么,事件处理方法会为我们做的,你只要担心做哪些事就行了。

选项S:慢进!

选项R:后退!

选项T:不想玩了,Game Over

 

运行程序!啊?出错了!我们还没Main方法呢,急什么!

那么我们就在写一个Tester类吧,写上Main方法,叫来我们的GameController,开动!



注:1.这个程序还是有一些小bug,也没有考虑异常处理,但是用来说明事件的原理已经够了。
       2.参文代码参考《C# Primer Plus》
 

转载于:https://www.cnblogs.com/wdxinren/archive/2004/11/23/67610.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值