游戏事件编辑器初步分析与实现(1)

引言

事件是游戏中不可缺少的一部分,它增添了游戏的大部分剧情,并且使游戏表达的更为生动。事件,特别是在RPG游戏中,是大量的存在的,如果一个一个去写,显然是非常浪费时间的,于是事件编辑器得以产生。

正文

事件编辑器是什么,在我看来它是对事件的概括与具体。说它概括与具体看起来是矛盾,但其实不是。概括是因为它总结了大量的事件,进行抽象的分类,把相同的事件概括为一类。说他具体,又是因为与事件相关的对象是具体的,每个事件都有独立的对象来参与。

要分析事件编辑器,那么先来分析一下事件:

引用网上的一个例子:花园里有一条狗,一个人 进入 花园,如果进入的人 不是 狗的主人,那么 。这就是一个很简单的事件。

那么这个事件可以分为事件(一个人进入花园)、条件(人是不是主人)以及行为(狗咬人)3个部分。

在计算机中我们可以将斜体的部分(即动作),看做是函数,而下划线的部分(即对象)看做是函数的参数。这样就有了事件在计算机中的描述。

构造以下3个函数:

bool enters(Man man,Region region);

bool is(Man man,Man man);

void attack(Unit unit,Man m);

在这里将Unit与Man分做了两类,其实大部分情况可以分为一类;并且实际操作中可能函数的参数是引用或指针类型。

接下来就利用这3个函数来描述这个事件:

Man m;

Unit dog; //假设Unit有个属性为master,类型为Man

Region r;

...初始化省略

//事件如下

if(enters(m,r))

if(is(m,dog.master))

attack(dog,m)

这样就完成了一个事件的叙述,是不是很简单。

简单代码如下:#include #include #include using namespace std; struct Man{ int pos; //位置 int ID; int HP; Man() { pos=0; ID=0; HP=100; } bool equals(Man p) { if(ID==p.ID) return true; return false; } }; struct Unit{ Man master; }; struct Region{ int rl,rr; }; //rl,rr表示region bool enters(Man m,Region r) { if(r.rl0) { p.pos=rand()%20; p.ID=rand()%2; cout << "Pos:" << p.pos << endl; if(enters(p,r)) { cout << "A man enters the gardon" << endl; if(!is(p,dog.master)) { cout << "The man " << p.ID << " is not the dog's master" << endl; attack(dog,p); cout << "Attack m" << endl; } else { cout << "The man" << p.ID << " is the dog's master" << endl; cout << "Don't attack m" << endl; } } else { cout << "No one enters" << endl; } cout << "HP" << p.HP << endl; cout << endl; Sleep(3000); } cout << m.ID << "is dead." << endl; } 

记住这仅仅是一个事件,如果用这种方法来把游戏中所有的事件一个个写出来的话,我不知道在当今游戏内容如此丰富的时代,有哪个程序员坎此重任。

而事件编辑器可以大大减少成本:

上面介绍的例子其实是一个具体事件,这仅仅是事件编辑器的一部分,而另一个部分就是抽象。

试想,每次有人进入花园,都要去写这么一个事件是多么麻烦的事情,能不能把工作变简单一点。其实计算机很适合做这样的事--重复。

接下来进行抽象部分,一个事件可以分为3个部分,事件,条件跟动作,那么就编写下面3个函数:

bool Event();

bool Condition();

void Action();

暂时不写参数。

写好这3个函数之后,怎么来进行使用呢?

很简单:

if(Event())

if(Condition())

Action()

但是怎么知道是哪个事件呢?或者说是哪种类型的事件呢?

我想的方法是用函数指针:

例如还是上面那个例子,我们怎么让Event确定为enter事件呢?

接下来就该补充Event函数的参数了:

按照bool enters(Man man,Region region)的来写,有两个参数,

bool Event(Man man,Region region,bool (*f)(Man man,Region region))

{

return (*f)(man,region);

}

放在代码中如下:

#include #include #include using namespace std; struct Man{ int pos; //位置 int ID; int HP; Man() { pos=0; ID=0; HP=100; } bool equals(Man p) { if(ID==p.ID) return true; return false; } }; struct Unit{ Man master; }; struct Region{ int rl,rr; }; //rl,rr表示region bool enters(Man m,Region r) { if(r.rl0) { p.pos=rand()%20; p.ID=rand()%2; cout << "Pos:" << p.pos << endl; if(Event(p,r,enters)) { cout << "A man enters the gardon" << endl; if(!is(p,dog.master)) { cout << "The man " << p.ID << " is not the dog's master" << endl; attack(dog,p); cout << "Attack m" << endl; } else { cout << "The man" << p.ID << " is the dog's master" << endl; cout << "Don't attack m" << endl; } } else { cout << "No one enters" << endl; } cout << "HP" << p.HP << endl; cout << endl; Sleep(3000); } cout << m.ID << "is dead." << endl; } 

这样就实现了Event事件的调用。Condition和Action函数可以采用相同的方法进行编写,这里就不在叙述。

 

如果仅仅对这一类的事件进行处理,那么还是不够的。事件编辑器应该能对不同类型的事件进行处理。

如何响应不同类型的事件呢?我这里采用了重构,即编写不同类型的函数,然后对Event重载。

例如,Event可以响应带一个参数的函数 bool Event(Man m,bool (*f)(Man m);

这样对不同类型的事件进行重载之后。基本的事件集合也就写好了。

然后就是怎么处理事件的问题了~~

如何加入一个事件,如何删除一个事件等等~该部分还没想好 等下次再说~

你可能感兴趣的:(游戏开发,游戏,struct,equals,action,hp,工作)