用Delphi开发DirectX控件

    技术2022-05-11  86

    用Delphi开发DirectX控件 整理编辑:China ASP   Microsoft推出的DirectX使我们在Windows9x下开发游戏软件便利了许多。一般在介绍DirectX 的资料里都讲的是如何用VC++来开发,其实inprise公司的语言也可以用来开发基于DirectX的游戏软件。我们这里用的是DirectX控件,它有Delphi3和Delphi4不同的版本。在 http://www.ingjapan.ne.jp/hori/ 处你可以download,是由一个日本人写的,而且,这套控件是完全免费的,你可以自由使用。在这套控件里有DirectX的各种范例程序,我们今天来讨论一下其中基于DirectX的网络通信程序如何开发。   想必大家都看到过那些硝烟纷飞的即时战略游戏,这些游戏中一个很诱人的买点就是可以几个人同时加入战斗,各自扮演一方高手,杀它个你死我活。那么这些即时战略游戏中的网络对战部分是怎么写的呢?其实在Microsoft的DirectX中专门有一类API就是负责网络通信的,不管是基于IPX,还是TCP/IP,或者是Modem,它都可以圆满解决。而作为程序设计的我们一般来说不用操心这些连接方式不同而带来的代码的不同,我们可以一视同仁,只要写一套统一的代码就可以了,各种连接方式的细节问题我们就交给DirectX去处理了。   下面我们具体分析一下一个chat聊天程序的构造。运行samples/network/chat.dpr,我们就看到了一个最简单的聊天程序了。首先程序会让你选择连接的方式:IPX连接、Internet TCP/IP连接、调制解调器连接和串行连接;选择好连接方式后(下面假设你是选择用TCP/IP方式连接),你可以选择是创建一个新游戏还是进入一个已经存在的游戏(当然现在这里的游戏就是指一个聊天程序!);如果你是选择建立一个新游戏,那么接下来要你输入游戏的名字和你的名字,然后聊天就开始了;如果你是选择加入一个已经存在的游戏的话,那么你可以通过输入指定的IP地址来连接或者索性让程序去搜索有哪些已经存在的游戏名字。如果你在连接方式中选择的是调制解调器连接的话,就稍微复杂一些,需要选择调制解调器,并准备拨号和应答等。有没有发现这些连接的方式和过程和我们通常在游戏中看到的很相似?由于这些关于连接的对话框都是由DirectX提供的,因而会有一点语言上的问题。如果你安装的是DirectX的中文版本的话,那么你看见的将全部是中文。(顺便说一句,这套Delphi 控件所支持的DirectX必须在5.0版本以上。)   这个程序本身并不复杂,下面是其主要的几个过程,我们已经加上了较为详细的注释:   //增加游戏者   procedure TMainForm.DXPlay1AddPlayer(Sender: TObject; Player: TDXPlayPlayer);   begin      Memo1.Lines.Add(Format(' %s entered a room.', [Player.Name]));   end;   //游戏者离开   procedure TMainForm.DXPlay1DeletePlayer(Sender: TObject;Player: TDXPlayPlayer);   begin      Memo1.Lines.Add(Format(' %s left a room.', [Player.Name]));   end;      //DirectPlay打开   procedure TMainForm.DXPlay1Open(Sender: TObject);   var      i: Integer;   begin      for i:=0 to DXPlay1.Players.Count-1 do           if DXPlay1.Players[i].RemotePlayer then             Memo1.Lines.Add(Format(' %s is entering a room.', [DXPlay1.Players[i].Name]));     end;    procedure TMainForm.FormDestroy(Sender: TObject);   begin      DXPlay1.Close;   end;   //窗口创建执行事件   procedure TMainForm.FormCreate(Sender: TObject);   begin    try       //DirectPlay 打开         DXPlay1.Open;    except      //防错处理         on E: Exception do         begin           Application.ShowMainForm := False;           Application.HandleException(E);           Application.Terminate;         end;    end;    //显示有关信息在窗口的caption    MainForm.Caption := Format('%s : %s', [DXPlay1.ProviderName, DXPlay1.SessionName]);   end;   //当有消息发送时   procedure TMainForm.DXPlay1Message(Sender: TObject; Player: TDXPlayPlayer; Data: Pointer;DataSize: Integer);   var      s: string;   begin    case DXPlayMessageType(Data) of       DXCHAT_MESSAGE:       begin           if TDXChatMessage(Data^).Len<=0 then             s := ''           else begin             //计算字符串长度和内容             SetLength(s, TDXChatMessage(Data^).Len);             StrLCopy(PChar(s), @TDXChatMessage(Data^).c, Length(s));           end;           //显示收到的消息           Memo1.Lines.Add(Format('%s> %s', [Player.Name, s]));       end;    end;   end;   //发送按钮   procedure TMainForm.Button1Click(Sender: TObject);   var    Msg: ^TDXChatMessage;    MsgSize: Integer;   begin      MsgSize := SizeOf(TDXChatMessage)+Length(Edit1.Text);      GetMem(Msg, MsgSize);      try         Msg.dwType := DXCHAT_MESSAGE;         Msg.Len := Length(Edit1.Text);         StrLCopy(@Msg^.c, PChar(Edit1.Text), Length(Edit1.Text));               //发送消息到所有的人         DXPlay1.SendMessage(DPID_ALLPLAYERS, Msg, MsgSize);         //发送消息到自己         DXPlay1.SendMessage(DXPlay1.LocalPlayer.ID, Msg, MsgSize);         Edit1.Text := '';    finally      FreeMem(Msg);    end;   end;   TDXPlay控件是写这类程序的关键,其属性、事件和方法并不多。GUID属性用来程序的自我识别,具有相同GUID的程序互相之间就能识别,所以你可以看到GUID是一个很长的数字;Open方法用来打开通讯端口,Close用来关闭通讯端口;SendMessage方法是用来发送消息到所有的游戏者,当你的程序收到消息的时候,会产生OnMessage 事件。   这个程序的代码应该是相当简练了,但是却完成了点对点的多点聊天功能。如果你在自己的程序里约定好一套规则,那么你的程序也就具备了互相的通信能力,是不是感觉很简单?可以说,利用DirectX来写这方面的通信程序是最佳的选择,你可以对网络的知识完全不懂,因为这一切已经由Microsoft花费了大量人力物力进行优化的代码来完成了。如果说有什么缺点,就是要求用户的电脑上一定要安装上DirectX,这在现在win98越来越普及的情况下,并不是一件难事。再说,Microsoft的DirectX也是一套完全免费的软件。利用DirectX优秀的性能加上功能强大的 Delphi语言,相信你一定能写出一套优秀的游戏软件(当然拥有设计良好的对战功能)。 Copyright © 上海聚声计算机系统工程有限责任公司 1999-2000, All Rights Reserved

    最新回复(0)