小新的技术天地

Make It Works !

博客园 首页 新随笔 联系 订阅 管理
 

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


using System;

enum MoveRequestType {FastForward, SlowForward, Reverse};

class MoveRequestEventArgs : EventArgs
{
    
private MoveRequestType request;

    
public MoveRequestEventArgs(MoveRequestType initRequest) : base()
    
{
        request 
= initRequest;
    }

    
    
public MoveRequestType Request
    
{
        
get
        
{
            
return request;
        }

    }

}


class Car
{
    
private int distance;
    
private int speedParam;
    
private string name;
    
    
public Car(int initSpeedParam, string initName)
    
{
        speedParam 
= initSpeedParam;
        distance 
= 0;
        name 
= initName;
    }

    
    
public void Subscribe(GameController controller)
    
{
        controller.OnMoveRequest 
+= new GameController.MoveRequest(MoveRequestHandler);
    }

    
    
public void Unsubscribe(GameController controller)
    
{
        controller.OnMoveRequest 
-= new GameController.MoveRequest(MoveRequestHandler);
    }

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

    }

    
    
public override string ToString()
    
{
        
return name;   
    }
 
}


class GameController
{
    
public delegate void MoveRequest(object sender, MoveRequestEventArgs e);
    
    
public event MoveRequest OnMoveRequest;
    
    Car[] gameCars 
= new Car[10];
    
string carName;
    
int speedParam = 0;
    
int carCounter = 0;
    
int carNumber = 0;
    
    
public void Run()
    
{
        
string answer;
        Console.WriteLine(
"Please select from the following menu: ");
        Console.WriteLine(
"A)dd new car");
        Console.WriteLine(
"C)ar. Subscribe to events");
        Console.WriteLine(
"U)nsubscribe from events");
        Console.WriteLine(
"L)ist cars in current game");
        Console.WriteLine(
"F)ast forward");
        Console.WriteLine(
"S)low forward");
        Console.WriteLine(
"R)everse");
        Console.WriteLine(
"T)erminate");

        
do
        
{
            Console.WriteLine(
"Select new option:");
            answer 
= Console.ReadLine().ToUpper();
            
            
switch(answer)
            
{
                
case "A":
                    Console.Write(
"Enter name of the new car: ");
                    carName 
= Console.ReadLine();
                    Console.Write(
"Enter car speed parameter of the new car: ");
                    speedParam 
= Convert.ToInt32(Console.ReadLine());
                    gameCars[carCounter] 
= new Car(speedParam, carName);
                    carCounter
++;
                
break;
                
case "C":
                    Console.Write(
"Enter array index of car you want to subscribe to events: ");
                    carNumber 
= Convert.ToInt32(Console.ReadLine());
                    gameCars[carNumber].Subscribe(
this);
                
break;
                
case "U":
                    Console.Write(
"Enter array index of car you want to unsubscribe from events: ");
                    carNumber 
= Convert.ToInt32(Console.ReadLine());
                    gameCars[carNumber].Unsubscribe(
this);
                
break;
                
case "L":
                    
for(int i=0; i < carCounter; i++)
                    
{
                        Console.WriteLine(gameCars[i]);
                    }

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

        }
 while(answer != "T");
    }

}


class Tester
{
    
public static void Main()
    
{
        GameController controller 
= new GameController();
        controller.Run();
    }

}

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

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

后面的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》
 

posted on 2004-11-23 16:17  小新0574  阅读(2014)  评论(3编辑  收藏  举报