【游戏客户端】大话slg玩法架构(三)建筑控件

news/2024/12/23 0:54:33/

 【游戏客户端】大话slg玩法架构(三)建筑控件

      大家好,我是Lampard家杰~~ 今天我们继续给大家分享SLG玩法的实现架构,关于SLG玩法的介绍可以参考这篇上一篇文章:游戏客户端】制作率土之滨Like玩法

       PS:和之前一样,本文也只是分享实现思路,并不会贴具体的代码和资源哟

 (一)架构总览

      SLG玩法的实现思路可以划分为四个部分,分别是滚动容器基类的搭建,背景大地图的实现,建筑的生成与刷新,以及玩法优化预加载相关

      上一篇文章我们分享了背景大地图的实现:【游戏客户端】大话slg玩法架构(二)背景地图,现在我们接着分享玩法的重中之重!!!建筑控件的实现逻辑

 (二)建筑控件的实现

(1)控件的结构

      建筑是玩法中的核心逻辑,玩法就呈现在每一个建筑的UI上。因此整理好一个建筑控件的展示结构与层级关系是很有必要的

      比如帮派纷争设计的建筑层级就是:建筑状态底板(我方=蓝色,敌方=红色,中立=白色) < 建筑纹理 < 建筑UI(名字,坐标,头像等) < 交互按钮(如分享,战报)  < 特效表现 (战斗中,免战状态等)

BUILD_PRIORITY = {BG = 1,TEXTURE = 2,UI_NODE = 3,BUTTON = 4EFFECT = 5,
}

      其中建筑UI内容也有需要,它们也需要细分一个显示层级,因此可以先往建筑上挂一个UINode,然后把建筑UI挂在这个节点上再细分即可

(2)控件的生成逻辑

    和大地图一样,首先第一步要知道这个控件生成出来之后要摆放到哪里。帮派纷争是一个77 * 77的小型slg玩法,那么我们将会有77 * 77个建筑位置。     

      每一个位置的建筑我们都可以通过接口计算出它在滚动容器上的坐标

function getPosById(Idx, Idy)-- BG_WIDTH = 大地图宽度-- BG_HEIGHT = 大地图高度-- BG_NUM = 每一行/列的地图块数量local PosX = (BG_WIDTH / 2) * (Idx + Idy - 1)local PosY = (Idy - Idx + BG_NUM) * (BG_HEIGHT / 2)return PosX, PosY
end

       我们可以用一个Table去存生成的建筑对象,如果是1*1的数据(如下图)我们就可以直接赋值BuildMap[2][2] = 生成的建筑对象

        如果是X * X的建筑,我们会把建筑对象记录左下角的坐标,如下图BuildMap[10][13] = 生成的建筑对象。那其余的位置怎么办呢?很简单,我们可以标识一个特殊的建筑类型--阻碍建筑,把其余八个位置标记为阻碍,玩家就不能迁城进攻到这些地方来了

 

(3)控件的数据获取

      这是一个多人的实时同屏的玩法,因此建筑的所有数据(等级,占领状态等)都依赖服务端进行下发

       把所有的数据一条协议下来那肯定是不科学的,我们用不上那么多数据,而且数据量太多协议肯定是顶不住。因此我们可以采取AOI的方式,根据目前所视的地图位置请求一定范围的建筑数据

      比如目前所示的视野中心是(8,14),我们只需要请求以(8,14)为原点,半径为5的建筑数据(当然可以预留一些避免滑动时穿帮)。并且我们可以在滚动的时候设置监听事件,如果滑动距离超过一定阈值,那么我们就再次请求数据

      PS:视野中心需要根据滚动容器InnerContainer当前所在位置进行换算,半径也需要根据不同机型的分辨率进行计算

      此时有一个好奇的朋友就会问了,如果我生成建筑的时候,建筑数据还没回来怎么办呢?

      这个很简单哈,只需要把返回的服务端数据缓存起来!!在数据回来的时候判断一下该位置的建筑生成了没有,如果没生成那么不用管它,它自然会从缓存中读取正确的数据。如果发现已经生成了,那也不要慌,同样先把数据缓存起来,然后执行一下那个建筑对象的update方法让其更新即可~~

(4)控件的刷新逻辑

    和地图块一样我们不会生成所有的建筑。同样采取控件缓冲池的方式,在进游戏前先生成一堆建筑对象,然后根据目前所示的位置,更新建筑对象的信息以及位置摆放。从而使极限的建筑数量从77*77 转化为两三百个

-- 释放
for x = 1, 77 dofor y = 1, 77 dolocal IsInView = 判断一下这一块建筑需不需要显示if not IsInView and self.BuildMap[x][y] thenlocal Build = self.BuildMap[x][y]Build:setFree()self.BuildMap[x][y] = nilendend
end-- 生成
for x = 1, 77 dofor y = 1, 77 dolocal IsInView = 判断一下这一块建筑需不需要显示if IsInView thenif self.BuildMap[x][y] then-- 存在这个建筑就设置可视就行local Build = self.BuildMap[x][y]Build:setVisible(true)else-- 不存在则找一个空闲的建筑控件重设信息local Build = getFreeBuild()self.BuildMap[x][y] = Build Build:resetInfo(x, y)endendend
end

       这里需要注意的是,getFreeBuild的时候,由于玩家可能会疯狂拖动导致建筑对象setFree不及时,那么就可能造成读取不到空闲的建筑对象,因此需要做一个保底处理,如果读不到的时候生成一个新的,然后塞进去缓冲池中即可

      除了玩家的操作导致需要刷新建筑,还有可能其他人进行了操作,服务端需要同步最新的结果来更新显示。此时我们只需要和上文一样,在服务端下发新建筑数据时进行判定,有则更新,无则缓存即可

       好啦~~建筑的生成介绍大概就到这里,下一篇文章会介绍这个玩法的预加载相关

      感谢阅读,记得点赞和关注!!!


http://www.ppmy.cn/news/1475757.html

相关文章

Spark核心技术架构

Apache Spark是一个开源的分布式计算系统&#xff0c;它提供了一个快速、通用和易于使用的集群计算环境。Spark 支持多种编程语言&#xff0c;如 Scala、Java 和 Python&#xff0c;并针对大规模数据处理进行了优化。以下是 Spark 技术架构的详细简述&#xff1a; 1. 核心组件…

ConfigMap-secrets-静态pod

一.ConfigMap 1.概述 ConfigMap资源&#xff0c;简称CM资源&#xff0c;它生成的键值对数据&#xff0c;存储在ETCD数据库中 应用场景&#xff1a;主要是对应用程序的配置 pod通过env变量引入ConfigMap&#xff0c;或者通过数据卷挂载volume的方式引入ConfigMap资源 官方解释…

部署PXE高效批量网络装机

目录 一、系统装机 1、系统装机的方式 2、系统的安装过程 3、Linux安装光盘的相关文件 二、PXE&#xff08;Preboot eXecution Environment&#xff09; 1、PXE概述 2、运行PXE 批量部署的优点 3、pxe实现的硬件条件 4、运行PXE的实现过程 5、PXE的实现操作 5.1、安…

零信任的架构结合模块化沙箱,实现一机两用的解决方案

零信任沙箱是深信达提出的一种数据安全解决方案&#xff0c;它将零信任原则与SDC沙箱技术的优势相结合。零信任原则是一种安全概念&#xff0c;核心思想是“永不信任&#xff0c;总是验证”。它要求对每一个访问请求都进行严格的身份验证和授权&#xff0c;无论请求来源于内部还…

在大型企业级应用中,如何优化 XML 数据的存储和检索效率,以满足高并发访问需求?

在大型企业级应用中&#xff0c;优化XML数据的存储和检索效率可采取以下措施&#xff1a; 数据库选择&#xff1a;选择适合XML存储和查询的数据库&#xff0c;如Oracle、MySQL、PostgreSQL等。这些数据库提供了专门的XML存储和查询功能&#xff0c;能够更高效地处理XML数据。 …

在微服务架构架构中父工程中的`<dependencyManagement>`和 `<dependencies>`的区别

在微服务架构架构中父工程中的<dependencyManagement>和 <dependencies>的区别&#xff1a; 在微服务架构中&#xff0c;通常会有一个父工程&#xff08;或称作聚合工程&#xff09;来管理一组相关的子模块&#xff08;即各个微服务&#xff09;。Maven 的 <de…

无人机图像目标检测

本仓库是人工智能课程的课程作业仓库&#xff0c;主要是完成无人机图像目标检测的任务&#xff0c;我们对visdrone数据集进行了处理&#xff0c;在yolo和ssd两种框架下进行了训练和测试&#xff0c;并编写demo用于实时的无人机图像目标检测。 requirements依赖&#xff1a; ss…

使用 OpenCV 的 inRange 函数进行颜色分割

使用 OpenCV 的 inRange 函数进行颜色分割 在图像处理领域&#xff0c;颜色分割是一个常见的任务&#xff0c;常用于识别和提取图像中的特定颜色区域。OpenCV 提供了一个非常方便的函数 inRange 来实现这一功能。在这篇博客中&#xff0c;我们将详细介绍 inRange 函数的用法&a…