2D网络游戏开发(网络篇)(六)

原创 2006年06月22日 11:38:00
2D网络游戏开发(网络篇)(六)
 
作者:akinggw
 
在前面的章节中,我们实现了一个简单的聊天室。今天,我们仍然要围绕这个主题,但采取别的方法,这个方法很有用,应该说是整个网络引擎的关键,它就是――RPC(Remote Procedure Calls),翻译成中文就可以理解成”远程功能调用”。
通常情况下,你发送一个信息,你必须实现下面的四个步骤:
 
1.       建一个数据包来存储你的数据;
2.       必须建立一个函数来实现数据包的编码和发送;
3.       建立一个数据包识别函数,用来识别你的数据包,以便于你调用哪个函数来处理它;
4.       最后建立一个函数来解码你的数据包并且处理它。
  
以上就是我们在编写网络程序要做的四个步骤。
但raknet已经为你做好了这一切,那就是RPC,有了它,你只用实现两个步骤,这样你就有更多的时间集中到游戏上。
 
1.       将你的数据编码;
2.       然后调用远程系统的一个相应函数来处理它.
 
RPC在你的游戏中实现的过程如下:
 
A.      告诉网络系统允许使用RPC调用函数
当然,你不需要RPC调用系统中的任何一个函数,这样势必为你带来很多的麻烦。你只需要几个用RPC参数定义的函数就行了,你可以照着下面的例子来定义你的RPC函数。
C函数
void MyFunction(RPCParameters *rpcParameters) {}
//
客户端指针
RakClient *rakClient;
//
注册成为RPC
REGISTER_AS_REMOTE_PROCEDURE_CALL(rakClient, MyFunction);

C++
静态函数
static void MyClass::MyFunction(RPCParameters *rpcParameters) {}
//
客户端指针
RakClient *rakClient;
//
注册成为RPC
REGISTER_AS_REMOTE_PROCEDURE_CALL(rakClient, MyClass::MyFunction);

C++
成员函数
class MyClass : public NetworkIDGenerator {
void __cdecl func1(RPCParameters *rpcParms);
};
//
客户端指针
RakClient *rakClient;
//
注册成为RPC
REGISTER_CLASS_MEMBER_RPC(rakClient, MyClass, func1)
服务器的注册同上一样。
 
B.给你的数据编码
你的RPC方法能够处理一个有长度的字符串或比特流,这就等同于将数据打包。
 
C.调用RPC函数进行处理
 
D.在远程系统上相应的函数将对你的数据进行处理
 
以上就是RPC的处理过程。
下面,我们来看一下RPC的参数和结构:
 
char * input; 来自于远程系统的数据;
unsigned int numberOfBitsOfData; 我们接收的数据的大小;
PlayerID sender; 哪一个系统调用这个RPC;
RakPeerInterface * recipient; rakpeer中的哪一个实例将得到这次调用;
Bool hasTimestamp; 如果为真,那么输入的开始4个字节表示时间;
RakNet::BitStream * replyToSender 用相应的数据流回应发送者.
 
下面,我们来具体地看一下代码:
char message1[300];
 
void PrintMessage(RPCParameters *rpcParameters)
{
printf("%sn",rpcParameters->input);
    sprintf(message1,"%s",rpcParameters->input);      
   
           if(rakServerInterface)
        {
      rakServerInterface->RPC("PrintMessage", message1, (strlen(message1)+1)*8, HIGH_PRIORITY, RELIABLE_ORDERED, 0,rpcParameters->sender, true, false, UNASSIGNED_NETWORK_ID,0);       
      }
}
下面,我们来具体地讲解这个函数。
Message1用于存储得到的信息。首先,我们打印我们得到的信息,然后判断我们是否是服务器,如果是,那么就调用客户端的RPC.
这里这个RPC函数原型如下:
bool RakServer::RPC ( char * uniqueID, 
 const char * data, 
 unsigned int bitLength, 
 PacketPriority priority, 
 PacketReliability reliability, 
 char orderingChannel, 
 PlayerID playerId, 
 bool broadcast, 
 bool shiftTimestamp, 
 ObjectID objectID, 
 RakNet::BitStream * replyFromTarget
 ) [virtual, inherited]
第一个参数,我们注册的RPC函数名;
第二个参数,我们要发送的数据;
第三个参数,发送的数据的大小;
第四个参数,数据包的安全级别,和send函数一样;
第五个参数,数据包的可靠性,和send函数一样;
第六个参数,和send函数一样;
第七个参数,接收者ID;
第八个参数,是否广播;
第九个参数,与时间有关,以后讲解;
第十个参数,如果是静态函数,直接设置成UNASSIGNED_OBJECT_ID
第十一个参数,保留。
 
if (rakServerInterface)
{
        // 服务器运行在端口60000处
       rakServerInterface->Start(32, 0, 0, 60000);
       REGISTER_STATIC_RPC(rakServerInterface, PrintMessage);
 
}
else
{
        // 运行客户端
       printf("输入服务器IP地址:n");
       gets(str);
        // 127.0.0.1 designates the feedback loop so we can test on one computer
        if (str[0]==0)
               strcpy(str, "127.0.0.1");
       rakClientInterface->Connect(str, 60000, 0, 0, 0);         
       REGISTER_STATIC_RPC(rakClientInterface, PrintMessage);
 
}
 
在服务器或客户端注册RPC。
gets(message);
        
         if(rakServerInterface)
          {
           rakServerInterface->RPC("PrintMessage", message, (strlen(message)+1)*8, HIGH_PRIORITY, RELIABLE_ORDERED, 0,UNASSIGNED_PLAYER_ID , true, false, UNASSIGNED_NETWORK_ID,0);          }
         else
          {
           rakClientInterface->RPC("PrintMessage", message, (strlen(message)+1)*8, HIGH_PRIORITY, RELIABLE_ORDERED, 0, false, UNASSIGNED_NETWORK_ID,0);
          }
 
得到信息,然后调用RPC。
 
其它代码不用改动,程序运行的效果如下:

 

 
图注1
图注2
OK,今天的内容就到这里了。
 
关于更多内容请访问金桥科普网站(http://popul.jqcq.com)游戏开发栏目,如你需要游戏开发方面的书籍请参考金桥书城游戏频道(http://book.jqcq.com/category/1_70_740.html)。如果你在阅读本篇文章时有什么好的建议请来信给我,我的E_mail: akinggw@126.com. 如果你在使用SDL时有什么问题,请到金桥科普网站(http://popul.jqcq.com)游戏开发栏目,我将详细地为你解答。  
 

用 Unity 进行网络游戏开发(一)

用 Unity 进行网络游戏开发(一) 这是我之前写的了,一直保存在电脑里,现在学习写博客。希望多和大家交流,共同进步,文章中说得不好的地方请指出,谢谢! 使用Unity3D进...
  • TRGVBZ
  • TRGVBZ
  • 2015年07月09日 16:04
  • 1704

Cocos2d-x开发网络游戏(四) 处理网络线程

转自:http://blog.sina.com.cn/s/blog_6084f58801014g0g.html
  • gf771115
  • gf771115
  • 2014年04月27日 22:33
  • 3268

[四种]网络游戏外挂的制作方法

1、动作式,所谓动作式,就是指用API发命令给窗口或API控制鼠标、键盘等,使游戏里的人物进行流动或者攻击,最早以前的“石器”外挂就是这种方式。(这种外挂完全是垃圾,TMD,只要会一点点API的人都知...
  • liujiayu2
  • liujiayu2
  • 2015年05月14日 15:36
  • 1641

游戏开发中网络通讯协议对比

在网络游戏开发中,通讯协议是一个无法被避免的问题,无论对于客户端开发中还是服务器开发程序猿而言,制定一个合适的通讯协议是很有必要的 游戏联网需求有弱联网游戏,即时互动类游戏 选择通讯协议的时候主要关注...
  • honey199396
  • honey199396
  • 2017年01月18日 19:10
  • 3026

java提高篇(六)-----关键字static

一、 static代表着什么        在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰...
  • chenssy
  • chenssy
  • 2013年10月24日 20:07
  • 8275

[Unity3D ARPG网络游戏编程实践] 网络连接 :unity NetWork与socket的对比(一)

unity3d ARPG网络游戏编程实践 作者:A神 目录 1 网络连接 (unity NetWork与socket的对比) 2 登录界面 (登录协议与模型定制 及流程开发) 3 角色选择 (...
  • kepoon
  • kepoon
  • 2015年05月08日 17:28
  • 5752

网络游戏服务器开发(一)

在开发过程中,会先有一份开发大纲或是一份策划案,但是这些在我的开发中可能不会有,或者即使有,也很有可能是我随性写下来的,但是我会尽可能写好它。网络通信层,我会放到单独的SOCKET编程中去讲解,这里的...
  • yueding521125
  • yueding521125
  • 2014年11月19日 11:43
  • 11978

网络游戏开发基础篇

本篇的内容,会介绍几个内容:单例,dll动态加载以及一些跨平台的处理。        1、单例:单例模式是一种使用广泛而又比较简单的设计模式,他的定义我就不多介绍了,大家上网一查就知道了,基本都...
  • u012890737
  • u012890737
  • 2014年01月07日 18:46
  • 451

游戏开发电子书(PDF)下载分享

游戏开发电子书(PDF)下载分享-大量Unity书籍 封面 书名 作者 出版社 下载 《Unity3D\2D手机游戏开发 第2版》 金玺曾 著 清华大学出版社 ...
  • good3651
  • good3651
  • 2016年12月01日 14:01
  • 7210

Unity网络教程翻译(一)从零开始编写一个网络游戏

原文: Unity网络教程翻译(一)从零开始编写一个网络游戏 未解决疑问: 1、战斗延迟 2、NetworkIdentity勾选任意一个时报错:“cannot be set for...
  • haobaworenle
  • haobaworenle
  • 2017年01月03日 10:28
  • 967
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:2D网络游戏开发(网络篇)(六)
举报原因:
原因补充:

(最多只允许输入30个字)