使用Delphi编写棋牌类游戏 -- 基础篇(1)

目前开发棋牌类游戏的公司和个人很多。但是对于很多开发者来说,开发一款具有可扩展、稳定的棋牌类游戏还是具有一定的难度。这次我就以我开发棋牌类游戏为例,讲述如何使用 DELPHI 来开发棋牌类游戏。希望我的经验可以对游戏开发爱好者起到抛砖引玉的作用。如果您对我基础篇中涉及到的内容非常熟悉,可以直接跳过进入设计篇。因为我的能力有限,所以文中难免有不足之处,欢迎大家指正。
首先来说说关于游戏开发中需要的一些基础知识。
第一个基础知识就是:链表的使用。
对于链表的使用,首先涉及到的就是结构的定义。以下是我定义的一个结构:
// 用户信息结构
RuserInfo= record
       UserID:String[20];
       Sex:Boolean;
       Face:Byte;
       Score:Integer;
End;
PuserInfo = ^ RuserInfo;
在这个结构中大家需要注意 UserID:String[20]; 的定义方法。我见过有人是这样定义的: UserID String; 我觉得这样定义是不正确的。对于 String[20] 来说,这样定义说明了它是一个 short String 类型,而这种类型的长度是 255 。可是定义成 string 的话它的长度应该是 2G 。一个结构不能占用这么大的空间。所以我建议大家在定义结构对象的时候 string 类型尽量定义成 string[] 方式。
对于链表的时候其次就是向链表中加入指针和从链表中删除指针。
加入指针使用 Add ,删除指针使用 Delete 例如:
// 添加链表
New(p_User);
p_User.UserID:= UserID;
p_User.Sex:= Sex;
p_User.Face:= Face;
p_User.Score:= Score;
UserList.Add(p_User);
// 删除链表
IF p_User.UserID = UserID then
Begin
  UserList.Delete(I);
  Dispose(p_User);
End;
在添加和删除链表的使用中一定要注意,在加入之前使用 NEW 函数在删除以后一定要使用 dispose 函数。我见的最多的错误就是在添加前使用了 New 但是在删除以后没有使用 Dispose 来释放自己申请的空间。这样会造成内存泄露。
2 :链表的嵌套。
在我后面关于开发游戏的例子中会讲到在定义链表的时候使用嵌套的方式。
例如:对于一个游戏来说,我们可以给它定义一个 GAMEID 来作为这个游戏的编号。而一个游戏可以分成好几个房间(我们使用房间编号 RoomID 来标记)。对于房间来说,里面会包含很多的用户。那如何使用一个链表来保存这个信息,并且让我们以后查找起来非常方便呢?我是这样定义的:
// 用户信息
RuserInfo = Record
  UserID:String[20];                   // 用户编号 用来唯一确定一个用户
  UserName:String[20];               // 用户名称 用于显示使用
  UserPaw:String[20];                 // 用户的密码
  UserFace:Integer;                     // 用户头像
  UserSex:Boolean;                     // 用户性别     
  … …                                      // 省略用户其它信息     
End;
PuserInfo = ^ RuserInfo;
// 房间信息
RroomInfo = record
  RoomID:Integer;                      // 房间编号
  UserList:Tlist;                          // 房间用户链表   用来保存 PuserInfo
End;
ProomInfo = ^ RroomInfo;
// 游戏信息
RgameInfo = record
  GameID:String[2];                   // 游戏编号
  RoomList:Tlist;                        // 房间链表   用来保存 ProomList
End;
PgameInfo = ^ RgameInfo;
这样定义出了一个使用嵌套的结构。
使用的时候和单一的链表结构使用没有区别。例如
在某房间加入一个用户 ( 假设 GameList 为游戏链表 )
Procedure AddUserInfo(GameID String RoomID Integer UserInfo RuserInfo)
Var
  P_GameInfo PgameInfo
  P_RoomInfo ProomInfo
  P_UserInfo PuserInfo
  I Integer
Begin
  For I:=0 to GameList.Count-1 do
  Begin
P_GameInfo = GameList.Items[I];
If P_GameInfo.GameID = GameID then
Begin
  For J:=0 to P_GameInfo. RoomList.Count-1 do
  Begin
       P_RoomInfo:= P_GameInfo. RoomList.Items[J];
    If P_RoomInfo. RoomID = RoomID then
    Begin
      New(P_UserInfo);
      P_UserInfo^:= UserInfo;
P_RoomInfo. UserList.Add(P_UserInfo);
Break;
    End;
  End;
End;
End;
End;
至于查询、删除都和上面的例子相差不大。
3 :函数链表的使用。
对于棋牌类游戏中函数链表的使用主要表现于:服务端框架和具体游戏逻辑处理 DLL 中。由于服务端框架部分已经实现了一些函数(例如数据发送函数、用户状态改变函数、桌子状态改变函数等等),没有必要再让 DLL 实现这个功能(或者不易实现这个功能)。所以我们只要将这些函数的指针传入就可以直接使用它们。具体的传入方式可以查看我的 BLOG 文章《 Delphi 下使用指针的简单总结》 中的 3 :函数指针的使用。为了保障阅读的连续性,我将当时的代码在这里也贴出来:
 
SendDataFun: procedure(Casetype: Byte; UserSocket: RUserSocket; Data: array of char; DataLen: Integer);
 
function ModuleSendData(FunPList: TList): Boolean; stdcall; export;
begin
  SendDataFun := FunPList.Items[0];
end;
 
EXE 中的代码是:
Linstance:=LoadLibrary(Pchar(Temp));
if Linstance>0 then
begin
  // 将发送数据的指针传入 DLL 插件中
  @GiveModuleFun:=GetProcAddress(Linstance,'ModuleSendData');
  if @GiveModuleFun<>NIl then
  begin
    m_FunList:=TList.Create;
    // 发送数据
    t_Pointer:=@DllSendData;
    m_FunList.Add(t_Pointer);
    GiveModuleFun(m_FunList);
End;
End;
 
 
是不是将链表使用的很熟练就可以开始开发游戏了呢?不是。对于网络棋牌类游戏来说。我的理解应该是两个部分非常重要: 1 :网络通信部分。 2 :界面实现部分。
下一篇我们来探讨使用 DELPHI 开发网络通信部分。

本文出自 “狗窝” 博客,转载请与作者联系!

你可能感兴趣的:(游戏,职场,Delphi,休闲,棋牌)