zoukankan      html  css  js  c++  java
  • 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实现的小效果。

      

     

  • 相关阅读:
    java输入一个文件夹,查找出所有的文件列表
    java字节流到字符流的桥梁InputStreamReader,OutputStreamWriter
    java中获取用户输入字符,并将字符大写后显示
    mqtt
    tcpcopy
    lmax disruptor
    delete solr index
    http://book.douban.com/doulist/2545443/
    http://www.dottoro.com/
    最值得学习阅读的10个C语言开源项目代码
  • 原文地址:https://www.cnblogs.com/yahle/p/1075364.html
Copyright © 2011-2022 走看看