【游戏客户端】制作你玩我猜Like玩法

news2025/2/21 23:15:20

【游戏客户端】制作你玩我猜Like玩法

 

      大家好,我是Lampard猿奋~~  “你画我猜”相信大家都不陌生,当初这款小游戏可谓茶余饭后必玩之选,风头一时无二。今天要和大家分享如何实现一个你玩我猜Like的玩法。

      我们可以简单的把需求拆成两个个部分:1.绘图功能的实现,2.数据传输方式

      本文不贴代码只讲设计思路,希望能帮助到大家~

(一)绘图功能的实现

(1)画布

    要作画我们首先需要一个画布,画布我们可以在UI编辑器中用一个image控件来显示但是需要注意两个地方:

    首先就是不要用太深的颜色作为底色(你没见过黑色的画布吧,五彩斑斓的黑当我没说...),        再者就是记得画布的透明度最好设置成255,因为之后的绘制是用目标颜色和画布进行混合渲染,因此如果透明度不为255的话,渲染出来的结果可能和设定的画笔颜色会有出入

 

(2)rendertexture类

    紧接着就是要介绍我们实现绘图逻辑的类:RenderTexture类,怎么去理解这个类呢?大家可ui把这个类当作一张白纸,我们想要实现绘制效果,首先要在白纸上画出背景颜色(画布颜色),然后再在画布颜色的基础上,继续增加各式各样我们想要绘制的图形

    此时问题很多的小明就要问了:为啥不直接用UI管理器导入的Image作为真正的画布?还要搞什么白纸的概念呢?

    这是因为我们要实现画笔所划过的地方与画布进行混合渲染,而RenderTexture类支持这个功能,而UI编辑器中封装好的UI类Image和Sprite是不支持的

    RenderTexture类底层是调用了OpenGL的glBlendFunc的混合绘制方法,关于RenderTexture的研究我们在之前做过了。

function clsWidgetScratch:initRenderTexture()
    local renderTexture = cc.RenderTexture:create(self.width, self.height)
	self:addChild(renderTexture)
    renderTexture:addChild(self.drawNode)
    renderTexture:addChild(self.rubberImg)
    return renderTexture
end

    如果大家想了解cocos中如何调用RenderTexture来进行混合绘制,可以看看我之前写的这一篇文章:【游戏客户端】实现刮刮乐效果

    如果大家想要了解RenderTexture的底层openGL渲染逻辑,可以看看这一篇文章:glBlendFunc颜色混合

 

(3)画笔DrawNode

    方才我们已经创建了一个Rendtexture的对象,然后把画布的颜色渲染了上去,紧接着我们只需要创造出画笔绘制的内容,然后和画布进行混合渲染就可以实现我们的绘图功能

    我们知道画画是需要从点到线再到面的,因此我们可以实例化一个带颜色的DrawNode对象用来描绘画笔点下的一个点

    而想要绘制出不同的颜色,只需要调整drawSolidCircle接口中的color字段即可

function clsWidgetScratch:initDrawNode()
    local drawNode = cc.DrawNode:create()
	drawNode:setVisible(true)
    drawNode:setBlendFunc(gl.ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
    drawNode:setLocalZOrder(1000)
	drawNode:drawSolidCircle(cc.p(self.length / 2, self.length / 2), self.length / 2, 360, 10, 1, 1, self.color)
    return drawNode
end

 

(4)调整绘制的位置

    有了画布和Drawnode画出来的点,我们下一步还需要做的就是监听玩家绘制的位置

    首先我们要创建一个监听用的Layout置于最上层,用onTouchMove的方法监听玩家触摸的位置。紧接着把DrawNode的position设置成玩家落笔的位置,然后调用cocos中renderTexture的混合绘制方法即可

 

(5)橡皮擦功能

    画图需求中带有了橡皮擦功能,其实聪明的朋友已经发现,所谓的橡皮擦功能。我们可以简单的把DrawNode的颜色设置为和画布的一样,就可以把之前绘制的内容给覆盖掉了

    好,我们看看目前所实现的效果:

 

(二)数据传输方式的选择

    当看到玩法效果实现出来的时候,我也和大家一样欣喜若狂,以为这个需求快要到尾声了。然鹅,困难的地方还在后面:首先这并不是一个单机玩法,它是多人实时同步的一个游戏。那就意味着你需要把绘制的内容实时同步给所有的玩家,那么问题来了,对于一幅960*640的画布,你要如何进行实时传输呢?

(1)Http协议拉取最新的图片

    首先我们可以想到用类似patch的方式,每当绘制成功后就把内容以png格式上传到资源库中,然后其他猜测的玩家则用http协议去拉取最新的资源

    这样的做法好处是确保绘制内容的准确性和完整性

    坏处是每一次绘制内容的更新,都要去拉取一次资源,我们知道文件的IO是非常耗时的,这样当遇到性能有点卡顿的时候,更新时就会一闪一闪,这样玩家的体验上并不好

(2)RPC协议同步像素内容

    那我们可不可以去同步像素的内容呢?虽然项目的每一个像素点用的都是RGBA8888的格式记录,也就是说一个像素需要32位,但我们实际只用到了8个颜色,且透明度都是255,因此我们完全可以用8个bit去映射记录每个像素的信息

 

    但是虽然如此优化了,但每一个像素也需要用到1B的大小去记录,而我们有960*640个像素,960 * 640 / 1024,算下来我们还要用到600KB的数据去传输这个画面。

    但由于处于性能压力的监控,服务端很早之前就闲置了,每次使用RPC协议,不能交互超过100KB的数据,因为如果我们需要用到这种做法,我们还得进一步优化:可以把画布分块,像场景地图那样切成小块去分开传输,总的来说也算是一种思路

    这种做法好处是确保了画面的准确性,以及省去了IO的时间

    坏处是需要分块请求画面内容,比较难确保每次数据传输我每一小块的内容都可以准确的获取数据和显示

 

(3)RPC协议同步绘制流程

    其实第二种的思路已经很接近正解了,但是唯一问题就是不想采用分块的方式,想完完整整的一幅图片同步给玩家。因此我想到了第三种方法:记录玩家的绘制流程,用RPC协议同步玩家的绘制记录。

    什么意思呢?首先我们把整一个画布划分成一个3*3,或者4*4像素方块组成的整体。然后我们用一个二维数组去记录这些小方块是否被绘制,绘制的颜色映射是什么。

    每当玩家绘制的时候,我们就更新二维数组中该小方块的映射值,然后把这个二维数组的记录信息,以二进制数据的形式拼接在一起上传。同时参与的玩家通过RPC协议获取最新的绘制信息,然后解码成二维数组,重新根据绘制信息重新把内容“画”出来

    这样我们就可以把3*3或者4*4的像素信息融合成一份,虽然会有一些锯齿感和多花了时间进行编码和解码,但是成功把数据压缩到了100K以内,且避免了IO的卡顿

local NORMAL_LENGTH = 3

local i  = math.floor(y / NORMAL_LENGTH)
local j  = math.floor(x / NORMAL_LENGTH)
self.nodeList[i*NORMAL_LENGTH][j*NORMAL_LENGTH] = self:getEncodeNodeIndex()

(三)最后看看我们最终的效果

你画我猜玩法视频

     至此你画我猜玩法的分享到此结束~~

      感谢阅读,点赞,关注!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/849674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像预处理——CV

目录 1.图像预处理 1.1 图像显示与存储原理 1.2 图像增强的目标 1.3 点运算:基于直方图的对比度增强 1.4 形态学处理 1.5 空间域处理:卷积 1.6 卷积的应用(平滑、边缘检测、锐化等) 1.7 频率域处理:傅里叶变换…

Seata - 入门笔记

1、事务 访问并可能更新数据库中数据库中各种数据线的一个程序执行单元 原子性:事务是一个不可分割的工作单位,一个事务要么都做要么都不做 一致性:必须是使数据库从一个一致性到另一个一致性的状态,中间状态不能被观察到 隔离…

Python爬虫在电商数据挖掘中的应用

作为一名长期扎根在爬虫行业的专业的技术员,我今天要和大家分享一些有关Python爬虫在电商数据挖掘中的应用与案例分析。在如今数字化的时代,电商数据蕴含着丰富的信息,通过使用爬虫技术,我们可以轻松获取电商网站上的产品信息、用…

明年,HarmonyOS不再兼容Android应用!

2023年华为开发者大会,不知道各位老铁们是否观看了,一个震撼的消息就是,首次公开了HarmonyOS NEXT的概念,简而言之就是,这是一款专为开发者打造的预览版操作系统,旨在提供"纯正鸿蒙操作系统"的体…

2023年果粉装机必备软件有哪些?Macbook电脑需要安装什么软件

作为一名从Windows全面切换到Mac的果粉,在一开始的时候确实感到诸多不便,比如文件管理器操作别扭,鼠标移动不够跟手等等。 后来才发现,除了游戏,大多数问题都能用软件来解决。Mac虽然小众,但是用户群体有很…

84. 柱状图中最大的矩形

题目描述 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入:heights [2,1,5,6,2,3] 输出:10 解释:最…

林【2018】

关键字: BST插入叶子结点、ADT结伴操作、队列插入前r-1、哈希函数二次探测法(1,-1,4,-4)、队列元素个数、折半查找失败次数、广义表链表结构、B-树构建、单链表指定位置插入数组元素 一、判断 二、单选 h(49)+1,-1,+4,-4

什么是动态测试?

作为一名测试人员,要对各种测试方法了然于胸,今天这篇文章就来介绍下什么是动态测试。采用动静结合的测试方式,挖掘出程序中存在的问题,以更好地保证测试质量。同时,我也准备了一份软件测试视频教程,放在文…

水壶问题(力扣)数学 JAVA

有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 targetCapacity 升。 如果可以得到 targetCapacity 升水,最后请用以上水壶中的一或两个来盛放取得的 targetCapacity 升水。 你可以&…

echarts 横向柱状图

<template><div ref"chart" style"height: 100%"></div> </template><script> import * as echarts from "echarts"; var cate ["质量通病1", "质量通病2", "质量通病3", "质…

LeetCode 热题 100 JavaScript--160. 相交链表

/*** Definition for singly-linked list.* function ListNode(val) {* this.val val;* this.next null;* }*//*** param {ListNode} headA* param {ListNode} headB* return {ListNode}*/// 1、暴力解法 var getIntersectionNode function(headA, headB) {var p1 …

大英博物馆将世界历史带入 The Sandbox 元宇宙

又一个知名的、历史领域合作伙伴加入了我们的元宇宙生态系统&#xff01; 大英博物馆选择 The Sandbox 作为其首次进入元宇宙的合作平台。通过这次合作&#xff0c;我们的用户将能够通过全新的沉浸式体验来探索全球历史。 以下是您需要了解的一切&#xff01; 我们正在与大英…

测试工程师如何利用AIGC高效工作?Chat PDF辅助我们写测试用例和脚本

ChatPDF 是一种基于人工智能的工具&#xff0c;用于将 PDF 文档转换为可交互式的聊天式界面。它能够将静态的 PDF 文件转化为动态的聊天对话框&#xff0c;使用户可以通过对话的形式与文档进行交互。 ChatPDF 可以完成以下工作&#xff1a; 1. 将 PDF 文档转换为聊天式界面&am…

H. HEX-A-GONE Trails 2023“钉耙编程”中国大学生算法设计超级联赛(7)hdu7354

Problem - 7354 题目大意&#xff1a;有一棵n个点的树&#xff0c;A和B分别从点x&#xff0c;y开始&#xff0c;每轮可以移动到一个相邻节点&#xff0c;但如果某个节点有人访问过&#xff0c;则两人都不能访问那个节点&#xff0c;先没有点可走的人输&#xff0c;问A有没有必…

pytest之测试用例执行顺序

前言 在unittest框架中&#xff0c;默认按照ACSII码的顺序加载测试用例并执行&#xff0c;顺序为&#xff1a;09、AZ、a~z&#xff0c;测试目录、测试模块、测试类、测试方法/测试函数都按照这个规则来加载测试用例。 而 pytest 中的用例执行顺序与unittest 是不一样的&#…

CTF流量题解http4.pcapng

流量分析 导出http 打开报错 验证文件头&#xff0c;发现是zip。 图常片见里文可件能的包16含进:压制缩头包部,word,pdf JPG FF D8 FF E0/FF D8 FF E1 PNG 89 50 4E 47 GIF 47 49 46 38 ZIP 50 4B 03 04 RAR 52 61 72 21 MP3 49 44 33 0 改后缀 使用工具爆破。 git clone git…

牛客周赛 Round 6

A 游游的数字圈 题目大意 给定一个由数字字符组成的字符串&#xff0c;统计该字符串中出现的圆圈数量。其中数字0、6、9各有一个圆圈&#xff0c;数字8有两个圆圈。 思路分析 遍历字符串中的每个字符&#xff0c;对于每个字符&#xff0c;判断其是0、6、9则加1&#xff0c;是…

网络安全--mysql中事务锁以及事务隔离解析

一、事务锁 1、个人理解&#xff1a; 专一性和历史性&#xff0c;例如一个男人历史上是花心的&#xff0c;但当他成长后开启begin和update后变的专一了&#xff0c;多项事务也影响不到他了&#xff0c;直到水泥封心&#xff0c;只可被一个人查询在此我们进入正题&#xff1a;…

【代码】表格封装 + 高级查询 + 搜索 +分页器 (极简)

一、标题 查询条件按钮&#xff08;Header&#xff09; <!-- Header 标题搜索栏 --> <template><div><div class"header"><div class"h-left"><div class"title"><div class"desc-test">…

《动手学深度学习》优化算法学习习题

优化算法 梯度下降类 小批量随机梯度下降&#xff0c;通过平均梯度来减小方差 动量法 基础 泄露平均法&#xff1a;用来取代梯度的计算 β \beta β这个参数控制了取多久时间的平均值 上述推理构成了”加速”梯度方法的基础&#xff0c;例如具有动量的梯度。 在优化问题…