我在等距墙上遇到了一些麻烦.
我正在使用从前到后渲染方法绘制等距地砖,它工作正常.我还将我的地砖正确排列在一个漂亮的网格中.代码(这似乎是等距地板绘图的标准)如下:
for(int x = 0; x < 6; x++){
for(int y = 3; y >=0 ; y--){
int xCo = (y+x)*(tileWidth/2);
int yCo = (x-y)*(tileHeight/2);
tile.draw(g, xCo, yCo);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个漂亮的小地板:
网格由此图块构成:

不幸的是,当我对墙壁使用相同的逻辑时,一切都是正确的.
for(int x = 0; x < 6; x++){
for(int y = 3; y >= 0 ; y--){
int xCo = (y+x)*(wallWidth()/2);
int yCo = (x-y)*(wallHeight()/2);
walls.draw(g, xCo, yCo);
}
}
Run Code Online (Sandbox Code Playgroud)
我用它作为我的墙砖:

(这是谷歌图片搜索的占位符,但它应该都是一样的)
这是我得到的结果:
我的墙壁的渲染顺序显然是正确的,更近的墙壁渲染在更远的墙壁上,这是我想要的,但定位也是非常不正确的,我不知道我应该如何纠正这个缺乏使用像素值.
作为参考,我确实使用硬编码像素值进行了试验,因为我发现从一个墙的右角到下一个墙的右角,变化恰好是(200,-100)像素.当我为我的渲染循环帐户
int xCo = (x+y)*200;
int yCo = (y-x)*-100;
Run Code Online (Sandbox Code Playgroud)
它工作正常,但这不是一个可行的解决方案,因为它不允许任何多功能性.
因此,寻找有关如何使我的等距墙排列的建议.我究竟做错了什么?
谢谢!
您不能简单地对墙壁和地板使用相同的绘图代码,因为墙壁和地板不在同一平面上:地板是平坦的(水平的),而墙壁是垂直的。所以你必须以稍微不同的方式绘制它们。
地板箱中的 x 和 y 坐标在瓷砖的放置方面意味着“左/右”和“向前/向后”。对于砖块来说,左和右仍然有意义,但我们想用上下替换向前/向后以反映垂直方向。所以我们的“y”有了新的含义。
现在,在数学中,y 轴通常指向上方,而在 2D 计算机图形中,y 轴通常指向下方。您可以选择 - 下面的代码假设它指向上方,因此y = 0意味着“在地板水平”。
那么让我们开始考虑顺序。您发布的示例砖块是用于地板左(上)端的墙。由于砖块的黑色部分(墙的深度),我们必须确保首先绘制更靠右的砖块,以便左侧的黑色深度将被更近的砖块覆盖。同样的论点也适用于墙顶部的黑色,我们必须先绘制较低的砖块。
如果我们坚持前面讨论的 x 和 y 方向(x 从左到右,y 从下到上),这意味着我们必须在负方向上运行两个 for 循环:
for (int y = 3; y >= 0; y--) {
for (int x = 5; x >= 0; x--) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在的主要问题是我们必须将每块砖的绘制相对于其他砖块偏移多少。让我们从 x 方向开始,一次一个方向地进行。
让我们想象一下只有两块相邻的砖块:

两者中的左侧有可见的黑色深度部分,但右侧不应显示它。因此,我们不能简单地将右图像偏移 PNG 的整个宽度。事实上,假设砖块与地砖对齐,墙壁前部的实际宽度应该与瓷砖宽度的一半相同。
int xCo = x * tileWidth / 2;
Run Code Online (Sandbox Code Playgroud)
左侧的黑墙深度不应被忽略,因为我们可能希望将每块砖稍微向左偏移一点,以便墙前角的 x 坐标与地砖对齐,而不是与地砖对齐。后角的坐标。
现在,每个砖块的 y 坐标有点棘手,因为它不仅取决于砖块行,还取决于 x 坐标:越靠右,我们应该画得越高。但让我们暂时忽略 x 方向并尝试简单地绘制一列砖块:

同样,两块砖块的 y 坐标之间的差值并不是 PNG 的完整高度。与左/右情况不同,我们假设砖块与瓷砖对齐,这允许我们使用tileWidthdelta-x,砖块可以具有任意高度。但我们仍然可以根据图像高度计算实际的砖块高度,因为我们知道左侧的深度和顶部的深度必须对齐。
如果我们看一下砖块PNG右上角的透明小三角形,我们会注意到它的宽度和高度的比率必须与地砖的宽度和高度的比率相同。这允许我们根据上面计算的 xoffset 计算 yoffset,并使用它来推断砖块的实际高度:
int yoffset = xoffset * tileHeight / tileWidth;
int wallHeight = wallHeight() - tileHeight / 2 - yoffset;
Run Code Online (Sandbox Code Playgroud)
请注意,这仅在 PNG 边界没有空白的假设下有效,并且由于舍入错误,它仍然可能失败。因此,如有必要,您可以在此处添加Math.ceil()(或简单地+ 1)。
因此,对于简单的列,我们现在就可以开始:我们可以简单地将y变量与上面的相乘wallHeight。但如前所述,砖块的 x 位置也会影响 y 像素坐标。如果我们再次查看第一张图片,其中两块砖块彼此相邻,我们需要将右侧砖块向上移动多少才能与左侧砖块对齐?嗯,这个其实很简单,因为它和地砖一样:是瓷砖高度的一半!
所以我们都准备好了。如果我们将所有内容放在一起,我们最终会得到如下代码:
int xoffset = wallWidth() - tileWidth / 2;
int yoffset = xoffset * tileHeight / tileWidth;
int wallHeight = wallHeight() - tileHeight / 2 - yoffset;
for (int y = 3; y >= 0; y--) {
for (int x = 5; x >= 0; x--) {
int xCo = x * tileWidth / 2;
int yCo = y * wallHeight - x * tileHeight / 2;
walls.draw(g, xCo - xoffset, yCo - yoffset);
}
}
Run Code Online (Sandbox Code Playgroud)
(我假设 wallWidth() 和 wallHeight() 返回砖块 PNG 的宽度和高度。)
请注意,for 循环之前的三个常量可以从实际的绘制代码中移出 - 它们仅依赖于图像属性和其他常量,并且不必在每次绘制墙壁时重新计算。