Gamemaker studio2经验(2)——TCP联机

2023-11-06

问题概述

众所周知gamemaker是一款制作2d游戏的优秀引擎,但是落后的弱联网机制始终是一个坑。所幸在gms2中,yoyogames集团加入了TCP的联机机制,这也为gm系列引擎制作联网游戏带来了希冀。
下面用一个最简单的“红蓝球游戏”作为我们的联机用例。用例的基本描述如下:
进入游戏先选择host和join,host方以红球身份进入房间,join方以蓝球身份进入房间。双方都以WSAD为移动方式,并且双方在屏幕上需要看得到对方的球被操控移动。

代码实现

首先声明一下,如果点击host,那么给全局变量global.net赋值1,如果点击join则赋值2,表示现在玩家是以什么样的身份进入游戏。
之后host方进入一个房间,这个房间有一个obj_server,join方进入另一个房间,这个房间有一个obj_joiner。

obj_server

创建

第一行表示创建一个新的tcp连接,括号中第一个参量是tcp的写法,第二个参量是端口(自定),第三个参量是客户端数量的上限(尽量不超过1000)
sendmes表示服务器要发送的数据内容,刚开始不发送的时候先清零
timer是一个计时器,规定每5步发送一次数据

network_create_server(network_socket_tcp,250,10);
sendmes=0;
timer=5;

步事件

这里面需要介绍一下buffer。buffer是一种缓冲区,可以起到优化空间的效果,而游戏引擎里也将buffer作为发送数据的载体,因此我们定义一个新的缓冲区buf。
发送的数据sendmes赋值为红球(即host方)的x值+y值×1000,因为我这里的地图坐标上限是999,因此这样一个六位数可以把x坐标和y坐标都储存下来,最后发送一个数字就可以了。
当计时器timer减到0并且判定网络连接已经连接成功了(global.connect==1),我们开始处理发送数据的事情。(具体怎么判定网络连接成功见后文)
首先要使用buffer_create()函数申请一个buffer(类似malloc)。第一个参量是缓冲区的容量,这个可以尽量大一点;第二个参量是buffer的类型,这个可以参考下表

类型 描述
buffer_fixed A buffer of a fixed size in bytes. The size is set when the buffer is created and cannot be changed again.
buffer_grow A buffer that will grow dynamically as data is added. You create it with an initial size (which should be an approximation of the size of the data expected to be stored), and then it will expand to accept further data that overflows this initial size.
buffer_wrap A buffer where the data will wrap. When the data being added reaches the limit of the buffer size, the overwrite will be placed back at the start of the buffer, and further writing will continue from that point.
buffer_fast This is a special “stripped down” buffer that is extremely fast to read/write to. However it can only be used with buffer_u8 data types, and must be 1 byte aligned. (Information on data types and byte alignment can be found further down this page).

第三个参量是数据排列字节数,详情可见gms2中万能的F1说明,这里不再赘述。
申请完缓冲区后,便可以使用buffer_write()函数向缓冲区中写入数据。第一个参量为声明的缓冲区,第二个参量为数据类型(具体写哪个数据类型可以F1自己查),第三个便是要发送的数据内容。
写完后,使用network_send_packet()函数发送你的数据包,第一个参量是接收对象,第二个参量是写好的缓冲区,第三个参量是总尺寸,这个写buffer_get_size()是绝对没错的。
发送完后,你的缓冲区就没有意义了,因此需要用buffer_delete()函数释放空间

var buf;
sendmes=global.redx+global.redy*1000;
if(timer>0)timer-=1;
if(global.connect==1&&timer<=0)
{
	buf=buffer_create(10000,buffer_fixed,4);
	buffer_write(buf,buffer_u32,sendmes);
	network_send_packet(client,buf,buffer_get_size(buf));
	buffer_delete(buf);
	timer=5;
}

绘制事件

打印出getmes的内容,这里纯粹是为了方便debug。

draw_text(5,5,getmes);

Async-Networking

Async本质上就是一种需要特殊条件才能触发的步事件,例如Networking就是一种触发条件,顾名思义就是“只要连接上网络了就触发”。当客户端成功连接上这里的服务器后,我们的服务器就会进入到这里,开始处理连接成功以后的琐事。
首先,我们需要再引入一个新概念:“map”。
我们理解map为一个外交官,当两国进行交涉后,外交官将会得到很多信息,比如他国的地理位置、他国的国际代号、他国接下来想做些什么等等等等。
这时候,我们想要从外交官那里套得信息,不能简单地问:“嘿,外交官,你知道关于X国的什么信息了”,这样太笼统。正确的问法是:“嘿,外交官,X国的地理位置在哪?”“嘿,外交官,X国的国际代号是什么?”“嘿,外交官,X国现在想对我国做些什么?”
这里面map就如同外交官一样,当服务器与客户端成功连接,那么map就会身为服务器的外交官与客户端进行交涉,之后他会得到若干种信息,分别是:

信息类型 含义
type 客户端的动机(X国想做什么?)
socket 客户端的id(X国的代号是什么?)
ip 客户端的地理位置(X国的地理位置是什么?)
buffer 客户端发来的数据(X国想跟我们说什么?)

这个应该很好懂,不多赘述。接下来开始写代码:
首先我们要赋予map这个使命,让他=async_load
然后!我们可以通过ds_map_find_value(map,“type”)来获取客户端的动机(动机可以有很多,比如联网,比如发送数据,比如失去连接)
这时候把他的动机赋值给一个新变量type,然后接下来检测:如果动机是连接上了(type==network_type_connect),那么我们就让global.connect=1,此时client和ip分别运用ds_map_find_value()获取客户端的id和地址。
如果动机是接受到客户端发来的数据了,那么我们就创建一个新的缓冲区,来接受发来的缓冲区,并使用buffer_read()函数来提取缓冲区的数据,放到getmes中。之后呢,x值和y值就可以由接收到的6位数来确定了。

var map=async_load;
var type=ds_map_find_value(map,"type");
if (type==network_type_connect)
{
	global.connect = 1;                             //表示连接上了
	client=ds_map_find_value(map,"socket");         //client表示接受的客户id
	ip=ds_map_find_value(map,"ip");
}
if (type==network_type_data)
{
	buffer_create(10000,buffer_fixed,4);
	buf=ds_map_find_value(map,"buffer");
	getmes=buffer_read(buf,buffer_s32);
	global.bluex=getmes mod 1000;
	global.bluey=getmes / 1000;
}

obj_joiner

对于客户端,首先我们要定义一个socket(即id),表示我们创建了一个tcp类型的接入口,然后通过network_connect()函数来连接服务器。第一个参量是刚创建的socket,第二个参量是服务器的地址,第三个参量是服务器的端口。

创建

socket=network_create_socket(network_socket_tcp);
network_connect(socket,"XXXXX",250);

步事件

这里面的内容和obj_server异曲同工(几乎一样),不再赘述

var buf;
sendmes=global.bluex+global.bluey*1000;
if(global.connect==1)
{
	buf=buffer_create(10000,buffer_fixed,4);
	buffer_write(buf,buffer_u32,sendmes);
	network_send_packet(server,buf,buffer_get_size(buf));
	buffer_delete(buf);
}

绘制事件

同上

draw_text(5,5,getmes);

Async-Networking

对于客户端而言,核心服务器永远只有一个,因此一旦连接成功,我们不需要判定type是否为network_type_connect便可以开始连接后的操作。

map=async_load;
type=ds_map_find_value(map,"type");
server=ds_map_find_value(map,"id");         //server表示服务器的id
global.connect = 1;                             //表示连接上了
if (type==network_type_data)
{
	buffer_create(10000,buffer_fixed,4);
	buf=ds_map_find_value(map,"buffer");
	getmes=buffer_read(buf,buffer_s32);
	global.redx=getmes mod 1000;
	global.redy=getmes / 1000;
}

之后服务器和客户端每帧都会收到一个getmes,确定完x和y后便将小球按这个坐标进行定位即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Gamemaker studio2经验(2)——TCP联机 的相关文章

  • 纯Numpy实现多层神经网络

    纯Numpy实现多层神经网络 本文分为以下几个内容 1 实现层的逻辑结构 2 实现各种激活函数 3 实现Dense层 4 实现前向传播 5 实现反向传播 6 示例 实现网络层的逻辑 首先实现一个简单的网络层 该网络层什么也不做 就是前向传播
  • Ubuntu指令之:统计指定类型文件的数目。eg:json、jpg

    ls grep 和 wc 命令统计指定类型文件数目的技巧 命令之间的交互通过命名管道完成 grep 用户根据给定模式或正则表达式进行搜索的命令 wc 用于统计行 字和字符的命令 1 普通文件的数目 用符号 表示 ls l grep wc l
  • ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.解决方案

    刚刚下载python3第三方库 下载速度真的慢 而且下载超过时间就会报错 真的心态崩了 下面提供我找到的解决方案 解决方法 1 设置控制超时 pip install default timeout 1000 包的名称 2 更换pip下载源
  • 可以说说猿如意的基本功能以及作用是什么啊?

    猿如意是一款软件工具 它的基本功能是帮助用户编写 调试和执行 Python 代码 它可以作为一个集成开发环境 Integrated Development Environment IDE 来使用 也可以作为一个单独的代码编辑器使用 猿如意提
  • LaTeX - 设置中文字体

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 第一步 字体从电脑导出 Window R输入cmd回车 输入fc list f family n lang zh gt d zhfont txt 回车 enter键 可以用
  • 高斯噪声

    高斯噪声 图像噪声之高斯噪声 gauss noise 概述 高斯噪声是指它的概率密度函数服从高斯分布 即正态分布 的一类噪声 与椒盐噪声相似 Salt And Pepper Noise 高斯噪声 gauss noise 也是数字图像的一个常
  • 【正点原子MP157连载】第五章 ATK-STM32MP157文件系统简介-摘自【正点原子】STM32MP157快速体验

    第五章 ATK STM32MP157文件系统简介 5 1 文件系统目录简介 5 2 文件系统Qt版本 5 3 如何创建systemd 自启动服务 5 4 如何禁用Qt界面启动 1 实验平台 正点原子STM32MP157开发板 2 购买链接
  • 红帽文件系统满了服务器启动不了,红帽系统盘问题汇总解答.doc

    红帽系统盘问题汇总解答 PAGE PAGE 1 作者 日期 PAGE NUMPAGES 做题盘问题汇总 备注 必须64位的机子 问题1 视频里的那个开始的脚本 O号0根不分不清 答 没有零都是大写的O 问题2 那我打了零 CSR证书可能要重
  • eclipse下新建maven web工程(是web工程!)以及部署maven web工程到tomcat服务器

    一 eclipse新建maven web工程 1 在菜单栏File gt New下面找到Maven Project 2 勾选上Create a simple project 不使用骨架 Next 3 填写工程名称和包名 并选择war类型 一
  • 支持向量机SVM的学习

    20201102 0 引言 支持向量机作为一种常用的机器学习算法 应用非常广泛 原始的SVM只能支持线性数据 而通过核函数的方式 可以使其应用于非线性数据 之前学习过SVM的具体过程 也在sklearn中进行过调优 但是都没有记录 而且上次
  • 4.2 计算机体系结构——存储层次结构——cache工作原理

    cache是小容量 高速缓冲存储器 由SRAM组成 速度几乎和CPU一样快 一般将cache和主存的存储空间都划分为若干大小相同的块 1 cache工作原理 根据时间局部性和空间局部性 当处理器访问一块数据时 它很可能再次访问这块数据或者访
  • 【Spring AOP】Spring AOP快速使用

    文章目录 前言 1 相关注解 类注解 方法注解 2 execution 表达式 例一 execution 表达式 的限制使用 例二 execution 表达式 的通配使用 3 相关pom依赖 4 案例 创建接口 Aop使用 方式一 Befo
  • struts2中各个jar包作用

    Struts2 3 4 所需的Jar包及介绍 Jar包的分类 jar包名称 jar包版本 jar包 文件名 jar包 的作用 jar包内包含的主要包路径及主要类 依赖的自有jar包名称 依赖的第三方jar包名称 本jar包是否为第三方包 S
  • Hash算法特点

    2 2 Hash算法有什么特点 一个优秀的 hash 算法 将能实现 正向快速 给定明文和 hash 算法 在有限时间和有限资源内能计算出 hash 值 逆向困难 给定 若干 hash 值 在有限时间内很难 基本不可能 逆推出明文 输入敏感

随机推荐

  • 第十届蓝桥杯省赛C++B组 等差数列

    数学老师给小明出了一道等差数列求和的题目 但是粗心的小明忘记了一部分的数列 只记得其中 N 个整数 现在给出这 N 个整数 小明想知道包含这 N 个整数的最短的等差数列有几项 输入格式 输入的第一行包含一个整数 N 第二行包含 N 个整数
  • 理解TCP/IP、HTTP、FTP、 NTP、 SNMP、VRRP等常用协议(FTP)

    FTP 概述 文件传输协议 FTP 作为网络共享文件的传输协议 在网络应用软件中具有广泛的应用 FTP的目标是提高文件的共享性和可靠高效地传送数据 在传输文件时 FTP 客户端程序先与服务器建立连接 然后向服务器发送命令 服务器收到命令后给
  • redis常用命令

    一 key 相关 1 redis允许模糊查询 key keys 有3个通配符 2 randomkey 返回随机key 3 type key 返回key存储的类型 4 exists key 判断某个key是否存在 5 del key 删除ke
  • 【颜值检测神器】来,请拿出你们的绝活(这颜值,对得起观众么?)

    前言 作者 程序员梨子 文章简介 本篇文章主要调用百度接口制作一款颜值检测小工具啦 文章源码获取 为了感谢每一个关注我的小可爱 每篇文章的项目源码都是无偿分 享滴 点这里蓝色这行字体自取 需要什么源码记得说标题名字哈 私信我也可 欢迎小伙伴
  • 9.全志H3-修改DDR的速度

    上面是我的微信和QQ群 欢迎新朋友的加入 前一篇文章 为了测试我自己画的板子 查了下关于uboot源码 降低DDR的速度 我使用的是友善之臂提供的源码 不多说其他的了 在源码里面 查找下图的文件 打开文件 修改图示内容就行 下面是启动的打印
  • 【java】兴唐第二十三节课作业

    已知如下 下表为某班级四次考试成绩单 要求使用HashMap
  • 万网域名如何设置显性url转发和隐性URL转发

    原文链接 http www enkj com idcnews Article 20161025 9580 URL转发技术就是将该域名的网站访问请求 通过浏览器端技术 转向到另外一个网站 如果跳转后 浏览器地址栏还是该域名 称为隐性URL转发
  • 眼底图像血管分割数据集_一个图像分割任务的Hello World项目(UNet+眼底血管分割)...

    庖丁解牛式的学习 才是真正的事半功倍 这是CVHub公众号的第七篇原创文章 也是 学术小白也能看懂的学术进阶专栏 计算机视觉方向 的第七篇文章 导读 在基于深度学习的医学影像分割任务中 基本在哪都能看到 U Net 的影子 这是一篇发表于
  • Protocbuf使用和安装

    Protocol buffers和mxl一样在序列化数据结构时很灵活 高效和智能 但是它的优势在于定义文件更小 读取速度更快 使用更加简单 目前protocol buffers支持C java和python三种语言并且独立于平台 linux
  • 了解硬盘的电路组成部分

    一 硬盘电路组成 硬盘电路板是将硬盘内部和电脑主板相互连接的中介 它将接口传送过来的电信号转换成磁信息记录到硬盘盘片上 写操作 反过来也可以将硬盘盘片上的磁信息转换成电信号传送到接口 读操作 硬盘电路板是裸露在外面的 因此也是比较容易出现故
  • Idea安装免注册版ChatGPT

    文章目录 一 前期准备 二 开始使用 一 前期准备 1 准备Idea开发软件并打开 VS Code同理 2 Ctrl Alt S 快捷键调出Settings窗口 如图 3 找到NexChatGPT 此插件不需要注册 可以直接使用 高级一些的
  • java中Synchronized和Lock的区别

    Synchronized和Lock的区别 原始构成 synchronized关键字属于JVM层面的 通过monitorenter monitorexit指令实现 底层是通过monitor对象来完成 其实wait notify等方法也依赖mo
  • Linux下安装QT4.3.2

    安装qt是因为我刚安装过mplayer想装个前端上网 一查 很多都推崇用smplayer 我也就下决心装上 刚开始一直都装不上 后来静心读了读Install文件才明白要装smplayer必须要有qt4 2或者更高版本 用rpm qa qt才
  • 短视频矩阵营销系统技术开发者开发笔记分享

    一 开发短视频seo抖音矩阵系统需要遵循以下步骤 1 确定系统需求 根据客户的需求 确定系统的功能和特点 例如用户注册登录 视频上传 视频浏览 评论点赞等 2 设计系统架构 根据系统需求 设计系统的整体架构 包括前端 后端 数据库等组件的功
  • 使用.NET构建登录网站

    摘要 本文将介绍如何使用 NET框架构建一个简单的登录网站 并附带每段代码的解释和讲解 帮助读者了解相关概念和功能 引言 在现代互联网应用中 登录系统是一个常见的功能模块 本文将使用 NET框架来创建一个简单的登录网站 演示如何进行用户认证
  • QT UDP简单的通信示例

    UDP user datagram protocol 即用户数据协议 是一个轻量级的 不可靠的 面向数据报的无连接协议 在qt中提供了QUdpSocket类来进行UDP数据报的发送和接收 在Pro中加入network模块 因为upd是无连接
  • 线性代数基础(变换)

    本文中的图片 公式等来自 GMAES101 在此向作者表达真挚的感谢 一 为什么要引入齐次坐标 平移变换不能用一个矩阵来表示 它不是线性变换 在缩放或者旋转等变换操作后 需要单独用一个向量来表示 这样表示起来就不方便了 根据以上约定 会有以
  • spring boot配置druid(德鲁伊)

    spring boot配置druid 德鲁伊 关于druid的介绍请看 阿里巴巴温少访谈 1 引入相关依赖 全部依赖是上一篇spring boot mybatis依赖的基础上 再加上下边的依赖 如下
  • [note] deep learning tensorflow lecture 1 notes 深度学习笔记 (1)

    1 logistic classifier model W X b Y where W is the Weights Vector X is input vector b is bias and Y is output Y the outp
  • Gamemaker studio2经验(2)——TCP联机

    问题概述 众所周知gamemaker是一款制作2d游戏的优秀引擎 但是落后的弱联网机制始终是一个坑 所幸在gms2中 yoyogames集团加入了TCP的联机机制 这也为gm系列引擎制作联网游戏带来了希冀 下面用一个最简单的 红蓝球游戏 作