您不能简单地对墙壁和地板使用相同的绘图代码,因为墙壁和地板不在同一平面上:地板是平的(水平的)而墙壁是垂直的。所以你必须稍微不同地绘制它们。
就瓷砖的放置而言,您在地板案例中的 x 和 y 坐标意味着“左/右”和“前/后”。对于砖块来说,left 和 right 仍然有意义,但我们希望将 forward/backward 替换为 up 和 down 以反映垂直方向。所以我们的“y”有了新的含义。
现在,在数学中,y 轴通常指向上方,而在 2D 计算机图形中则指向下方。您可以选择 - 下面的代码假定它指向上方,这y = 0
意味着“在地板上”。
所以让我们开始考虑顺序。您发布的示例砖是用于作为地板(上)左端的墙。由于砖的黑色部分(墙的深度),我们必须确保首先绘制更靠右的砖,以便左侧的黑色深度会被更近的砖覆盖。相同的论点适用于墙壁顶部的黑色,我们必须先绘制较低的砖块。
如果我们坚持前面讨论的 x 和 y 方向(x 从左到右,y 从下到上),这意味着我们必须在负方向上运行两个 for 循环:
for (int y = 3; y >= 0; y--) {
for (int x = 5; x >= 0; x--) {
...
}
}
现在的主要问题是我们必须将每块砖相对于其他砖的绘制偏移多少。让我们一次只做一个方向,从 x 方向开始。
让我们想象一下只有两块相邻的砖块:
两者的左侧有可见的黑色深度部分,但右侧不应该显示它。因此,我们不能简单地将正确的图像偏移 PNG 的整个宽度。事实上,假设砖与你的地砖对齐,墙的实际前部的宽度应该是瓷砖宽度的一半。
int xCo = x * tileWidth / 2;
左边的黑色墙体深度不能忽略,因为我们可能想让每块砖向左偏移一点,这样墙前角的x坐标就和地砖对齐了,而不是x-后角的坐标。
现在,每块砖的 y 坐标有点棘手,因为它不仅取决于砖的行,还取决于 x 坐标:越靠右,我们应该画得越高。但是让我们暂时忽略 x 方向并尝试简单地绘制一列砖块:
同样,两块砖的 y 坐标之间的增量不是 PNG 的全高。与我们假设砖块与允许我们tileWidth
用作 delta-x 的砖块对齐的左/右案例不同,砖块可以具有任意高度。但是我们仍然可以从图像高度计算出实际的砖高度,因为我们知道左侧的深度和顶部的深度必须对齐。
如果我们看一下砖PNG右上角的小透明三角形,我们注意到它的宽度和高度的比例必须与地砖的宽度和高度的比例相同。这允许我们从上面计算的 xoffset 计算 yoffset,并使用它来推断砖的实际高度:
int yoffset = xoffset * tileHeight / tileWidth;
int wallHeight = wallHeight() - tileHeight / 2 - yoffset;
请注意,这仅在 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);
}
}
(我假设 wallWidth() 和 wallHeight() 返回砖块 PNG 的宽度和高度。)
请注意,for 循环之前的三个常量可以从实际绘图代码中移出——它们只依赖于图像属性和其他常量,不必在每次绘制墙壁时都重新计算。