• 欢迎访问极客公园网站,WordPress信息,WordPress教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入极客公园 QQ群
  • Git主题现已支持滚动公告栏功能,兼容其他浏览器,看到的就是咯,在后台最新消息那里用li标签添加即可。
  • 最新版Git主题已支持说说碎语功能,可像添加文章一样直接添加说说,新建说说页面即可,最后重新保存固定连接,演示地址
  • 百度口碑求点赞啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊http://koubei.baidu.com/s/gitcafe.net
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏极客公园吧

Web策略类游戏开发(二):WebGame事件

未分类 博客教主 14年前 (2010-09-28) 1139次浏览 0个评论

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)从数据库里取结束时间<当前事件的事件进行处理。

///

/// 事件处理线程
/// 每间隔1s处理一次到时间了的事件
///

static void EventThread()
{
DateTime lastTime = DateTime.Now;
while (Run)
{
try
{
Event.SystemEvent.DoEvent(lastTime);
}
catch (Exception ex)
{
Common.Logging.Error(ex.ToString());
}

long def = DateTime.Now.Ticks – lastTime.Ticks;
lastTime = DateTime.Now;

if (def < 10000000) { // 线程休息,并等待下一次时间间隔 int ms = (int)(10000000 - def) / 10000; if (ms > 0)
System.Threading.Thread.Sleep(ms);
}
}
}

/**////

/// 系统事件
/// 主要作用是执行处理事件的过程
///

public class SystemEvent
{
public static void DoEvent(DateTime time)
{
List evs = Event.GetEvents(time);
foreach (Event e in evs)
{
try
{
IEvent ie = e.Object;
if (ie != null)
{
ie.Parent = e;
ie.DoEvent();
}
}
catch (Exception ex)
{
Common.Logging.Error(ex.ToString(), e.EventObject);
}
try
{
e.Delete(); // 从数据库里删除信息
}
catch (Exception ex)
{
Common.Logging.Error(ex.ToString());
}
}
}
}

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

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

作者:Yahle

极客公园 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Web策略类游戏开发(二):WebGame事件
喜欢 (0)

您必须 登录 才能发表评论!