1 事件系統事件系統是整個WebGame系統裡一個核心的組成部分,我們用它來控制的進程,讓遊戲世界裡能夠24小時運轉。1.1 事件的概念事件是指遊戲裡玩家的某個(系列)活動,它可以分為瞬時活動和非瞬時活動。
瞬時活動顧名思義就是在玩家發出指令的瞬間就能完成的活動。像RPG遊戲裡,玩家從NPC裡購買一瓶藥水,在玩家發出這個指令後,玩家的金錢減少,並獲得藥水,這一切都在玩家發出指令後瞬間完成(當然實際邏輯上處理還需要幾個ms處理時間)。
而非瞬時活動則是在玩家發出某個指令後一段事件才會被執行。例如RPG裡玩家鼠標點擊地圖上某個地方,遊戲角色則會自動行走到剛才點擊處。這個移動過程就是一個非瞬時過程,它有了一個移動的過程,這個過程需要消耗一定的時間(玩家能感知的事件)
非瞬時系列活動是指一位或者多位玩家通過一系列的瞬時\非瞬時活動完成一個動作(功能)。例如wow裡面的拍賣場,有1位玩家提供道具,同服務器裡的其他玩家對該道具進行競拍。
在WebGame裡,玩家的很多操作其實是非瞬時部分事件是村莊資源減少(前提投資),非瞬時事件是建築物建設,這個動作(同能)的結果是建築物等級上升。
又比如《Travian》裡的攻擊,瞬時事件是當前村莊的士兵減少(派出部隊),非瞬時事件是減少的士兵移動到需要攻擊的村莊(行軍過程),動作結束是,兩個村莊的部隊開打了(戰鬥)。1.2 觸發器(事件隊列)前面說了瞬時事件和非瞬時事件的概念,當WebGame在24小時運轉的時候,系統會產生大量的非瞬時事件,這些非瞬時事件不會在玩家點擊頁面時執行,而是需要等一段時間後才會執行,因此在遊戲裡把這些非瞬時事件拿出來,按事件的執行時間進行排序,組成一個事件隊列。再通過一個觸發器,在事件設定的執行時間到達的那時執行相對應的事件。
這裡面就涉及到兩個內容:
• 非瞬時的事件隊列
• 事件觸發器1.2.1 事件隊列數據庫除了用於存儲外,其查詢功能也非常強大,直接拿來做事件隊列很合適。事件隊列裡通常保存事件涉及的對象(村莊),結束時間、事件類型以及事件相關參數等。
下表為我們系統裡使用的事件表:

保存時將這些對象做xml序列化保存到EventObject字段裡。當然如果為了效率還可以存儲二進制序列化後的對象,這樣在序列化以及反序列化時能節省大部分時間。1.2.2 觸發器Asp.net
Asp.net的處理在觸發器上的處理就比較簡單了。在服務器程序啟動的時候,就執行一個線程,定時(1s)從數據庫裡取結束時間<當前事件的事件進行處理。/**//// <summary>
/// 事件處理線程
/// 每間隔1s處理一次到時間了的事件
/// </summary>
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);
}
}
}/**//// <summary>
/// 系統事件
/// 主要作用是執行處理事件的過程
/// </summary>
public class SystemEvent
{
public static void DoEvent(DateTime time)
{
List<Event> 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實現的小效果。 |