当前位置: 代码迷 >> Web前端 >> web对策类游戏开发(二) WebGame事件
  详细解决方案

web对策类游戏开发(二) WebGame事件

热度:547   发布时间:2012-06-29 15:48:47.0
web策略类游戏开发(二) WebGame事件

作者:Yahle
曾用网名:Dogvane
原载:http://www.cnblogs.com/yahle
版权所有。转载时必须以链接形式注明作者和原始出处。
?


1 事件系统

事件系统是整个WebGame系统里一个核心的组成部分,我们用它来控制的进程,让游戏世界里能够24小时运转。

1.1 事件的概念
事件是指游戏里玩家的某个(系列)活动,它可以分为瞬时活动和非瞬时活动。
瞬时活动顾名思义就是在玩家发出指令的瞬间就能完成的活动。像RPG游戏里,玩家从NPC里购买一瓶药水,在玩家发出这个指令后,玩家的金钱减少,并获得药水,这一切都在玩家发出指令后瞬间完成(当然实际逻辑上处理还需要几个ms处理时间)。
而非瞬时活动则是在玩家发出某个指令后一段事件才会被执行。例如RPG里玩家鼠标点击地图上某个地方,游戏角色则会自动行走到刚才点击处。这个移动过程就是一个非瞬时过程,它有了一个移动的过程,这个过程需要消耗一定的时间(玩家能感知的事件)
非瞬时系列活动是指一位或者多位玩家通过一系列的瞬时\非瞬时活动完成一个动作(功能)。例如wow里面的拍卖场,有1位玩家提供道具,同服务器里的其他玩家对该道具进行竞拍。
在WebGame里,玩家的很多操作其实是非瞬时部分事件是村庄资源减少(前提投资),非瞬时事件是建筑物建设,这个动作(同能)的结果是建筑物等级上升。
又比如《Travian》里的攻击,瞬时事件是当前村庄的士兵减少(派出部队),非瞬时事件是减少的士兵移动到需要攻击的村庄(行军过程),动作结束是,两个村庄的部队开打了(战斗)。

1.2 触发器(事件队列)
前面说了瞬时事件和非瞬时事件的概念,当WebGame在24小时运转的时候,系统会产生大量的非瞬时事件,这些非瞬时事件不会在玩家点击页面时执行,而是需要等一段时间后才会执行,因此在游戏里把这些非瞬时事件拿出来,按事件的执行时间进行排序,组成一个事件队列。再通过一个触发器,在事件设定的执行时间到达的那时执行相对应的事件。
这里面就涉及到两个内容:
??非瞬时的事件队列
??事件触发器

1.2.1 事件队列
数据库除了用于存储外,其查询功能也非常强大,直接拿来做事件队列很合适。事件队列里通常保存事件涉及的对象(村庄),结束时间、事件类型以及事件相关参数等。
下表为我们系统里使用的事件表:

?

ID

int

VillageCode

int

TargetVillageCode

int

Type

int

EndTime

DateTime

EventObject

ntext

保存时将这些对象做xml序列化保存到EventObject字段里。当然如果为了效率还可以存储二进制序列化后的对象,这样在序列化以及反序列化时能节省大部分时间。

1.2.2 触发器
Asp.net
Asp.net的处理在触发器上的处理就比较简单了。在服务器程序启动的时候,就执行一个线程,定时(1s)从数据库里取结束时间<当前事件的事件进行处理。

?1????????///?<summary>
?2????????///?事件处理线程
?3????????///?每间隔1s处理一次到时间了的事件
?4????????///?</summary>

?5????????static?void?EventThread()
?6????????{
?7????????????DateTime?lastTime?=?DateTime.Now;
?8????????????while?(Run)
?9????????????{
10????????????????try
11????????????????{
12????????????????????Event.SystemEvent.DoEvent(lastTime);
13????????????????}

14????????????????catch?(Exception?ex)
15????????????????{
16????????????????????Common.Logging.Error(ex.ToString());
17????????????????}

18
19????????????????long?def?=?DateTime.Now.Ticks?-?lastTime.Ticks;
20????????????????lastTime?=?DateTime.Now;
21
22????????????????if?(def?<?10000000)
23????????????????{
24????????????????????//??线程休息,并等待下一次时间间隔
25????????????????????int?ms?=?(int)(10000000?-?def)?/?10000;
26????????????????????if?(ms?>?0)
27????????????????????????System.Threading.Thread.Sleep(ms);
28????????????????}

29????????????}

30????????}

31

?1??///?<summary>
?2????///?系统事件
?3????///?主要作用是执行处理事件的过程
?4????///?</summary>

?5????public?class?SystemEvent
?6????{
?7????????public?static?void?DoEvent(DateTime?time)
?8????????{
?9????????????List<Event>?evs?=?Event.GetEvents(time);
10????????????foreach?(Event?e?in?evs)
11????????????{
12????????????????try
13????????????????{
14????????????????????IEvent?ie?=?e.Object;
15????????????????????if?(ie?!=?null)
16????????????????????{
17????????????????????????ie.Parent?=?e;
18????????????????????????ie.DoEvent();
19????????????????????}

20????????????????}

21????????????????catch?(Exception?ex)
22????????????????{
23????????????????????Common.Logging.Error(ex.ToString(),?e.EventObject);
24????????????????}

25????????????????try
26????????????????{
27????????????????????e.Delete();????//?从数据库里删除信息
28????????????????}

29????????????????catch?(Exception?ex)
30????????????????{
31????????????????????Common.Logging.Error(ex.ToString());
32????????????????}

33????????????}

34????????}

35????}

36


php
PHP没用过,不过好像不能在PHP页面里无法创建线程,用纯PHP服务端来实现触发器估计有点难度。但是可以做成一个PHP的应用程序,由应用程序来实现触发器。

1.3 游戏资源的24小时自动增长
游戏资源的24小时自动增长,这是一个有趣的话题,很多刚开始设计WebGame的朋友都会在这个问题上卡一下。每个人对于如何实现这个功能都有自己的独到见解,我在这里就不能给出一个唯一的答案,这里给的解决方案只是自己正在做的WebGame用到的方案。
首先,我们否定了每个时间间隔(10分钟)就执行更新村庄资源的设计,这即不准确,同时也很消耗服务器资源。所以,我们的系统就只有在用户执行事件(瞬时的和非瞬时)的时候才将新的资源信息写入数据库。平时显示资源的时候用?
(当前时间 - 上一次更新事件)*资源每小时产量+上一次更新产量
公式计算出当前资源并显示在页面上。也就是说,每次页面更新时重新计算资源,但只只要用户没有做任何修改资源的动作(事件),就不会把重新计算后的资源写回数据库。
《Travian》在前台界面上看到资源不断的上涨其实是利用JavaScript实现的小效果。