找回密码
 立即注册
搜索
查看: 7322|回复: 42

[其他] 在S1白票开发之旅 l带可变高度地形的2D等距视角的sprite排序

[复制链接]
发表于 2021-4-8 12:37 | 显示全部楼层 |阅读模式
本帖最后由 mes 于 2022-12-9 15:15 编辑



forum.yoyogames.com/index.php?threads/smart-isometric-drawing-order.57356/
比如像这样还有上下两层,代码要怎么写才能让它显示正常?
另外有比如大于一格大小物体的显示问题,3个物体互相重叠的显示问题等。
qiita.com/Shinoda_Naoki/items/fccdc137747ea4301578
回复

使用道具 举报

     
发表于 2021-4-8 20:29 | 显示全部楼层
本帖最后由 Tring 于 2021-4-8 20:36 编辑

3者交错覆盖的情况,仅在2D架构下做处理办不到吧。
真需求这种,老老实实上3D吧。要不就自己实现些类似BSP树算法或者扫描线算法之类的手动做遮挡。

对于固定视角的简单覆盖,自己手动分图层来处理覆盖吧。
回复

使用道具 举报

头像被屏蔽
     
发表于 2021-4-8 20:43 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

     
发表于 2021-4-8 21:21 | 显示全部楼层
如果引擎是unity的话我没准可以帮上忙,最近刚解决了图层显示顺序的问题。
回复

使用道具 举报

 楼主| 发表于 2021-4-9 00:34 | 显示全部楼层
Yan1961 发表于 2021-4-8 21:21
如果引擎是unity的话我没准可以帮上忙,最近刚解决了图层显示顺序的问题。 ...

应该不管什么(免费)引擎都一样,都是要自己写。只考虑最简单的状况,每个固定的图块占一格,每个移动的图块长宽都不超过一格,有一个地图像这样
[
[1,1,1,1,1,1],
[1,0,0,0,0,1],
[1,2,1,0,1,1],
[1,0,2,0,2,1],
[1,0,0,0,2,1],
[1,1,1,1,1,1]
]
数字代表高度(有多少个立方体叠在一起),希望也可以站在它们上面,所以普通的分层不适用
比如1人移动从1变成2之间,可能会先被其他1盖住,也可能先把其他1盖住

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

     
发表于 2021-4-9 00:55 | 显示全部楼层
本帖最后由 Tring 于 2021-4-9 01:02 编辑
mes 发表于 2021-4-9 00:34
应该不管什么(免费)引擎都一样,都是要自己写。只考虑最简单的状况,每个固定的图块占一格,每个移动的 ...

按照Z方向顺序绘制图块(包括主角)就可以了。
比如图中的例子,就是以这种顺序绘制:
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
...
主角sprite在哪个位置,就随哪个位置的绘制顺序。
另外,在同一格上的多层图块,按从下往上的顺序绘制,主角同理。
回复

使用道具 举报

     
发表于 2021-4-9 08:41 | 显示全部楼层
mes 发表于 2021-4-9 00:34
应该不管什么(免费)引擎都一样,都是要自己写。只考虑最简单的状况,每个固定的图块占一格,每个移动的 ...

我印象中等距视角要同时考虑y轴和z轴的控制,而且根据sprite的透视情况要有一个y和z的较为精确的权重比。
有了这个权重比就可以根据两轴的共同情况来确定渲染顺序。
回复

使用道具 举报

头像被屏蔽
     
发表于 2021-4-9 09:14 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2021-4-9 09:48 | 显示全部楼层
绝对保证正确的办法是从用户视角投射透视线,然后计算每个物件在这条轴上的坐标。比如说你的眼睛是0,离你眼睛最近的是-1,远一点的是-2,等等。然后从最小的开始画,每一层都在上边进行覆盖。然后如果要画阴影的话就加上alpha通道。

取巧的方法是提前计算好这个矩阵甚至于把视角设置在一个容易计算的位置。比如你的空间的(x,y,z)方块在视线轴上的值是v=x+y+z(45度的话应该可以这么做)。然后在你的绘画方法里把所有有数据的方块按这个排序然后渲染,即可。

当然,你的人物或者物品有可能会占据很多格,那你可能就需要对每一格都做这个处理了。
回复

使用道具 举报

 楼主| 发表于 2021-4-9 11:56 | 显示全部楼层
asdfg 发表于 2021-4-9 09:48
绝对保证正确的办法是从用户视角投射透视线,然后计算每个物件在这条轴上的坐标。比如说你的眼睛是0,离你 ...

x+y+z应该是最正确的方法,所以才有这种视角,很奇怪竟然查不到,谢了。不过已经按行和列排了(for x<w(for y<h 新图块位置=x,y)),还是先想想“2D”的方法。还有45度没什么关系,算坐标转换是见到好像是30度60度之类。另外昨天见到,常见的45度俯视视角其实是很诡异的视角,虽然不一定,但是当然屏幕上向左右走一步和向上下走一步是一样的距离最好,也就是一个正方形贴在地上,按这个视角看还是个正方形,其实就是完全90度向下了,但是又还能看到侧面,那干脆侧面也是和原来一样,于是一个正立方看上去其实是两个一样的正方形面上下排列。不过我见过的大都是水平于地面会扁一点,垂直就看不出来,又或者说,这是这个角度下经过左右压缩到符合比例得出的图像。
回复

使用道具 举报

     
发表于 2021-4-9 12:11 | 显示全部楼层
https://indienova.com/indie-game ... t-2d-sprite-order-/
制作 oblique/cabinet 投影的 2D 游戏时,确认精灵先后顺序的排序方法

indienova的这篇文章应该能帮到你
简单总结一下
大概就是先用Colider检测碰撞 所有有碰撞物体间形成有向射线 统计完所有有向射线后 对所有有向射线做一次拓补排序 得到渲染顺序
根据渲染顺序来决定物体的深度先后

  -- 来自 能看大图的 Stage1官方 Android客户端
回复

使用道具 举报

 楼主| 发表于 2021-4-9 12:57 | 显示全部楼层
AlerHugues 发表于 2021-4-9 12:11
https://indienova.com/indie-game-development/oblique-cabinet-2d-sprite-order-/
制作 oblique/cabinet  ...

这其实是另一种视角,虽然不知道这个具体角度是什么,但很可能3种视角都不一样,也就是说素材其实不通用,当然混用可能也“看不出”有什么问题。这个方法可能见过,用来处理大于一个的物体,当然算法不一样。不过这个视角似乎人物是垂直的,直接走3D现在应该是最简单的办法……
回复

使用道具 举报

     
发表于 2021-4-9 13:41 | 显示全部楼层
本帖最后由 moudianzi 于 2021-4-9 13:52 编辑

说一些我想起来的方法和注意点:

1、在关卡地图的设计中,主动避免 “地形遮挡角色”  的情况发生,让地形按照 “从远到近越来越低” 的规则进行布局,这样一来,只要设置角色的绘制优先级永远高于地形,然后分别排序地形和角色的绘制顺序即可,从而无需在绘制的核心排序逻辑中处理 “人挡地形、地形挡人” 这种问题。
而对于个别需要 “地形遮挡角色”的场景设计,就直接特殊处理,将这部分会遮挡住角色的地形贴图单独抠出来,以“遮挡装饰物贴图”的身份,而非“地形贴图”的身份,来进行绘制处理。
(可以用GBA模拟器去看一些斜视角战棋游戏的图层分布作为参考,例如最终幻想战略版、皇家骑士团这种,可以看到房屋有可能遮挡住角色的贴图部分,会被拆分出来,进行单独的绘制处理,从而伪造出遮挡效果)

2、开启z轴绘制缓冲区,模拟3d游戏的绘制方式,让贴图的每个像素点对应绘制深度,最终得以通过3d的方式来绘制出2d画面。
(这种方法在u3d做的游戏里好像相对常见一些,开启3d,然后让角色的纸片人贴图斜着45°绘制,之后再通过拉长贴图本身的高度,来修正因为倾斜角度而被缩短掉的绘制高度)

3、自行设计一套捕获遮挡关系的逻辑算法,依次捕获每个单位间的遮挡关系,构建出类似于树的排序关系,然后按照这个排序去依次绘制即可(如,通过规则得出A被B遮挡,而B又被CD遮挡,且DC间不构成遮挡关系,那么就能很清楚的按照ABCD或ABDC的顺序来进行绘制了)。同时要注意主动避免循环遮挡情况的发生,或者针对循环遮挡的特殊情况,专门设计出一次性的应对方案(只要在视觉表现上,玩家不觉得突兀即可)

4、定死到底是前后遮挡的优先级大,还是高度遮挡的优先级大,然后遵循这个大优先级的前提进行分层排序。不过这种做法会有比较多的视觉限制,所以在绘制元素的设计上要比较注意,例如,让高度遮挡优先级大于前后遮挡优先级的话,就别让角色随便向上跳,从而出现后面跳起的角色反而挡住前面角色的情况发生。一般会结合1进行使用、

5、基于最基本的前后遮挡优先的前提下,针对具体的游戏情况进行设计,以及添加约束条件。例如,这是个战棋游戏,限定角色只能沿着轴线4方向位移,且角色不可能跑到地砖下面,那么在正常情况下,角色就永远会与某个地砖的tile间存在位置上的具体绑定关系,然后再以这个角度作为切入点,来进行排序规则的设计,如,先让前后排的地形间以遮挡优先级关系进行排序,然后再结合角色站在地砖上,来得出“前排地砖上的角色→前排地砖→前+1排地砖上的角色→前+1排地砖→……(以此类推)” 的排序规则

6、一般来说,即便有地形导致的上下层遮挡关系,也会通过 “让上层可站角色的位置,远离下层可站角色的位置” 的设计,来避免掉让上下层的角色间,直接出现贴图重叠的情况发生,从而创造出能够使用1或者其他解决方案的投机空间。

7、对于占用多格地形的大型单位,比较无脑的方法有2种。一种是刻意简化场景的遮挡关系,让大型单位可达的地形不涉及高低地情况,那么就可以直接按照前后优先遮挡的规则来绘制了。另一种是拆分大型单位的贴图,例如,可以将2x2尺寸的单位看做是4个1x1单位的贴图,然后再分别进行绘制即可。
回复

使用道具 举报

     
发表于 2021-4-9 14:49 | 显示全部楼层
最简单的办法 直接上3d啊!渲染上下功夫 做成你想要的样子就行
回复

使用道具 举报

     
发表于 2021-4-9 14:51 | 显示全部楼层
啊不对 如果想要那种纸片人质感的话(3d场景+2d纸片人角色) 3d貌似还挺麻烦的 因为遮挡问题 这事情明日方舟技术分享上还说过
回复

使用道具 举报

 楼主| 发表于 2021-4-9 18:02 | 显示全部楼层
moudianzi 发表于 2021-4-9 13:41
说一些我想起来的方法和注意点:

1、在关卡地图的设计中,主动避免 “地形遮挡角色”  的情况发生,让地形 ...

1可以,视乎什么游戏,回到198X年,街机也是只有一层地形。素材网上倒是见过,不知道为什么柜子右上的一丁点特意分出来了,可能空间不够之类吧。
2问题是毕竟还是2d,还是一块平的,就是说如果它很长,左边右边z应该不一样但是没办法,它就只能设一个z
3要是能随便写出来就不用问了
5虽然不知具体是不是一样,我个人一开始的思路是每一格里所有的东西都属于一个坐标,然后通过调整offset,从下到上盖上去,然后对所有格进行按y轴排序,但是这意味着角色永远在一个坐标,就算有offset,从一块上走到另一块的动画得拆开,也不好搞于是放弃。现在仍是每一格属一个,实在不行也可以改xyz就是了。
回复

使用道具 举报

     
发表于 2021-4-9 18:57 | 显示全部楼层
mes 发表于 2021-4-9 18:02
1可以,视乎什么游戏,回到198X年,街机也是只有一层地形。素材网上倒是见过,不知道为什么柜子右上的一 ...

2、(不太确定说的左边右边z指的是什么)但应该是有针对性的处理办法,给每个纸片人额外配一张“蒙版图”,来用于记录详细的z偏移深度。这样绘制的时候就可以让3d系统根据这张图,来为每个像素点进行深度偏移的运算了。(但这种做法实现写法和便利性,还和引擎有关,不清楚LZ会用什么引擎)

3、我现在手头也没代码例子,且之前看的一些实现案例感觉都不是很好(写起来麻烦,用起来也不够灵活),所以也没有太细介绍。还记得的其中一种比较直接的搜索方法,就是以一个位于顶点位置的单位,将其作为根节点出发,向特定方向搜索,遇到遮挡物就将其作为子节点记录起来,然后再以这个遮挡物作为出发节点,继续搜索下去,搜索完了就返回上一个父节点继续搜索
(大概下面这种感觉)
通过
A 0 B C
A 0 B 0
A 0 B D
A 0 0 0
获得
A → 0 → B → C
↓↓            ↓↓
A → 0     B → 0
↓↓            ↓↓
A → 0     B → D
↓↓
A → 0 → 0 → 0

5、同一格中的单位也是可以不同坐标的,只要在绘制排序的时候,通过用具体的单位坐标,反过来计算获取其所在格的地块位置坐标(或者通过提前/实时记录好单位所在的地块单位,也行,以便于用时能方便获取),然后再将其用于这些单位的排序计算中即可。
至于跨越地块时的表现bug问题,是存在的,但只要不是在交界处停留得太久,即便不做太多视觉处理手段,玩家也是有可能忽略掉一些短暂的视觉BUG的,特别是对于移动比较规律的战棋游戏(对于行动相对自由的动作类游戏,又或者是在会有大量的图像单位,分别同事四处移动的时候,可能就不太合适了)。

总之,用相对2D绘制的思路去实现这种视角的表现,实现比较简单又万金油的处理方案,我觉得是没有的,主要还是做取舍,选一种自己熟手的、效果将就过得去的实现方案来用。(steam上的一些斜视角轴的战棋游戏,其实也是如此,或会存在一些视觉小BUG,但不影响整体的游玩体验,又或会在关卡上做设计,提前做回避那些麻烦问题)
回复

使用道具 举报

     
发表于 2021-4-9 19:29 | 显示全部楼层
不是,你们是不是弄太复杂了啊?
分单位格子的正斜角ISO视角,只要保证图块不超出单位格,最大的好处就是可以按照固定顺序绘制保证遮盖关系不出错。
而固定顺序就是我前面6L说的那种。
回复

使用道具 举报

     
发表于 2021-4-9 20:32 | 显示全部楼层
Tring 发表于 2021-4-9 19:29
不是,你们是不是弄太复杂了啊?
分单位格子的正斜角ISO视角,只要保证图块不超出单位格,最大的好处就是可 ...

你前面先在6l提到的固定顺序方案,我后来提的第5点,以及LZ在16说他一开始的思路,应该都是同种思路
不过LZ可能还想看看有没有其他方案作为参考,以便捷地处理一些出格、跨格的边界情况
回复

使用道具 举报

     
发表于 2021-4-9 21:03 | 显示全部楼层

https://codepen.io/BSoD_X/full/YzNEbye
不出格子的情况写了个固定顺序绘制的DEMO。

有画面内容超出格子的话,那确实没有很好的纯2D处理办法了,那种情况已经不算ISO视角能够简化处理的范畴了。
要么试着把超出格子的内容拆分到几个格子里,要么上3D,要么就要上一些很麻烦的隐面消隐算法了。

回复

使用道具 举报

 楼主| 发表于 2021-4-9 21:27 | 显示全部楼层
本帖最后由 mes 于 2021-4-9 21:39 编辑
Tring 发表于 2021-4-9 00:55
按照Z方向顺序绘制图块(包括主角)就可以了。
比如图中的例子,就是以这种顺序绘制:
1 2 3 4 5 6

不好意思其实没看到,这个方法的问题是,其实和
123456
789...
没有区别,从数字连续的格子走没有问题,但从8走到2,问题就来了。
为什么说没有区别是因为当它们属同一个优先级时,没有办法控制谁显示在前,同样的移动,按这个就是中间的3移动到右边的3前的2,但是没法控制到底是哪个3在前面(至少我用的游戏引擎似乎是)。
这个是根本问题,所以如果是占了整个宽的东西在移动很可能按这种排列真的无解,只是其实以前某个这种游戏的角色宽只有1/2格以下,虽然怎么实现的仍然不知道。因为必须考虑地面进去,如果一格只属一个固定值,那必须所有在这格上的东西都属这个值,因为只要向上移动一点就会被格上其他所有东西包括地面挡在前面。但固定值的话就有以上这个根本的问题。
回复

使用道具 举报

     
发表于 2021-4-9 21:42 | 显示全部楼层
本帖最后由 Tring 于 2021-4-9 21:51 编辑
mes 发表于 2021-4-9 21:27
不好意思其实没看到,这个方法的问题是,其实和
123456
789...

你是指的移动的动画播放中,很难决定什么时间点切换主角SPRITE的绘制顺序?
还是说,主角的绘制顺序本身就很难改变?

等等,我理解你的意思了,让我组织一下语言。
回复

使用道具 举报

 楼主| 发表于 2021-4-9 21:55 | 显示全部楼层
Tring 发表于 2021-4-9 21:42
你是指的移动的动画播放中,很难决定什么时间点切换主角SPRITE的绘制顺序?
还是说,主角的绘制顺序本身就 ...

主要的难点是保证从“低”往“高”正确地显示地形的同时,保证在各格之间位置的正确显示顺序,因为虽然没什么人提,正常来说“高”的图块那些会被“低”的挡住。
回复

使用道具 举报

     
发表于 2021-4-9 22:05 | 显示全部楼层
在你的顺序中
1 2 3
4 5 6
7 8 9
考虑5的图块在移往8时,动画播放中的正确遮挡应该是,挡住7但是被6挡,这显然在当前绘制顺序下是不可能实现的事情,是一个反序遮挡。

但是用我提到的顺序
1 3 6
2 5 8
4 7 9
图块5无论往哪个方向移动,跨越的交叉线处的遮挡都不会出现反序:
5->2  4>3
5->3  6>2
5->7  8>4
5->8  7>6
但是注意到,有几个移动时,无论是使用起始顺序(5)还是目标顺序(2,3,7,8)都无法正确遮挡。
因此在播放移动动画时,需要把移动色块的绘制顺序调整为起始于目标的中间值。
比如5->8时,动画的绘制顺序变为(5+8)/2 = 6.5
这样就能满足7>6.5>6而获得正确的遮挡了。
回复

使用道具 举报

 楼主| 发表于 2021-4-9 22:19 | 显示全部楼层
Tring 发表于 2021-4-9 22:05
在你的顺序中
1 2 3
4 5 6

必定会有移动会失效就是我说的根本问题,而且不能忽略地面,改了会被8的地面挡住,并不是我想考虑地面,而是有高度的地方站上去了也等于地面。不过改成下面两个中更小的数是没想过...
回复

使用道具 举报

     
发表于 2021-4-9 22:27 | 显示全部楼层
mes 发表于 2021-4-9 22:19
必定会有移动会失效就是我说的根本问题,而且不能忽略地面,改了会被8的地面挡住,并不是我想考虑地面, ...

用镜头Z方向的顺序,也就是我说的那种顺序,就不会出现移动时有无法以正确顺序绘制的问题了。
另外,至于高度问题,按道理来说在ISO视角下,高度应该基本上不影响啥的,大多时候把同一格里不同高度的格子相同处理都没什么问题,只要保证同一格里的渲染顺序是从低到高就可以了。
回复

使用道具 举报

 楼主| 发表于 2021-4-9 22:43 | 显示全部楼层
Tring 发表于 2021-4-9 22:27
用镜头Z方向的顺序,也就是我说的那种顺序,就不会出现移动时有无法以正确顺序绘制的问题了。
另外,至于 ...


因为角色其实只占半格,似乎用什么排列都可以,感觉其实答案应该很接近了,只是我不知道要怎么处理地面

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

     
发表于 2021-4-9 22:49 | 显示全部楼层
本帖最后由 Tring 于 2021-4-9 22:59 编辑
mes 发表于 2021-4-9 22:43
因为角色其实只占半格,似乎用什么排列都可以,感觉其实答案应该很接近了,只是我不知道要怎么处理地面
...

什么叫怎么处理地面?

地面也当成一层图块不就好了么?

另外,你那个顺序虽然在主角只占1/2格时不会出现同时与2个图块发生反向遮挡的问题,
但是其实处理动画的绘制顺序还是很麻烦,并不能简单的用一个中间值作为新顺序绘制。

还是5->8的情况,动画的前半段因为要被6遮挡,所以绘制顺序得用5;后半段因为要遮挡7,所以绘制顺序得用8.
也就是说一段动画,必须在中点时切换绘制顺序。
回复

使用道具 举报

     
发表于 2021-4-9 23:55 | 显示全部楼层
刚用tilemap魔改了一套等距视角 每个格子可以直接调节高度的。
知乎上有篇,但还是很浅,油管上大概也看了下,讲的很少
最终效果还是要动态调整角色层级,,如果用z轴模拟总会有一些问题。

知乎那篇:https://www.zhihu.com/question/323924778/answer/681296588
回复

使用道具 举报

发表于 2021-4-10 12:35 | 显示全部楼层
但是我还是不明白为什么不直接上3d模型就好了
回复

使用道具 举报

 楼主| 发表于 2021-4-10 13:24 | 显示全部楼层
Tring 发表于 2021-4-9 22:49
什么叫怎么处理地面?

地面也当成一层图块不就好了么?

如果没有地面就变得非常简单,在5区就永远是5,在8区就永远是8,因为只有一半宽度,当走到8已经不用考虑刚好在它左边或右边的格子,但是如果有地面,走到这个位置前会被地面挡住
回复

使用道具 举报

 楼主| 发表于 2021-4-10 13:39 | 显示全部楼层
Wiksy 发表于 2021-4-10 12:35
但是我还是不明白为什么不直接上3d模型就好了

这就是一个觉得这样更好看还是那样更好看,还有能做到哪一样的什么程度的问题……

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

     
发表于 2021-4-10 17:33 | 显示全部楼层
iso地图格子 屏幕的y轴不就是深度嘛 有那么复杂嘛
回复

使用道具 举报

     
发表于 2021-4-11 00:43 | 显示全部楼层
mes 发表于 2021-4-10 13:24
如果没有地面就变得非常简单,在5区就永远是5,在8区就永远是8,因为只有一半宽度,当走到8已经不用考虑 ...

我想了一下,确实是一个问题。
那这样的话,就只能在高度方面,也按镜头深度Z的顺序来绘制了。
对于一个3层3X3的例子来说,绘制顺序就是:

第一层
[ 1,  3,  7],
[ 2,  6, 12],
[ 5, 11, 18],

第二层
[ 4,  9, 15],
[ 8, 14, 20],
[13, 19, 24],

第三层
[10, 17, 23],
[16, 22, 26],
[21, 25, 27],


考虑主角在正中间14图块的位置,要移往19图块。
动画就应该使用绘制顺序(14+19)/2,也就是16.5。
遮挡方面:
16.5>11>6,所以能遮住下层地面;
16.5<22<25,所以不会被上层天顶挡住;
横向的交叉处的遮挡方面:
20>16.5>13,就像前面帖子里分析的也没有问题。


至于如何实现这个动画取中值绘制顺序的问题,
我来做的话,为了避免低效率的动态排序,会预先静态计算出动画时的绘制顺序。
因此干脆直接将3X3X3扩展成5X5X5:
[[[  1.   3.   7.  14.  25.]
  [  2.   6.  13.  24.  39.]
  [  5.  12.  23.  38.  56.]
  [ 11.  22.  37.  55.  74.]
  [ 21.  36.  54.  73.  91.]]

[[  4.   9.  17.  29.  44.]
  [  8.  16.  28.  43.  60.]
  [ 15.  27.  42.  59.  77.]
  [ 26.  41.  58.  76.  93.]
  [ 40.  57.  75.  92. 106.]]

[[ 10.  19.  32.  48.  65.]
  [ 18.  31.  47.  64.  81.]
  [ 30.  46.  63.  80.  96.]
  [ 45.  62.  79.  95. 108.]
  [ 61.  78.  94. 107. 116.]]

[[ 20.  34.  51.  69.  86.]
  [ 33.  50.  68.  85. 100.]
  [ 49.  67.  84.  99. 111.]
  [ 66.  83.  98. 110. 118.]
  [ 82.  97. 109. 117. 122.]]

[[ 35.  53.  72.  90. 105.]
  [ 52.  71.  89. 104. 115.]
  [ 70.  88. 103. 114. 121.]
  [ 87. 102. 113. 120. 124.]
  [101. 112. 119. 123. 125.]]]

其中,奇数层奇数行奇数列,表示静态图块的绘制顺序,
而偶数层偶数行偶数列,表示其相邻的2个静态图块之间的移动动画的绘制顺序。
还是上面的例子,正中间的图块63,向下移动到图块94时,就应该使用其中间的图块79作为绘制顺序。

附上个这种顺序生成的示例代码:
  1. #! python3
  2. # coding: utf-8

  3. import numpy as np

  4. def order3(max_x, max_y, max_h):
  5.     arr = np.zeros([max_h, max_y, max_x])
  6.     depth = 0
  7.     idx = 1
  8.     while depth <= max_x + max_y + max_h - 3:
  9.         for h in range(max_h):
  10.             for x in range(max_x):
  11.                 y = depth - h - x
  12.                 if not 0 <= y < max_y:
  13.                     continue
  14.                 arr[h][y][x] = idx
  15.                 idx += 1
  16.         depth += 1
  17.     return arr

  18. if __name__ == '__main__':
  19.     arr3 = order3(3, 3, 3)
  20.     print('3 x 3 x 3')
  21.     print(arr3)
  22.     arr5 = order3(5, 5, 5)
  23.     print('5 x 5 x 5')
  24.     print(arr5)
  25.    
复制代码


回复

使用道具 举报

     
发表于 2021-4-11 09:25 | 显示全部楼层
本帖最后由 御风八极 于 2021-4-11 09:59 编辑

外行脑洞一下,
楼盖高一点,挑台浅一点。人物矮一点。即,柱子的上半部分和基座部分是两个层。人物都是大头,站在柱子前不会够到柱子上半部分。2楼挑高较高,隔层的下半部分是前景,上半部分是背景,1、2楼的人物不可能重叠。毕竟你也希望玩家看清楚角色对吧?
反正就是个2.5D视角的游戏,搞那么多暗角是为了钓玩家么?

要深纠的话,每一层地图做一个背景,重复每一层的物体上半部分做一个前景即可。
除非你一定要做出石林旅游的效果。如果那样的话,给每个图块加上一个基位参数,就是该物体的脚底(或者垂直影子)所在的地图坐标Y值,然后把这个坐标上的垂直图块封装成一个对象,比如一个柱子上的花瓶,算一整个物体,拥有一个唯一的基坐标,就是绘制地图时摆放的Y值。尽量减少额外变量,画地图的时候就自动指定了显示优先权。

当然,继续深究的话又会出现一个问题,上楼梯会不会从2楼地板钻出来。我觉得是不会的,因为2楼你要留楼梯口。但是数学上来说完全可以出现这种场景,比如2楼是格栅地板,主角变雾。那么此时这团雾穿过格栅地板,是以横线作为边界呢,还是根据雾团各点的亮度加权优先级呢?还是要做一个透明函数呢?请展开讨论。。。

又比如,主角扛着一根很长的矛上2楼,那么到底哪一级台阶触发改变楼层呢?
又比如,一个高背椅子,对于同样坐在该坐标的玩家来说,朝向不同时,遮挡关系也完全不同哦。如果这个主角吊儿郎当,坐姿不正经,一条腿在正面,一条腿耷拉在侧面,你就慢慢研究去吧。

最极端的情况我也想到了,克苏鲁游石林,请做出遮挡关系。
游戏的乐趣在于一定程度模拟现实但不是无限深究,玩家也会挑选游戏,找到合适的模拟深度。你研究2.5D也是因为画面美感体验较好,而不是因为它能完全仿真物体遮挡情况。
这就是Dota比魔兽星际好玩的理由。迪士尼乐园街道的房子后面都不是正经生活场所,本来就只是个剧场、舞台,不用事无巨细。






回复

使用道具 举报

 楼主| 发表于 2021-4-11 16:16 | 显示全部楼层
Tring 发表于 2021-4-11 00:43
我想了一下,确实是一个问题。
那这样的话,就只能在高度方面,也按镜头深度Z的顺序来绘制了。
对于一个3 ...

应该就是x+y+z吧,毕竟我不会怎么看码,其实昨晚也试了两样新排法,一样是按xy一层一层叠上去,一样就是x+y+z,这时我想起了角色不是一个立方体,而且我用的是很矮的砖,反正代码如下
  1. func sort():
  2.         for x in range(LEVELWIDTH):
  3.                 index.append([])
  4.                 for y in range(LEVELHEIGHT):
  5.                         index[x].append([])
  6.         var count = 0
  7.         for a in range(26):
  8.                 for x in range(LEVELWIDTH):
  9.                         if x > a:
  10.                                 break
  11.                         for y in range(LEVELHEIGHT):
  12.                                 if y > a:
  13.                                         break
  14.                                 for h in range(map[x*12 + y]):
  15.                                         if int(h / 3) > a:
  16.                                                 break
  17.                                         if x + y + int(h / 3) == a:
  18.                                                 move_child(room[x][y][h],count)
  19.                                                 count = count + 1
  20.                                                 if h + 1 == map[x*12 + y]:
  21.                                                         index[x][y] = room[x][y][h].get_index()
  22.                                                         print(index[x][y])
复制代码

结论就是没有修好边缘“出界”的问题,而且某些高度更bug了。虽然x+y+z貌似很有道理,但不得不把角色拆开,而且这不是像俯视可以横着一刀切。至于中间值我可以闭着眼睛就说不行,因为在中间表示有个地面的值会更高,即是地面盖住了人物。
回复

使用道具 举报

 楼主| 发表于 2021-4-11 16:59 | 显示全部楼层
御风八极 发表于 2021-4-11 09:25
外行脑洞一下,
楼盖高一点,挑台浅一点。人物矮一点。即,柱子的上半部分和基座部分是两个层。人物都是大 ...

关于长矛那就是2d的本质了,比如主角面向“上”砍敌人,不管什么状况武器肯定显示在敌人前面,因为它和主角是一整个部分。反正不用伤脑筋因为已经有人做过了,效果如下
只是现在看感到好像是刻意避过了某些状况…

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

     
发表于 2021-4-11 18:15 来自手机 | 显示全部楼层
mes 发表于 2021-4-11 16:16
应该就是x+y+z吧,毕竟我不会怎么看码,其实昨晚也试了两样新排法,一样是按xy一层一层叠上去,一样就是x ...

不管是中值还是扩展中间行列肯定是可以的,加上层高计算顺序后地面不是问题,因为地面在角色下一层,不可能会挡住角色。
回复

使用道具 举报

     
发表于 2021-4-11 21:49 | 显示全部楼层

https://codepen.io/BSoD_X/full/yLgvNyW

用上面说的扩展插行的方式实现的demo。
就这样了,你觉得行就行,觉得不行拉倒。

讲道理,闭着眼睛拍脑门说不行之前,还是先用脑子想想行不行吧。
回复

使用道具 举报

 楼主| 发表于 2021-4-12 11:40 | 显示全部楼层
本帖最后由 mes 于 2021-4-13 02:50 编辑
Tring 发表于 2021-4-11 21:49
https://codepen.io/BSoD_X/full/yLgvNyW

用上面说的扩展插行的方式实现的demo。


这个方法说不定是可以,所以有设计成一格这么高的游戏,应该就是为了和角色高度一致,也即是说角色不能高于一格。
但是本质上,不管设z值,按y轴,都是一个一个来,都要重新排一次,要是这样行那就是说一个一个排也应该有办法,这个方法有很多空位,应该有种算法能直接求出没空位的情况下插入哪里。

其实有个新的想法,姑且叫投影法,但似乎挺难写,也不知行不行,之前看到x+y+z时也觉得行了,结果是试试才知道还有什么问题,毕竟没那么好脑力。虽然问题是多层行不行,不过如果我自己做个小游戏一层楼就够了(不用上下交叉就像doom),只是虽然不知用不用上,也想保证非按格而是自由移动,也许有别的解法。


现在的排序方法,先把最底层先排了然后按斜格一个个向下扫,之后的会覆盖之前的,目测好像没大问题了,感觉尽力了,就算有也改地图凑合好了。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|上海互联网违法和不良信息举报中心|网上有害信息举报专区|962110 反电信诈骗|举报电话 021-62035905|Stage1st ( 沪ICP备13020230号-1|沪公网安备 31010702007642号 )

GMT+8, 2025-7-16 19:28 , Processed in 0.343382 second(s), 8 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表