GameMaker多人游戏、服务器的创建
作者:tifaices
GM提供了部分网络函数,使得GM能过制作出具有联网功能的游戏~,不过网络方面的东西,涉及面较广,有一个环节不正确,玩家之间都无法正确的进行数据交流,现在我们将介绍一些GameMaker网络方面的游戏制作的知识,最后会包括一些额外FAQ39dll等应用哦!
第一章:游戏的创建与连接

    GM其实提供了4种连接方式,ipx tcp/ip以及modem以及序列(详情查看帮助的“多人游戏”),其中序列是最为古老,远在95年的时候,C&C(命令与征服)就采用了此连接方式;接下来就是使用调制解调器的连接,然而这2种方式放在我们现在,已经可以不使用了,而我们现在着重讲解的就是广为使用的TCP/IP创建游戏~而ipx是倾向于局域网连接,所以如果你会使用TCP/IP来进行游戏制作的话,ipx也不在话下了。

    创建连接前,我们来认识两个函数:


  mplay_init_tcpip(addr)

    mplay_ipaddress()   

    mplay_init_tcpip函数是在创建连接的时候,必须执行的初始化函数,其中参数:addr,则是我们需要初始化连接的地址,一般作为创建者,这里最好写入自己的ip地址,如你本机为123.54.1.27那么就写为mplay_init_tcpip("123.54.1.27"),如果是内网ip,同样也写内网的ip(内网ip也可以通过外网来连接,后期会说明这个原理),不知道自己的ip?不要紧使用mplay_ipaddress() 会将你的ip以字符串形式返回,这个时候我们就可以这样写啦:mplay_init_tcpip(mplay_ipaddress())。
    如果是作为连接者的话,你现在需要做的事情就是:获取你想连接的玩家/服务器的ip地址,然后同样使用以上函数就可以进行连接哦!比如你知道你朋友建立的游戏,他ip为
123.54.1.27,那么就写为mplay_init_tcpip("123.54.1.27"),当然,他的连接必须在开启状态
,不然你是连不进去的。
    创建连接后,我们接下来需要开始建立一个游戏联机啦:

    mplay_session_create(sesname,playnumb,playername)

    作为游戏创建者,在进行tcpip初始化以后,第一件事情就是创建一个游戏连接,使用以上函数即可创建,其中参数sesname就是联机的名称,你可以取一个好听的名字,这样如果你是作为服务器的话,别人获得的连接就是你的名字啦(如很多网络游戏);playnumb,这个是游戏玩家,比如你和朋友们玩的话,一般设定在8位以下,而作为一个大型游戏,你可以设置多一些,甚至可以利用编程来达到排队的方式进入,这里就不多说了;playername,因为gm指定你在作为创建者时,也需要取一个名字来作为这个创建里的玩家。
    如果你是作为联结者的话,在进行tcpip初始化以后,第一件事情就是在这个ip里查到一个游戏连接,以下是相关函数:

    mplay_session_find()


    mplay_session_name(numb)

    mplay_session_join(numb,playername)

    注意:无论什么情况,我们必须先执行mplay_session_find(),才能运行后个函数,不然的话,就算你知道连接,也连接不进去,因为——你电脑不知道呀~mplay_session_find()是让你电脑马上对你初始化的ip进行扫描,让电脑知道此ip一共有几个游戏连接,然后我们来利用mplay_session_name(numb)得到第numb个游戏连接的名称,一般我们只创建一个,那么numb则是0。mplay_session_join(numb,playername)顾名思义,就是加入这个连接啦,如果numb号连接存在的话,我们就利用这个函数加入游戏~,游戏的加入我们需要给自己取一个名字吧,那么playername正是你作为加入者的名字。

      在加入游戏以后,拥有2个以上的玩家,那么就说明我们的联网游戏第一步已经成功~,接下来,我们可以通过以下函数获得当前连接玩家的信息:


      mplay_player_find() 在目前联机中搜寻全部玩家并返回发现的玩家数目。
      mplay_player_name(numb) 返回第numb号的玩家名称(0是第一位玩家,通常是你自己)。这例行程序只能在呼叫之前的例行程序后呼叫。
      mplay_player_id(numb)  返回玩家numb的唯一账号(id),这个函数详细说明一下,每个玩家加入以后,gm会自动分配一个类似instance_id的东西给这个玩家,这个就是这个玩家作为连接里的id啦,是一个数字~。

      最后,我们做一个最简单的网络测试——同步一个数据,我们把创建者里一个变量作为共享数据传输给其他的玩家:
   
      mplay_data_write(ind,val)

      mplay_data_read(ind)


      mplay_data_mode(guar)

      首先,在创建者的游戏里,使用mplay_data_write(ind,val) 将想要共享的数据写入共享id里,其中ind由你自定,ind类似一个索引,他将你的共享数据作一个编号,此ind是识别数据的唯一办法,所以你在设定共享数据的时候一定不要将ind重复了哦。mplay_data_read(ind)作为接收者(非联结者,作为创建者也可以为接收者),我们使用这个函数来接收ind上的数据, mplay_data_mode(guar)数据保护模式,在下一章将会进行详细介绍~。

第二章 数据的共享、发送与接收

    在成功的建立的连接之后,我们就可以开始互相接收数据啦!在此之前,我们接收数据GM也提供了大量
的函数,其中分为2种方式:
 
    第一种为共享数据方式,在上一章结尾我们已经大致的使用了一下:

      mplay_data_write(ind,val)

      mplay_data_read(ind)

      mplay_data_mode(guar)

    大概的共享使用方法,我们已经在上一章结尾说的很清楚,我们现在就只介绍一下mplay_data_mode(guar) 这个函数,在任何数据发送给其他玩家的时候,我们其实是并不知道对方是否接收成功的,但是如果你使用了这个函数mplay_data_mode(guar) ,并将guar参数设定为true,那么我们就可以保证数据能够成功的发送给对方,就好比你对着朋友叫一句:“喂~听见了吗?”,对方回答你一句:“听见了”的道理一样,同理,因为你需要等待对方回答你,设定了guar为true以后,发送数据的速度,就没有为false的时候快了哦。
    共享数据使用范畴一般是为大家都需要同步的数据,比如:一个游戏的总共时间啦,一些共同的障碍物啦之类的。但是,如果是对象的数据,是否也该使用这个办法来实现共享呢?答案是错误的,虽然你可以使用这种办法,但是你到后面你会发现很多麻烦,首先索引只提供10000号数据,在越来越多的实例,你的这10000号是否够用呢?再次,你每个对象使用这种同步的话,你会挨个去给他们编排队伍,这样你迟早会累死,遇见这种情况应该怎么办?

    现在就要使用第二种数据发送接收方式啦,也就是——消息(message):

    mplay_message_send(player,id,val)

    mplay_message_send_guaranteed(player,id,val) 
 
    发送消息,即将你自己想给予其他玩家的内容,利用消息方式发送出去,这样的话,玩家
之前也能进行交叉交流了~mplay_message_send(player,id,val)这是将一条消息发送给玩家player,val就是一个你想发送给这位玩家的值,这个值当然可以是一句字符串,也可以是你的坐标或者正在使用的精灵,player如果是0的话,就是将这个消息发送给在连接中的所有玩家,而参数id,这样理解比较好一些,是发送的时候,你用来区分你消息类别的,这个你可以自定,比如id是1的时候,就是传送坐标啦之类的数据,id是2的时候,又是对话的数据等等。mplay_message_send_guaranteed(player,id,val) 与上一句的用法一模一样,只是类似于mplay_data_mode(guar),是用一定会收到的方式进行发送,建议你在创建自己发射的子弹等数据的时候,使用这句话,不然一旦出现掉包,别人都看不见你的子弹哦~

    在发送消息以后,自然我们就需要接收这些消息啦:

    mplay_message_receive(player)

    mplay_message_id()


    mplay_message_value()

    mplay_message_player()

    mplay_message_name()

    mplay_message_count(player) 

    mplay_message_clear(player)

    在处理任何消息之前,我们要先使用mplay_message_receive(player) 来获得这一消息,player是获得消息来源的玩家,他可以识别玩家的id或者名称,比如你想接收第"allen"玩家的
消息,那么就是"allen",你也可以使用mplay_message_player() 来获得这个玩家的id,再使用mplay_message_receive(mplay_message_player()) 来获得这个玩家发送的消息。现在我们接收到消息了,开始对这些消息着手进行处理,mplay_message_id() 是得到这个消息的识别id,也就是发送的时候参数id的值。mplay_message_value()是返回这条消息的值,也就是参数val里的值;mplay_message_player()是获得发送这条消息的玩家的id;mplay_message_name() 和上一函数差别不大,但是他获得是发送消息的玩家的名字;mplay_message_count(player)是获得参数player玩家发送给你的消息,还未处理的一共有多少条,如果你用0的话,则可以统计你自己目前总共接收了多少没有处理的消息。mplay_message_clear(player)则是清除这些未处理消息,如果是0的话,你可以删除所有未处理的消息。
第三章 服务器与数据

第一节 服务器

    其实这一章已经没有基本知识,基本是基于上两章更深的应用,这里不仅拥有的是理论知
识,而且拥有能够完全搭建服务器传输的完整方法。

    服务器(Server)对于我们来说即是一个集中式主机系统,他给予我们终端设备统一的信号,这样第一可以大幅度减少错误的封包消息,第二可以在游戏的时候最大限度减少玩家的作弊。

    gm建立服务器,其实就是使用mplay_session_create(sesname,playnumb,playername)建立一个多人数的联机~,然后再客户端使用mplay_message_send_guaranteed(player,id,val) 将自己的数据,指定发送给服务器,然后再由服务器用mplay_message_send_guaranteed(player,id,val) 统一把数据返回给所有终端机,这样既完成一次服务器数据收发操作。

    例;重要代码如下:

    服务器


    create event:

    mplay_init_tcpip(mplay_ipaddress())
   
    mplay_session_create('server',250,'admin')

    step event:
基于tcpip协议的文件传输命令是
    player_num = mplay_session_find()

    for ( i = 0 ; i < player_num ; i += 1 )

      {

        mplay_message_receive(0)

        mplay_message_send_guaranteed(0 , 0 , mplay_message_value())

      } 

    客户端

    create event:

    mplay_init_tcpip("服务器ip")

    mplay_session_find()

    mplay_session_join(0,'player001')


    step event:

  mplay_message_send('admin' , 0 ,数据)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。