瓦片地图(Tiled Map)系列文章:

  • 斜45度瓦片地图(Staggered Tiled Map)里的简单数学

  • 瓦片地图注意事项

前段时间在做游戏的地图编辑功能,我们是在一个斜45度视角的场景上,对地图上的建筑或装饰物进行添加、移动、移除等基本操作,而且位置的改变是以网格作为最小操作单位的。本渣是用Staggered Tiled Map实现的,与垂直视角的Tiled Map不同,斜45度视角处理起来相对麻烦些,这次就聊聊其中一些跟数学相关的有趣问题。

<!-- more -->

何为Staggered Tiled Map?

不解释,有图有真相XD


'Orthogonal Tiled Map'


'Isometric Tiled Map'


'Hexagonal Tiled Map'


‘Hexagonal Tiled Map’

判断区域相交

地图编辑的一个基础功能便是判断当前被编辑的建筑或装饰物的位置的合法性。这种合法性检查主要有两方面:一是不能放置在地图上被禁止编辑的区域(例如地图上的河流、山坡),这可以通过在Tiled Map上在相应区域做上标记,判断建筑所在的区域是否有该标记就可以了;二是不能与其他建筑或装饰物重叠,这便是这里主要要讨论的问题了。

在实际做位置判断时,我们并非按照每个建筑或装饰物的图片实际轮廓,而是把它们都对应到Tiled Map上一块以网格线为边的区域上——在斜45度视角下,这样的区域就是一个平行四边形。因此,建筑或装饰物是否重叠的问题便转化为在Tiled Map上的两个平行四边形是否相交的问题。再做进一步简化,我们发现这其实只需要判断任一平行四边形的四个顶点的瓦片(tile)是否落在另一个平行四边形内部就可以了。

看到这里,你也许已经发现:这不就是中学里简单的代数问题吗?判断点是否在平行四边形内,只需要知道平行四边形四条边所在直线的方程和点的坐标,便迎刃而解。没错,Tiled Map里每一块瓦片区域有自己的坐标,我们只需要把一块瓦片的坐标当做点的坐标,直线方程和点的坐标就有了。但斜45度角Staggered Tiled Map的有趣之处在于,即便把瓦片当做点,得到的并不是一个常见的平面直角坐标系。

下面我们还是通过图片来看看Staggered Tiled Map的坐标:

为了方便起见,我们把向下作为y轴正方向,我们可以发现上面的坐标(x, y)有着如下规律:

-- columnNum表示列数
-- columnNum = 1, 2, 3, ...
x = (columnNum - 1) % 2-- rowNum表示行数
-- rowNum = 1, 2, 3, ...
y = rowNum - 1

看上去好像不复杂,但要列出直线方程呢?比如以下两种可作为平行四边形瓦片区域的边的直线:

一时半会懵逼了吧?使问题复杂的正是这些公式需要判断奇偶性,能不能把奇偶性判断拿掉呢?当然可以,做坐标转换就可以了,让我们先看一张直观的坐标转换结果图:

这相当于做了如下的坐标转换:

f[(x, y)] = (x * 2, y) if y mod 2 = 0f[(x, y)] = (x * 2 + 1, y) if y mod 2 = 1

合并成一条公式也就是:

f[(x, y)] = (x * 2 + y mod 2, y)

现在是不是简单得多了?上面两条直线方程(因为这样的直线斜率是确定的,只需要知道直线上一点的坐标就可以确定直线方程)分别是:

-- linear equation of the row line containing the point of tileCoord
local function rowEquation(tileCoord)return tileCoord.x * 2 + tileCoord.y % 2 + tileCoord.y
end
-- linear equation of the column line containing the point of tileCoord
local function columnEquation(tileCoord)return tileCoord.x * 2 + tileCoord.y % 2 - tileCoord.y
end

这个时候你应该已经发现,我们可以用之前简单的代数问题解法来解决这一问题了:已知点的坐标tileCoord和一个区域region四个顶点的坐标(分别为region.topregion.bottomregion.leftregion.right,事实上只需要知道其中两个点就可以了),判断点是否在区域内,只需要做不等式判断即可:

local function containsTile(region, tileCoord)return (rowEquation(tileCoord) >= rowEquation(region.top))and (rowEquation(tileCoord) <= rowEquation(region.bottom))and (columnEquation(tileCoord) <= columnEquation(region.top))and (columnEquation(tileCoord) >= columnEquation(region.bottom))

你也许会问,为什么不直接定义一套方便计算的坐标系统?为何要用Staggered Tiled Map原有的坐标系统去做变换呢?这是因为前面所提到的做标记的非法编辑区域是采用原有的坐标系统的,采用同一套坐标系统加简单的坐标转换处理比起采用两套坐标系统,在实现上和维护上的成本更低。

遮挡关系

地图编辑的另一个基础需求是要处理好建筑及装饰物之间的遮挡关系。这个问题可以转化为建筑或装饰物的显示层级的排序。但是问题又来了,如何比较任意两个建筑或装饰物的显示先后顺序呢?特别是它们还有可能隔得很远,并没有显示上的重叠区域?

这个问题其实没有固定答案,本渣也只是根据我们系统的实际情况定了一套排序规则。在本渣的规则中,建筑或装饰物的显示层级只与它们对应的平行四边形区域有关。本渣用每一个的平行四边形左侧和右侧瓦片的坐标点得到一条直线,并把平行四边形对角线交点作为基准点。当比较两个建筑或装饰物的显示先后时,先判断二者平行四边形的宽度(两条相邻边的tile数量),短的求基准点,长的求直线。如果点在直线下方,则点所对应的建筑或装饰物在前方;反之则在后方。

当然,本渣这套规则实际能显示正确还有赖于美术大大们提供的建筑或装饰物图片资源的情况哈,如果建筑或装饰物的轮廓宽度超过它们的平行四边形区域,还是可能会出现显示奇怪的地方的。

斜45度瓦片地图(Staggered Tiled Map)里的简单数学相关推荐

  1. Tiled实现斜45度瓦片地图

    首先是我最近在做的一个项目的需求,要做一个斜45度角的大地图,里面有很多的建筑,会有人在里面走来走去.一个手指按住滑动可以拖动地图,两个手指按下可以调整地图的放大和缩小. 1.tiled新建地图,加入 ...

  2. cocos2dx使用TiledMap模拟3D地图场景----斜45度2D地图的靠墙直线移动

     基于cocos2dx引擎的第三人称射击游戏,角色使用3D模型,地图采用2.5D.  定制地图编辑系统抛开不谈,这里最大可能的挖掘现有工具TiledMap的潜力,完成超2.5D地图的实现.  使用2D ...

  3. 45 度角地图-----斜45度角地图拼接

    45 度角地图, 可以分为 Staggered, slid 和 Diamond 三种类型 先看看地图元素: 可以看出来是个扁的菱形.这个地图元素的大小是64X32,你可以随意决定元素长宽,在设计程序时 ...

  4. tilemap 菱形_带高度的isometric tile map 斜45度 2d 地图制作

    常见的 tile map 游戏是 不带 高度变化的 也就是 地面都在一个水平面上 这样 3种 坐标 之间的变换 是比较简单的 3 种坐标系统 可以参看 这篇文章 而带有高度的 tile map 中 存 ...

  5. 编写简易斜45度地图编辑器

    最近在研究cocos2dx的地图,最开始使用的是Tiled,这个编辑器做比较小的地图还是比较强大的,不过做大地图的时候,有一些功能不太方便并且有缺陷(包括刷图繁琐以及坐标体系过于复杂,导致寻路比较看起 ...

  6. 魔力宝贝高清单机计划(二) 地图转为tiled map

    文章目录 地图格式 tiled map格式学习 转换步骤 代码地址: https://github.com/mversace/CrossGateRemastered 地图格式 地图文件头: #prag ...

  7. html5地图编辑器,Tiled地图编辑器 Tiled Map Editor 的使用(一)基础功能+地形功能...

    看了很久关于 Tiled Map Editor 相关资料,但是网上的东西相对太少了,多日整理之后重新写一份吧 一方面是对自己学习的总结 另外也是和想入门的人做个分享. 首先是官网下载地址 http:/ ...

  8. Tiled地图编辑器 Tiled Map Editor 的使用(一)基础功能+地形功能

    看了很久关于 Tiled Map Editor 相关资料,但是网上的东西相对太少了,多日整理之后重新写一份吧 一方面是对自己学习的总结 另外也是和想入门的人做个分享. 首先是官网下载地址   http ...

  9. 45度斜角地图菱形坐标转换

    !!! 此文章内容为转载,没有真实实践,只给需要的朋友提供思路,具体详细算法需要自己根据项目需求变动 !!! 我们要做一个45度游戏地图中,那么如何判断鼠标点中了哪一个碎片呢??如图:   也许你想到 ...

最新文章

  1. centos安装JDK与Tomcat
  2. rm 空间不释放_面试官跟我说rm删除文件之后,空间就被释放了吗?我该怎么答...
  3. 通过StringBuilder的reverse()实现倒序
  4. UVA10881蚂蚁
  5. 庄导就业指导2020.4.6
  6. 深度学习:tensorflow Layers的实现,numpy实现深度学习(二)
  7. linux shell之字符串的比较
  8. python 视频和图片转换 视频压缩 图片降低分辨率 图像处理
  9. 面试题系列(9):对前端界面工程师这个职位是怎么样理解的?
  10. 能伸能屈的拼音及解释
  11. php二维数组的某一字段 做分组统计
  12. Atitit.跨语言  文件夹与文件的io操作集合  草案
  13. 无领导小组讨论(LGD)九大经典案例3
  14. slickedit调试linux内核,SlickEdit使用(设置篇)
  15. 设计一个person类java_定义一个Person类,含姓名、性别、年龄等字段;继承Person类设计...
  16. 医用电气设备中关于电源开关的符号使用要求探讨
  17. 教你win7下如何删除微软拼音输入法~!
  18. Mysql忘记密码设置新密码
  19. CHAPTER 24 Dialog Systems and Chatbots
  20. 抛弃爬下来的灰色数据,有门槛的风控怎么做?

热门文章

  1. android 键盘码表,键盘码表,键盘扫描码,ASCII码
  2. 互联网晚报 | 10月11日 星期一 | 联想回应终止科创板IPO;万达广场小程序用户量破亿;2021年全国电影票房破400亿元...
  3. 三星K2200复印机提示更换传输卷问题的简单处理
  4. 【排错日记】java.lang.IllegalStateException: It is illegal to call this method if the current...
  5. 大数据系统计算的概念全面解析
  6. pypinyin--python 汉字与拼音的转换
  7. kaptcha谷歌验证码使用
  8. 【线性代数】高斯消元法与矩阵的初等变换
  9. php date 怎么处理 夏令时 冬令时的切换
  10. Python的自定义模块细讲