找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5187|回复: 0

PSS应用之-游戏插件开发(一)

[复制链接]
发表于 2012-5-11 11:48:50 | 显示全部楼层 |阅读模式
最近使用这个开源程序的朋友越来越多了,给我提出了很多宝贵的意见,在这里我非常感谢,我在逐渐完善它,相信它会越来越好。
前一段时间,有一个朋友说,你能不能在这个框架下实现一个简单的游戏插件,我们好作为开发参考?我答应了。于是就有了以下的文字。我将会在0.85版本推出的时候,给出全部游戏插件样例的开发代码。
不过,在我看来,其实有比开源插件代码更重要的工作,我希望大家如果有兴趣的话,可以把这个PSS发挥到极致,不过要想好好发挥它的能量,就要有一定的开发模式与之匹配。我希望大家读完车篇文章,看到的不仅仅是代码,而是一种开发的思维模式,如何去创造优秀?并且保持激情。
那么来看看,如果我要做一个简单的游戏插件,我需要具备哪些解决问题的能力?(我开始想写这个游戏模块的时候,首先浮出我脑子里面的4个问题。)
(1)我如何组织我的数据?我要求就算在程序崩溃的最坏条件下,我的重要的信息数据如何才能得到最大的保全?
(2)我如何分层组织数据,在BUG出现的时候,怎样做能迅速查找到问题的点?
(3)诚然,随着逻辑的多样化和复杂性,我的代码会看上去越来越乱,那么,我怎么来让它具备可维护性?就算一个新手来看,他应该从何方向着手?
(4)如果上面三个问题解决了,我怎么做到更快速的开发?
从我的从业经验而言,游戏其实是一个很简单的工作,也是一个很复杂的工作。很多人认为游戏门槛很高,其实从服务器角度而言,并非如此,你往往不需要很高深的数据知识。但是你需要通过学习和使用了解一些游戏逻辑的基本处理手段。写代码其实并不难,难在组织,难在沟通,我经历过几个游戏团队,失败的游戏做过,成功的也做过,那么,在我们动手之前,来看看我们会面临什么样的问题。
其实,策划和程序,在处理不好的时候,往往会变成矛盾体。一方面,程序需要维护自己的代码的执行效率,另外,还要懂得策划想要得到的结果。在逻辑简单的时候还好,等到逻辑越变越多的时候,程序往往会变的顾此失彼。策划总是说:"你实现的完全就不是我要的。",或者,"你实现的BUG太多了!"。受罪的同时,还要挨骂。如此恶性循环,最后会把项目推到危险的境地。
那么,什么如何解决这个问题呢?我觉得,关键在于组织,逻辑部分,策划是最清楚的。那么,有些东西就可以让策划去做,程序不再过多参与?恩,让我们想想,既然策划能够写出策划文档,为什么我不再进一步,我给策划提供一种实现的容器,让策划在上面组织积木?当然,这个积木是由我们提供的,策划拿到这些积木去建立他们的大楼,这样做,既节省了反复沟通的成本,也降低了程序开发的复杂性。那么或许你会说,这样的容器哪里去找?其实,这几年,脚本语言和C++的整合越来越成为了一种趋势,那么,我就先选一个我手熟的脚本,Lua来作为这个容器吧。
好了,容器有了,那么我们开始制造积木吧!
想的很美好,在实际游戏开发中,其实这里也是有误区和风险的。程序想,既然要制造积木,自然越细越好,比如,提供给策划各种玩家修改,修改金钱,修改数值。想的很好,洋洋洒洒写了几十个甚至上百个积木。
结果呢?过了一个星期,或许你会发现策划一行脚本也没写出来。
程序:"啊,怎么会这样?"
策划:"大哥,你把我当程序使啊,我哪里会?光看着几十个积木我就头晕,更别说组织了。"
程序:"你妹啊,我已经给你想要的一切了,你写不出来可不是我的问题!"
策划:“你这哪里是协作?分明是推卸责任,什么都我写了要你干啥?”
呵呵,如果你遇到这样的对话,当你遇到这样的时候,你会怎么想呢?或者说,你会怎么回答呢?
说实在的,freeeyes就面对过这样的对话。而且,那个程序很可能就是freeeyes哦。不得不说,这让freeeyes有很大的挫败感,当然,问题还是要解决的。静下来想想。如果自己是一个很完美的建筑师,要建立一个很漂亮的大楼,图纸写好了,结果施工的工人给我了一堆沙子,石子,钢块,木头。就算再优秀的建筑师,也会无从做起,为啥?鬼才知道我要的混凝土配方是怎么做的,我也不会炼钢,更别说如何做钢架构模型了,我又不是木工,别指望我能切削到我图纸上的那些木质结构,我连木锉怎么用都不知道。我要的是可以拆卸的构架,因为我只知道这个地方,要一个小小的构件!
构件,构件!!构件!!!
对,问题就在这里,如果我们把策划想象成建筑师,越是优秀的策划,可能对构件的要求越清晰。
对,解决它的方法,就由我们程序,来提供这些构件吧,你不知道混凝土怎么做,那么我就给你提供混凝土,甚至是一堵可以拆卸的墙。你需要什么样的钢架,我直接提供你钢架。
没错,聪明的呢一定想到了,要做好一件事情,我们就需要符合事物成长的关键因素,我姑且管他叫做"粒度",说俗一点就是"粗细"。好的程序,其实是一个非常完美的组织者,你可以清楚的了解,策划需要什么构件,而不是细致入微的东西。这一定要谨记!也是我设计开发遵守的准则之一。
于是,让我们继续。
就拿最近比较流行的德克萨斯扑克来说吧。
对于策划,他会想要什么呢?
策划说:"我想要知道什么时候发牌,什么时候玩家出来,玩家什么时候坐下,玩家什么时候离开。"
好,非常好,如果策划能说出上述语句,说明你第一步已经成功了。也就是说,策划开始思考,我需要什么样的事件。
让我们来看看,lua脚本是如何写的。
  1. --在房间中的逻辑
  2. --add by freeeyes
  3. ROOM_PLAYER_SIZE         = 5    --房间内玩家参加的最大人数
  4. ROOM_PLAYER_VISITOR_SIZE = 5    --观察者玩家的最大个数
  5. ROOM_ERROR_NULL          = 0    --正确的返回值
  6. --玩家进入房间,nRoomID:房间ID,nPlayerID:玩家ID
  7. function EnterRoom(nRoomID, nPlayerID)
  8. end
  9. --玩家坐下,nRoomID:房间ID,nPlayerID:玩家ID, nLocation是所在位置
  10. function SitRoom(nRoomID, nPlayerID, nLocation)
  11. end
  12. --玩家离开房间nRoomID:房间ID,nPlayerID:玩家ID
  13. function ExitRoom(nRoomID, nPlayerID)
  14. end
  15. --房间踢出玩家规则nRoomID:房间ID,nPlayerID:玩家ID,nOperationIDc操作者ID
  16. function OutRoom(nRoomID, nPlayerID, nOperationID)
  17. end
  18. --玩家变换房间,nSrcRoomID:原始房间ID,nDstRoomID:目标房间ID,nPlayerID:玩家ID
  19. function ChangeRoom(nSrcRoomID, nDstRoomID, nPlayerID)
  20. end
  21. --房间事件到达,定时更新调用。nEventID,事件ID,nPlayerID触发玩家ID,如果没有玩家触发则是-1
  22. function Update(nRoomID, nPlayerID, nEventID, nData)
  23. end
  24. --清理房间,全部退出
  25. function ClearRoom()
  26. end
  27. --初始化房间
  28. function InitRoom()
  29. end
  30. --玩家Player身上的定时器到达
  31. function PlayerTimer(nRoomID, nPlayerID, nEventID)
  32. end
  33. --房间的定时器到达
  34. function RoomTimer(nRoomID, nPlayerID, nEventID)
  35. end
复制代码
好了,freeeyes兴冲冲的拿着这个文件给策划看。(到此,程序总耗时10分钟
策划说,大部分我看懂了,但是,你的最后两个PlayerTimer和RoomTimer是干什么的?freeeyes解释说,这是定时器,因为是一个棋牌引擎,为了通用,我把这个隔离出来,你可以在玩家身上设置一个标记,比如,等待这个玩家出牌。如果20秒到了,玩家没有出牌,由你策划来决定怎么处置。之所以分为两个,是因为一个房间可以有N个玩家,这两种不同的定时器,用于处理不同的事件。策划说,了解了。
好了,那么freeeyes接着说,你可以开发了吧,策划说,还不行。我虽然知道了事件的含义,但是我不知道怎么操作?
恩,那么就让freeeyes来帮你把。
程序:"咱们说的细一点,先说第一个事件,EnterRoom。"
策划:"好的,让我们看看我们能做什么?"
程序:"EnterRoom, 顾名思义,玩家进入一个房间,你可以想象一下啊,我有一个房间,有一个玩家进来了。他会做什么呢?"
策划:"恩,我想让他看看,身边有没有人。"
程序:"恩,然后呢?"
策划:"奥,对了,之前我还得知道房间是否允许进入,是否满员,满员就不让进来了,还有,玩家进来必须先站着,想坐下的时候,才是想在这个房间进行游戏的玩家。"
程序:"非常棒,我似乎看到了你的场景的样子,肯定很精彩。那么,你来把它写在里面如何,用中文?"
策划:"好,我来试试。"
于是策划给了程序一个这样的东东。
  1. --玩家进入房间,nRoomID:房间ID,nPlayerID:玩家ID
  2. function EnterRoom(nRoomID, nPlayerID)
  3.         --如果房间内座位已满,则提示,你不能进去了
  4.         --如果房间内参观玩家已满,则提示,站着的人都满了,您就别凑这个房间的热闹了
  5.         --如果以上你都没有被踢出,那么贺喜你,你可以进来看看了,进入房间
  6.        
  7.         --当然也不能白看,在这里看是有时间限制的,如果你10秒钟还不坐下,对不起,你得被请出去,你不玩还有人玩呢
  8. end
复制代码
OK,程序非常高兴,如果你的策划已经能写出这样的东西,说明你已经成功了大半。
在我程序看来,上面每一步就是一个完整的构件。一共需要几个构件呢?
于是,freeeyes写下了以下的实现。(到此,程序总耗时15分钟
  1. --玩家进入房间,nRoomID:房间ID,nPlayerID:玩家ID
  2. function EnterRoom(nRoomID, nPlayerID)
  3.         --如果房间内座位已满,则提示
  4.         if LuaFn_Room_API_GetPlayerCount(nRoomID) > ROOM_PLAYER_SIZE then
  5.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Room Player is full.")
  6.                 return -1
  7.         end
  8.        
  9.         --如果房间内参观玩家已满,则提示
  10.         if LuaFn_Room_API_GetVisitorPlayerCount(nRoomID) > ROOM_PLAYER_SIZE then
  11.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Room Player is full.")
  12.                 return -1
  13.         end       
  14.        
  15.         --进入房间
  16.         nRet = LuaFn_Room_API_EnterRoom(nRoomID, nPlayerID, "freeeyes", 1000)
  17.         if nRet ~= ROOM_ERROR_NULL then
  18.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] EnterRoom fail.[nRet="..nRet.."]")
  19.                 return -1
  20.         else
  21.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] EnterRoom success.")
  22.                
  23.                 --这部分为测试代码,用于数据跟踪
  24.                 --nCount        = LuaFn_Room_API_GetPlayerCount(nRoomID)
  25.                 --nVisitorCount = LuaFn_Room_API_GetVisitorPlayerCount(nRoomID)
  26.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] EnterRoom [Count="..nCount.."][Visit Count="..nVisitorCount.."]")               
  27.                 return 0
  28.         end
  29. end
复制代码
然后给策划看,策划看了一下,于是说,"我看不懂!"
程序此时并不失望,继续说,这就是我给你提供的构件,对应你上面的需求,看一下,是不是你要的?
策划对照着上面自己写的文档,看了一会,说:"恩,大概意思我明白了。"
于是程序说,对,这就是我要给你的构件。首先,我会尝试与你沟通,希望引导你我产生一种共鸣,并建立最简单的构件,当你习惯看这样的构件组织方式,我们的效率就真正起来了。一开始,我会帮你组织一个例子,以后等你手熟了,这些构件你就能自己制造了,而对于我,我只需要按照你的需求填充每个构件内的实现。你看,你做到了,这就是你做到的!
呵呵,良好的端源于敢于沟通,并鼓励,激情,感染。
于策划沟通,程序必须有足够的感染力,互动力,这样,策划才会慢慢放下警惕与恐惧,融入到你的想法中去,这里有freeeyes的准则之一,你必须让你的伙伴,感到成就感。
策划看了一会,说:"让我们一起来,把其他部分填充一下。"
于是策划写出了如下的文字:
  1. --在房间中的逻辑
  2. --add by freeeyes
  3. ROOM_PLAYER_SIZE         = 5    --房间内玩家参加的最大人数
  4. ROOM_PLAYER_VISITOR_SIZE = 5    --观察者玩家的最大个数
  5. ROOM_ERROR_NULL          = 0    --正确的返回值
  6. --玩家进入房间,nRoomID:房间ID,nPlayerID:玩家ID
  7. function EnterRoom(nRoomID, nPlayerID)
  8.         --如果房间内座位已满,则提示
  9.        
  10.         --如果房间内参观玩家已满,则提示
  11.        
  12.         --进入房间
  13. end
  14. --玩家坐下,nRoomID:房间ID,nPlayerID:玩家ID, nLocation是所在位置
  15. function SitRoom(nRoomID, nPlayerID, nLocation)
  16.         --尝试坐下
  17.         --判断房间是否存在定时器
  18.                         --如果没有定时器,则按照规则做一个定时器
  19.                                 --判断当前时间是否大于房间更新时间5秒
  20.                                         --添加一个房间的定时器
  21. end
  22. --玩家离开房间nRoomID:房间ID,nPlayerID:玩家ID
  23. function ExitRoom(nRoomID, nPlayerID)
  24.         --玩家离开房间,并做一些清理动作
  25. end
  26. --房间踢出玩家规则nRoomID:房间ID,nPlayerID:玩家ID,nOperationIDc操作者ID
  27. function OutRoom(nRoomID, nPlayerID, nOperationID)
  28.         --踢出玩家
  29. end
  30. --玩家变换房间,nSrcRoomID:原始房间ID,nDstRoomID:目标房间ID,nPlayerID:玩家ID
  31. function ChangeRoom(nSrcRoomID, nDstRoomID, nPlayerID)
  32. end
  33. --房间事件到达,定时更新调用。nEventID,事件ID,nPlayerID触发玩家ID,如果没有玩家触发则是-1
  34. function Update(nRoomID, nPlayerID, nEventID, nData)
  35.         --玩家下注
  36.                         --移动到下一个玩家
  37.                                 --计算当前轮次是不是最后一轮
  38.                                         --在这里进行牌局结算
  39.                                 else
  40.                                         --给下一个玩家身上装上定时器
  41.         return 0
  42. end
  43. --清理房间,全部退出
  44. function ClearRoom()
  45. end
  46. --初始化房间
  47. function InitRoom()
  48. end
  49. --玩家Player身上的定时器到达
  50. function PlayerTimer(nRoomID, nPlayerID, nEventID)
  51.                 --到期玩家没有下注
  52.                
  53.                 --在这里处理玩家移动的规则
  54. end
  55. --房间的定时器到达
  56. function RoomTimer(nRoomID, nPlayerID, nEventID)
  57.                 --如果是1001事件,那么就是到时发牌事件(在这个C++函数里面完成了发牌,下大盲注,小盲注以及标记房间状态的任务)
  58.                         --设置开始的玩家ID,以此为轮次计算的依据,如果GetRoomNextPlayerID到了这个玩家,则轮次计算+1
  59.                        
  60.                         --对下一个出牌的玩家添加定时器
  61.                 end
  62.         end
  63. end
复制代码
好了,程序拿到这个。来看看。他怎么做的
  1. --在房间中的逻辑
  2. --add by freeeyes
  3. ROOM_PLAYER_SIZE         = 5    --房间内玩家参加的最大人数
  4. ROOM_PLAYER_VISITOR_SIZE = 5    --观察者玩家的最大个数
  5. ROOM_ERROR_NULL          = 0    --正确的返回值
  6. --玩家进入房间,nRoomID:房间ID,nPlayerID:玩家ID
  7. function EnterRoom(nRoomID, nPlayerID)
  8.         --如果房间内座位已满,则提示
  9.         if LuaFn_Room_API_GetPlayerCount(nRoomID) > ROOM_PLAYER_SIZE then
  10.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Room Player is full.")
  11.                 return -1
  12.         end
  13.        
  14.         --如果房间内参观玩家已满,则提示
  15.         if LuaFn_Room_API_GetVisitorPlayerCount(nRoomID) > ROOM_PLAYER_SIZE then
  16.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Room Player is full.")
  17.                 return -1
  18.         end       
  19.        
  20.         --进入房间
  21.         nRet = LuaFn_Room_API_EnterRoom(nRoomID, nPlayerID, "freeeyes", 1000)
  22.         if nRet ~= ROOM_ERROR_NULL then
  23.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] EnterRoom fail.[nRet="..nRet.."]")
  24.                 return -1
  25.         else
  26.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] EnterRoom success.")
  27.                
  28.                 --这部分为测试代码,用于数据跟踪
  29.                 --nCount        = LuaFn_Room_API_GetPlayerCount(nRoomID)
  30.                 --nVisitorCount = LuaFn_Room_API_GetVisitorPlayerCount(nRoomID)
  31.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] EnterRoom [Count="..nCount.."][Visit Count="..nVisitorCount.."]")               
  32.                 return 0
  33.         end
  34. end
  35. --玩家坐下,nRoomID:房间ID,nPlayerID:玩家ID, nLocation是所在位置
  36. function SitRoom(nRoomID, nPlayerID, nLocation)
  37.         --尝试坐下
  38.         nRet = LuaFn_Room_API_PlayerSit(nRoomID, nPlayerID, nLocation)
  39.         if nRet ~= ROOM_ERROR_NULL then
  40.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom fail.[nRet="..nRet.."]")
  41.                 return -1
  42.         else
  43.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom success.")
  44.                
  45.                 --判断房间是否存在定时器
  46.                 if LuaFn_RoomTimer_API_Check(nRoomID) == false then
  47.                         --如果没有定时器,则按照规则做一个定时器
  48.                         nCount        = LuaFn_Room_API_GetPlayerCount(nRoomID)
  49.                         nVisitorCount = LuaFn_Room_API_GetVisitorPlayerCount(nRoomID)
  50.                         LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom [Count="..nCount.."][Visit Count="..nVisitorCount.."]")
  51.                         if nCount > 1 then
  52.                                 --判断当前时间是否大于房间更新时间5秒
  53.                                 if LuaFn_Room_API_CheckRoomUpdateTime(nRoomID, 5) == true then
  54.                                         --添加一个房间的定时器
  55.                                         nRet = LuaFn_RoomTimer_API_Add(2, nRoomID, nPlayerID, 1001)
  56.                                         if nRet <= 0 then
  57.                                                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom timer fail.[nRet="..nRet.."]")
  58.                                         else
  59.                                                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom timer success.[nsecond=5]")
  60.                                         end
  61.                                 else
  62.                                         --添加一个房间的定时器
  63.                                         nRet = LuaFn_RoomTimer_API_Add(5, nRoomID, nPlayerID, 1001)
  64.                                         if nRet <= 0 then
  65.                                                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom timer fail.[nRet="..nRet.."]")
  66.                                         else
  67.                                                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] SitRoom timer success.[nsecond=2]")
  68.                                         end                               
  69.                                 end
  70.                         end
  71.                 end
  72.         end       
  73.         return 0
  74. end
  75. --玩家离开房间nRoomID:房间ID,nPlayerID:玩家ID
  76. function ExitRoom(nRoomID, nPlayerID)
  77.         --调试代码
  78.         --nCount        = LuaFn_Room_API_GetPlayerCount(nRoomID)
  79.         --nVisitorCount = LuaFn_Room_API_GetVisitorPlayerCount(nRoomID)
  80.         --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] ExitRoom [Count="..nCount.."][Visit Count="..nVisitorCount.."]")
  81.        
  82.         --获得下一个用户
  83.         --nPlayerID1 = LuaFn_Room_API_GetRoomNextPlayerID(nRoomID)
  84.         --nPlayerID2 = LuaFn_Room_API_GetRoomNextPlayerID(nRoomID)
  85.         --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] ExitRoom [nPlayerID1="..nPlayerID1.."][nPlayerID2="..nPlayerID2.."]")
  86.        
  87.         nRet = LuaFn_Room_API_Exit(nRoomID, nPlayerID)
  88.         if nRet ~= ROOM_ERROR_NULL then
  89.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] ExitRoom fail.[nRet="..nRet.."]")
  90.                 return -1
  91.         else
  92.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] ExitRoom success.")
  93.                
  94.                 --调试代码
  95.                 --nCount        = LuaFn_Room_API_GetPlayerCount(nRoomID)
  96.                 --nVisitorCount = LuaFn_Room_API_GetVisitorPlayerCount(nRoomID)
  97.                 --LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] ExitRoom [Count="..nCount.."][Visit Count="..nVisitorCount.."]")
  98.                 return 0
  99.         end
  100. end
  101. --房间踢出玩家规则nRoomID:房间ID,nPlayerID:玩家ID,nOperationIDc操作者ID
  102. function OutRoom(nRoomID, nPlayerID, nOperationID)
  103. end
  104. --玩家变换房间,nSrcRoomID:原始房间ID,nDstRoomID:目标房间ID,nPlayerID:玩家ID
  105. function ChangeRoom(nSrcRoomID, nDstRoomID, nPlayerID)
  106. end
  107. --房间事件到达,定时更新调用。nEventID,事件ID,nPlayerID触发玩家ID,如果没有玩家触发则是-1
  108. function Update(nRoomID, nPlayerID, nEventID, nData)
  109.         --玩家下注
  110.         if nEventID == 3001 then
  111.                 nRet = LuaFn_Room_API_SetPlayerBet(nRoomID, nPlayerID, nData)
  112.                 if nRet ~= ROOM_ERROR_NULL then
  113.                         LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Update SetPlayerBet.[nRet="..nRet.."]")
  114.                         return 0
  115.                 else
  116.                         --移动到下一个玩家
  117.                         nNextPlayer = LuaFn_Room_API_GetRoomNextPlayerID(nRoomID)
  118.                         if nNextPlayer > 0 then
  119.                                 --计算当前轮次是不是最后一轮
  120.                                 if LuaFn_Room_GameInfo_API_GetRoundCount(nRoomID) >= 4 then
  121.                                         LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Update LuaFn_Room_GameInfo_API_GetRoundCount.[RoundCount=4]")
  122.                                         --在这里进行牌局结算
  123.                                 else
  124.                        
  125.                                         --给下一个玩家身上装上定时器
  126.                                         LuaFn_PlayerTimer_API_Add(5, nRoomID, nNextPlayer, 2001)
  127.                                 end
  128.                         else
  129.                                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] Update GetRoomNextPlayerID.[nRet="..nRet.."]")
  130.                         end
  131.                 end
  132.         end
  133.        
  134.         return 0
  135. end
  136. --清理房间,全部退出
  137. function ClearRoom()
  138. end
  139. --初始化房间
  140. function InitRoom()
  141. end
  142. --玩家Player身上的定时器到达
  143. function PlayerTimer(nRoomID, nPlayerID, nEventID)
  144.         if nEventID == 2001 then
  145.                 --到期玩家没有下注
  146.                 LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] PlayerTimer Begin")
  147.                
  148.                 --在这里处理玩家移动的规则
  149.         end
  150. end
  151. --房间的定时器到达
  152. function RoomTimer(nRoomID, nPlayerID, nEventID)
  153.         LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] RoomTimer Begin")
  154.         if nEventID == 1001 then
  155.                 --如果是1001事件,那么就是到时发牌事件(在这个C++函数里面完成了发牌,下大盲注,小盲注以及标记房间状态的任务)
  156.                 nRet = LuaFn_Room_API_DealCode(nRoomID, 1000, -1, -1)
  157.                 if nRet ~= ROOM_ERROR_NULL then
  158.                         LuaFn_Print("RoomID["..nRoomID.."],nPlayerID["..nPlayerID.."] RoomTimer Begin DealCode.[nRet="..nRet.."]")
  159.                         return 0
  160.                 else
  161.                         nCurrPlayerID = LuaFn_Room_API_GetRoomCurrPlayerID(nRoomID)
  162.                        
  163.                         --设置开始的玩家ID,以此为轮次计算的依据,如果GetRoomNextPlayerID到了这个玩家,则轮次计算+1
  164.                         LuaFn_Room_API_SetBenginePlayerID(nCurrPlayerID)
  165.                        
  166.                         --对下一个出牌的玩家添加定时器
  167.                         LuaFn_PlayerTimer_API_Add(5, nRoomID, nPlayerID, 2001)
  168.                 end
  169.         end
  170. end
复制代码
程序开始一行行的解释,给策划。应对它的每一个构件。一直到策划能够提出在哪里完善新的构件位置。到此,程序总耗时30分钟
这里,freeeyes开发准则之一,在开发的前期,伪代码永远会提升你对逻辑的吸收和理解,所以请不要吝惜这些看似没意义的东西。
好了,今天先写到这里,呵呵,这是一个系列文章,下一章,我将会讲到,如何在程序里面实现和lua对接的技巧和方法,我希望用我的文字,来告诉大家,我是如何开发一个游戏的。
期盼winston加精吧。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-28 08:56 , Processed in 0.013275 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表