斜角地图逻辑原理解析和Isometric地图编辑器设计方案

本文主要是介绍斜角地图逻辑原理解析和Isometric地图编辑器设计方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当我要做的一款游戏,而无法即时地查看地图各图形元件的拼接效果,而导致不得不中止时,当时找过不少公开的地图编辑器,希望能拿来即用,但不是因为拼接效果不满意,就是因为生成的文件不是太满意。无奈之下决心自己动手写一个工具时,才知道有多少困难。

论坛里的相关帖子,基本上都试着各种关键词看了一遍,说实在的,感觉上,除了几个原来做过斜角地图编辑的,其余帖子里基本上是迷茫的
感觉坛子里像wangqiang99x,闪刀浪子,恋水泥人,wxsr等几位应该还是比较熟悉的,但看了一下他们的帖子,还是感觉有些不够,直到看过杜宇欣的文章,才算解决了斜角地图中的各个障碍

在前一篇斜角地图原理解释及斜角图形绘制实例细述已经对斜角地图的原理进行了细致的阐述。这里就不再重复了,只从斜角地图的逻辑原理方面进行解析。

关于地图中的图形元件的拼接原理,请参考这篇文章闪刀浪子的地图编辑器对应的地图解析类及教程的前半部分,或者只看这个图

因为所有的图片都是矩形的,所以拼接时必然要有所叠加,这就是图片的遮挡。

而要处理图片的遮挡关系,才能使所有这些图片构成的地图所呈现的画面显示出立体效果。
而这种遮挡关系就是地图景深的处理,那么景深的处理都会涉及哪些关键点呢,下面请一个个来看。

1、图片之间的遮挡,这是景深呈现的关键

2、图形元件所代表的意义,即处于某个位置的图形元件是山水建筑物,还是路面等,以标识游戏当中的角色是可以通行还是受阻碍的

3、图形元件是否允许与用户的交互,即一个图形元件放到地图上,如果就是代表一棵树,一片小山,而这些又仅仅是表征地图地形的一个障碍物,那么则不会影响用户的键盘鼠标消息

4、如何通过鼠标当前位置(或角色当前位置),来了解所处的是哪里(什么地形,会不会产生事件等)

5、如何通过网格中某个单元格的纵列位置,来获得屏幕坐标。比如角色在某一个位置,而房子在另一个位置,现在角色要走到房子里,这就要获取某个建筑物所在的坐标,以使角色行走到目标位置

6、碰撞处理和寻路等,如果是地国中有运动的角色等类物体,就必须处理这方面的问题,这暂时不属于地图逻辑原理,也不属于地图编辑器的设计,暂不展开讨论

为了表述方便,我专门截图制作了下面的一张图片来进行一些要素的标注
 

从上图可以看出,以等距地图网格对象的顶点top为坐标系原点T(0,0),以汉字撇捺两个方向的纵列为坐标系的两个坐标轴,即Pie轴与top-right方向平行,Na轴与top-left平行。

这样比其他文章里建立的u-v坐标系在使用时更容易理解,也计算时也更便捷。
在接下来的计算中,各单元格也与网格坐标一样,全部以其顶点坐标代表该单元格的位置(屏幕坐标x,y);
而建立的Pie-Na坐标系,仅是通过单元格相对原点T的撇向序号,捺向序号(Pie,Na)数值对来表示该单元格在此网格上的序列位置。

我们通过分析一下网格的两个单元格关系,就可以得出此坐标系下的计算公式。
看图中标注的两个绿色点M(1,2),N(3,1),我们首先看一下,M点相对原点T其屏幕坐标是什么关系
Mx = cellHalfWidth * (Mpie - Mna) = -1 * cellHalfWidth,即相对原点T向左半个单元格宽度
My = cellHalfHeight * (Mpie + Mna) = 3 * cellHalfHeight,即相对原点T向下3倍的半个单元格高度

我们再用此公式来套一下N点,看下是否如实
Nx = cellHalfWidth * (Npie - Nna) = 2 * cellhalfWidth,看下图中,是不是刚好相差一个单元格宽度?
Ny = cellHalfHeight * (Npie + Nna) = 4 * cellHalfHeight,看下图中,也刚好相差2个单元格高度。

好吧,再看点M和N之间又如何呢
Width(M-N) = cellHalfWidth * ((Npie -Mpie) - (Nna-Mna)) = cellHalfWidth * (2 - (-1)) = 3 * cellHalfWidth,再对照一下图中,嗯,刚好是3倍的半个单元格宽度
Height(M-N) = cellHalfHeight * ((Npie - Mpie) + (Nna - Mna)) = cellHalfHeight * (2 + (-1)) = 1 * cellHalfHeight,看下图中,这个也没错!

那么经过一番验证,我们的公式就可以确定没问题了,
即,在上述以网格顶点T为原点的Pie-Na坐标中,任一单元格的屏幕位置Q(x,y)都有如下公式:
Qx = cellHalfWidth * (Qpie - Qna) + Tx
Qy = cellHalfHeight * (Qpie + Qna) + Ty

Width(Q) = cellHalfWidth * (Qpie - Qna)        //含正负,在原点左侧为负,右则为正
Height(Q) = cellHalfHeight * (Qpie + Qna)      //肯定为正

对于任意两点U(ux,uy),V(vx,vy)都有如下公式:
Vx = cellHalfWidth * (Vpie - Vna) + Ux
Vy = cellHalfHeight * (Vpie + Vna) + Uy

V到U的距离为
Width(V-U) = cellHalfWidth * ((Vpie-Upie) - (Vna-Una))        //含正负,V在U点左侧为负,右则为正
Height(V-U) = cellHalfHeight * ((Vpie-Upie) + (Vna-Una))      //肯定为正

看起来,上下两个公式没多大不同,不过在使用时,可以一目了然,还是比较方便,所以不嫌麻烦都列出来了

这解决了上面所说的哪个问题了,通过单元格的序列位置求出其屏幕位置,是不是第5个问题解决了呢。

大海航行靠舵手,在斜角地图的逻辑中,有了这样一个公式的出现,就可以顺次搞定以上的1~5的问题了,下面就不这么罗嗦了。

4、通过任一点屏幕坐标,求所在单元格的序列位置
直接把上面公式一翻转,再根据前一篇(还不知道斜角地图原理和细节的看这里)中所述的单元格的宽=2*单元格的高
可得出如下公式:
参数点Q(x,y)为Cell中任一点,其与网格的顶点坐标的距离在X、Y轴方向长度分别是Width(Q),Height(Q);
Qpie = (2 * Height(Q) + Width(Q)) / (cellHalfWidth * 2)
Qna = (2 * Height(Q) - Width(Q)) / (cellHalfHeight * 2)


3、是否允许用户交互,我们只要给图形元件设置这样一个属性即可

2、图元类型,同理,我们只需标识一下此图元的类型即可

1、遮挡关系,现在再去看下图中的单元格序列坐标,就可以看到,凡是单元格序列坐标小的,必然被单元格序列坐标大的遮挡
再来看稍微复杂点的单元格之间的遮挡关系,比如M,N

如果图片的宽度仅为单元格顶点left-right,则像M,N这样的点,根本不会发生遮挡关系,因为Mright与Nleft相距半个单元格宽度的,但如果其宽度都超出left-right的宽度,并

且都又比较高,这时仍然会发生遮挡关系的,那么该如何处理这个遮挡关系呢,非常快速,加减法而已
(Npie - Mpie) + (Nna - Mna) > 0,则N挡M,小于零,则M挡N。

那么又必然会存在相等的,比如M(1,2)与Q(2,1)看起来是平行的,这时怎么办呢
像这类,根本就是完全平行,即使是在视觉效果上,所以,怎么处理都无所谓了,左挡右,或者右挡左,都非常合理,完全视自己喜好了

但是在代码中,一般是不需要这么进行3次加减法运算,多数都会拦截在对pie,na序列值的if语句处。
当然,如果是循环设置地图上所有的图元遮挡关系,pie,na的两个for循环中更是直接

说到这里,斜角地图的逻辑原理,就已经没什么东西了,再来看地图编辑器该如何来设计

通常,我们会为地图绘制一幅背景图的,然后我们可能在这个背景图上添加一些建筑物等物体(甚至包括地面,NPC等),让整个游戏世界看起来像是真实世界的映射。

我们首先来看一下会有哪些东西要出现在这个地图当中

1、地图背景

2、网格对象

3、放置的物体(建筑、地面、NPC等)

4、角色对象

5、有时也需要一个可通行路径对象

一般来说,地图这个大容器可能会被塞进去很多的对象,当非常多的可视对象,尤其是交互类对象时,会使得相关的一些处理,比如遮挡关系的处理,碰撞检测,寻路等非常耗费系统资源,所以我们在规划时,就要考虑到可能出现的这些问题

对于上述前三类对象,是必须放置到地图这个容器当中去的。

而第3项,放置的物体有可能会包含两类,一类是非交互性物体,一类是交互性物体;
而处理方式,一般也有两种方式,即放置进的物体都是非交互性物体,而交互性物体放置到地图外面的另一专门层里,并且使之与地图容器对象等大,这个层容器里面,全部是响应用户的一些对象,但都是看不到的,当鼠标或角色移动到此类对象范围内时,就表现出交互性的半透明效果叠在地图中同样位置的对象上面,因为可响应用户的对象在地图中远远少于非交互对象。但这样一来,寻路和角色在运动时的遮挡处理也复杂化了,因为既然把交互对象移出了地图容器,那么地图容器一般都会设为完全不响应用户,角色有属于自己的层对象来容纳,而遮挡关系就只能靠贴图算法来实现了,当同屏幕有数量非常多的角色对象时,而主程能力又很给力时,有个优秀的贴图算法,可以实现非常高的效率和承载能力

但是一般较为常用的方法,还是采用非交互性物体和交互性物体都放置在地图容器中,而且角色也同样放置在地图容器中,这种处理方案一般在遇到地图在有大量物体,并且角色数量在3~4位数时,通常会遇到瓶颈,CPU和内存飞速上涨,而且会出现画面卡顿的现象。但是一般的小游戏都可以满足了,只要尽量消减一下地图中的非交互性对象数量即可,但话又说回来,如果采用消减地图中非交互性对象的数量,则一定会采用通行路径的处理办法,因为地图上大量不可通行的位置都在地图背景图片中来表现来的

newscreen348447000.png (42.56 KB, 下载次数: 20)

newscreen348447000.png

这篇关于斜角地图逻辑原理解析和Isometric地图编辑器设计方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/719253

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。