当前位置: 首页 > news >正文

通用游戏地图解决方案设计解析

前言:

在软件开发过程中,我们都希望能设计出一个稳健的,可维护的系统,为了实现这个目的,人们总结出了很多相关的设计原则,比如SOLID原则, KISS原则等等。SOLID每个字母代表了一种设计原则,具体大家可以去看《架构整洁之道》这本书或者在网上找相关的博客学习。在本系统中将应用这些原则,力求得到一个可用好用可理解可改动的通用地图模块。SOLID原则中的D,指的是Dependence Inversion Principle,中文可以叫依赖倒置原则或者依赖反转原则。其强调的是在处理依赖关系时,应当尽可能依赖抽象类型,而不是具体实现。 在绝大多数情况下,抽象的东西是稳定的,在设计这个抽象类或者接口时,我们往往会带着前瞻性的思维去考虑,这个接口设计得是否合理?是否方便使用者去实现去拓展?如果一个抽象的对象发生变化了,那对应的所有实现一定会发生改变,而如果具体实现发生变更,不会影响到抽象接口。因此我们有理由判定,接口是不太容易变更的,如果一个接口被反复修改,那一定是设计这个接口的时候有地方不合理:接口承担的内容过多;或者是接口方法不够通用,带进来了一些业务相关的东西。依赖反转原则也是本文主要讨论的原则。

正文

结构组成

本系统主要由三部分内容组成,一个是基础的数据结构模块,一个是寻路模块,一个是地图模块。三个模块功能内聚,但也存在耦合,为了防止一个模块修改导致其他模块发生变更,所以在耦合时,尽量使其仅依赖其他模块中的接口,因此模块具体实现修改并不会导致其他模块受到影响。下面将简单介绍这三个模块的内容与设计思路。

数据结构模块

基础的数据结构模块提供了一个最小堆和最大堆,这是具体的实现,其目的是为寻路模块提供服务的,寻路模块直接依赖了数据结构模块,如果从设计的角度出发,这其实是不应该的,因为前面说了我们要依赖抽象类或接口,而不是具体实现,不过我们也可以发现,最小堆和最大堆相对来说是一个较稳定的东西,其设计完成一旦通过验证,就不太会有理由再去修改它们,因此可以认为这个虽然是具体实现,但是是一个不容易发生变更的具体实现,所以直接依赖这个具体实现也是没问题的。如果非常希望解除耦合将这个直接依赖给取消掉,我们也可以考虑引入一个IHeap的接口,让寻路模块依赖这个接口,同时原来的最小堆最大堆实现该接口,因此寻路依赖堆实现类,变成了寻路和堆实现类均依赖IHeap接口。

原依赖关系

image-20230303132941756

新依赖关系

image-20230303133036132

寻路模块

寻路模块中定义了一个寻路的接口IPathSearch,并实现了三种A星算法,分别是原始的A星算法和两种经过一定优化后的A星算法,实现这个接口的好处在于,如果后期我们需要针对特定的场景比如横冲技能,使用额外的寻路规则,仅需额外再实现一种新的寻路算法,并在原本实例化寻路算法的地方改成实例化新的寻路算法即可,而使用的地方由于依赖的是IPathSearch接口,因此完全不需要做任何修改。
PathFinding类图.drawio

地图模块

地图模块主要分成地图抽象层、地图具体实现和地图生成三个部分,具体可查看文章后面的类图或项目代码。

地图抽象层定义了整个地图模块的基本要素和必要方法,比如IMapGrid接口定义了地图的基本数据,对外的方法等等。该接口依赖INode接口,INode接口定义了一个最基础的地图节点是啥样的,而IPathNode则在INode的基础上,增加了寻路相关的属性。另外定义了一个IMapShow的接口,负责处理地图节点的实际显示,比如绑定地图数据层和实际节点对象等功能。INodeEntity定义了节点的基本操作,比如设置高亮等等。在这个层中定义的接口,均不依赖某个具体实现,但定义了地图的几乎所有行为,在实现功能的前提下保证了该层的稳定性。

地图具体实现则实现了两种常见的游戏地图:网格地图和六边形地图。这两种地图实现了IMapGrid的方法,并在实例化的地方注入了创建节点的方法,使得地图类型和节点可以摆脱依赖,便于后面实现同种类的地图不同的节点。

地图生成部分定义了一个生成配置类和生成类,配置类负责配置要生成的地图种类,地图所处的平面,以及各种类地图的一些独有参数。生成类依赖配置来创建具体的地图,并为其绑定对应的显示。

系统完整类图

MapGridInUnity类图.drawio
看不清可以去这里查看。

额外的实现细节

系统的整体结构与设计如上文所示,为了实现地图的通用和寻路通用,还有一些比较巧妙的设计,这里进行补充阐述。

  • 在寻路的时候,经常会需要从一个节点访问到该节点的一圈邻居,但是不同的地图,获取某个节点邻居的方式不同,为了通用我们需要定义一个方法,能直接获取到某节点的所有邻居。本系统定义了一个IDir接口,用来获取一个节点四周邻居相对于该节点的索引偏移,这样在寻路时可以通过该节点和索引偏移计算出周围所有邻居的节点。在网格地图中,分为了两种,一种是四方向的,一种是八方向的,对应的索引偏移列表不同。而对于六边形地图,则是另一种索引偏移,所以在本系统中,分别实现了三个具体实现,并通过配置来决定使用哪组偏移列表。
  • 为了高效在六边形地图中实现范围高亮,六边形使用了Cube coordinates,这个名词来自于Amit Patel的《Hexagonal Grids 》中,其使用了三个轴来表示每个节点,使得在访问邻居时,可以在三个轴上做索引偏移,大大减少了查找邻居的消耗。这里我最开始是使用了偏移坐标,但是在实际去高亮大范围节点时发现并没有那么轻松,尤其是高亮可能发生在地图边缘,后面忍痛对此做了重构改用立方体坐标了。
  • 在处理扇形高亮时,实际上就是从圆形高亮中抠出一部分,因此其内部是判断一个朝向,并根据扇形宽度算出扇形左右最大偏移角,最后调用圆形高亮的方法并添加一个角度的Filter对节点做筛选。
  • 地图配置类中,增加了编辑器类,来对配置类Inspector界面做个性化显示,根据选取的地图类型,来展示该类型所需要的独有参数,并隐藏无关的参数。

总结

以上便是整个地图系统的全部内容和设计思路了,在类图中,箭头代表了依赖关系走向,A指向B表示A依赖B。从图中不难看出,箭头指向的对象基本都是接口,抽象类,或者是一些不太会发生变化的东西。如数据结构小节中的图示,即便依赖的对象是具体实现,我们也可以引入更抽象的接口对象,实现依赖反转,使得整个依赖关系走向更合理,系统更稳定可靠。当然这个系统并不完善,也可能不如料想的那般好用,但我希望通过开源出来给更多的人看见,给更多的人使用,并提供反馈来完善这个东西,使得其可以代代相传(doge。

项目地址:

https://github.com/tang-xiaolong/MapGridInUnity

引用:

  1. Amit Patel.《Hexagonal Grids 》https://www.redblobgames.com/grids/hexagons/
  2. Catlike Coding.《Hex Map》https://catlikecoding.com/unity/tutorials/hex-map/
  3. Robert C.Martin. 《架构整洁之道》

相关文章:

通用游戏地图解决方案设计解析

前言: 在软件开发过程中,我们都希望能设计出一个稳健的,可维护的系统,为了实现这个目的,人们总结出了很多相关的设计原则,比如SOLID原则, KISS原则等等。SOLID每个字母代表了一种设计原则&…...

java @Autowired @Resource @Inject 三个注解的区别

javax.annotation.Resourcejdk 内置的,JSR-250 中的注解。依赖注入通过 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 来处理。org.springframework.beans.factory.annotation.Autowired org.springframework.beans.factory.annotati…...

「媒体分流直播」媒体直播和传统直播的区别,以及媒体直播的特点

传媒如春雨,润物细无声,大家好直播毋庸置疑已经融入到了我们生活的方方面面,小到才艺,游戏,大到政策的发布,许多企业和机构也越来越重视直播,那么一场活动怎么最大化的进行传播,一是…...

数据是如何在计算机中存储的

我们普通人对于数据存储的认识恐怕大多数都是从自己使用的电脑来的。现在几乎人手一台电脑,而我们的电脑存储着各种各样的文件,比如视频文件、音频文件和Word文档等。这些文件从计算机术语的角度都可以称为数据。 如图1-1所示是Windows 10 “我的电脑”的截图。通过该截图我…...

Day907.分区表 -MySQL实战

分区表 Hi,我是阿昌,今天学习记录的是关于分区表的内容。 经常被问到这样一个问题: 分区表有什么问题,为什么公司规范不让使用分区表呢? 一、分区表是什么? 为了说明分区表的组织形式,先创建…...

C++概览:工具链、基础知识、进阶及总结

本篇写给C初学者,作为概览,文中仅包含各方面基础知识,无深入分析。 C基础概念简介 C编译过程示意图 关键词:源文件、预编译、编译、汇编、链接 C工具链总结 cmake项目工程文件是一种中介工程文件,可以转化成其他…...

目标检测中回归损失函数(L1Loss,L2Loss,Smooth L1Loss,IOU,GIOU,DIOU,CIOU,EIOU,αIOU ,SIOU)

文章目录L-norm Loss 系列L1 LossL2 LossSmooth L1 LossIOU系列IOU (2016)GIOU (2019)DIOU (2020)CIOU (2020)EIOU (2022)αIOU (2021)SIOU (2022…...

JOSN数据转换和解析

文章目录JOSN数据转换和解析内容回顾Map 集合转成 JSON 字符串List 集合转换成 JSON 字符串Ajax 异步和同步异步概念同步概念异步和同步区别异步请求案例同步请求时间格式化旧时间 api 格式化格式化和解析的工具类JSTL 时间格式化JSTL 使用JOSN数据转换和解析 内容回顾 ajax …...

浅析Linux内核中进程完全公平CFS调度

一、前序 目前Linux支持三种进程调度策略,分别是SCHED_FIFO 、 SCHED_RR和SCHED_NORMAL;而Linux支持两种类型的进程,实时进程和普通进程。实时进程可以采用SCHED_FIFO 和SCHED_RR调度策略;普通进程则采用SCHED_NORMAL调度策略。从…...

安装 RustDesk 服务器 (适用 Rocky Linux, CentOS, RHEL 系列发行版)

环境:Rocky Linux 9.1 1. 安装 Docker Engine 可以参考 [[linux-docker-rocky-install]] https://cc01cc.com/2023/03/02/linux-docker-rocky-install/英文可以参考官方文档 Install Docker Engine on RHEL https://docs.docker.com/engine/install/rhel/ 2. 安装…...

23种设计模式-策略模式

策略模式是一种设计模式,它允许在运行时选择算法的行为。它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户端。在本文中,我们将深入探讨策略模式的概念和实际应用&#…...

C#开发的OpenRA的游戏主界面怎么样创建

通过前面加载界面布局数据,可以把整个界面逻辑的数据加载到内存, 但是这些数据怎么显示出来,又是没有定义的。比如前面定义了多个界面的布局, 又是怎么样知道需要显示哪一个界面? 现在就来解决这个问题,其实整个游戏都是可以通过yaml文件进行配置的, 所以我们需要从yaml…...

考研还是工作?两战失败老道有话说

老道入职第一周自我介绍谈谈考研谈谈工作新的启程自我介绍 大家好!在下是一枚考研失败两次的自认为聪明能干的有点小帅的实则超级垃圾的三非名校毕业的自动化渣男。大一下就加入实验室,在实验室焊板子、画板子、培训、打比赛外加摸鱼;参加过…...

引用是否有地址的讨论的

说在前头,纯属个人理解,关于引用是否有地址,实际上并没有一个很统一的说法, C标准没有规定一个引用是否需要占用一块内存。 这里引用知乎“C 中引用是一块内存的标记,那引用本身有地址吗_百度知道 (baidu.com)”里面的…...

1、JAVA 开发环境搭建 - JDK 的安装配置

文章目录一、下载 JDK81、官网地址:[**https://www.oracle.com**](https://www.oracle.com)二、安装 JDK1、鼠标右键安装包,以管理员身份运行(无脑下一步即可)2、细节说明三、配置环境变量1、为啥要配置环境变量呢?2、原因分析3、配置环境变量…...

【Storm】【六】Storm 集成 Redis 详解

Storm 集成 Redis 详解 一、简介二、集成案例三、storm-redis 实现原理四、自定义RedisBolt实现词频统计一、简介 Storm-Redis 提供了 Storm 与 Redis 的集成支持&#xff0c;你只需要引入对应的依赖即可使用&#xff1a; <dependency><groupId>org.apache.storm…...

算法代码题——模板

文章目录1. 双指针: 只有一个输入, 从两端开始遍历2. 双指针: 有两个输入, 两个都需要遍历完3. 滑动窗口4. 构建前缀和5. 高效的字符串构建6. 链表: 快慢指针7. 反转链表8. 找到符合确切条件的子数组数9. 单调递增栈10. 二叉树: DFS (递归)]11. 二叉树: DFS (迭代)12. 二叉树: …...

CentOS 7.9汇编语言版Hello World

先下载、编译nasm汇编器。NASM汇编器官网如下图所示&#xff1a; 可以点图中的List进入历史版本下载网址&#xff1a; 我这里下载的是nasm-2.15.05.tar.bz2 在CentOS 7中&#xff0c;使用 wget http://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2下载…...

CoreData数据库探索

CoreData是什么 Core Data 是苹果公司提供的一个对象-关系映射框架&#xff08;Object-Relational Mapping&#xff0c;ORM&#xff09;&#xff0c;用于管理应用程序的数据模型。Core Data 提供了一个抽象层&#xff0c;使开发人员能够使用面向对象的方式访问和操作数据&…...

FreeRTOS入门

目录 一、简介 二、堆的概念 三、栈的概念 四、从官方源码中精简出第一个FreeRTOS程序 五、修改官方源码增加串口打印 一、简介 FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统&#xff0c;功能包括&#xff1a;任务管理、时间管理、信号量、消息队列、…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...