我目前正在开发一个Java项目,该项目涉及创建3D迷宫游戏,但我的墙壁存在问题。实际上,当我们绕墙走动时,它会消失;它就像从后面看不到墙。
以下是我的代码(主要来自YouTube用户" thecherno"):
public void renderWall(double xLeft, double xRight, double zDistanceLeft, double zDistanceRight, double yHeight) {
double upCorrect = 0.0625;
double rightCorrect = 0.0625;
double forwardCorrect = 0.0625;
double walkCorrect = -0.0625;
/* que se passe t-il quand on bouge vers la gauche sur l'axe des x */
double xcLeft = ((xLeft) - (right * rightCorrect)) * 2;
/* sur la gauche sur l'axe des z */
double zcLeft = ((zDistanceLeft) - (forward * forwardCorrect)) * 2;
/* quand on fait une rotation vers la gauche sur l'axe des x */
double rotLeftSideX = xcLeft * cosine - zcLeft * sine;
/* le coin du mur haut gauche */
double yCornerTL = ((-yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
/* bas gauche */
double yCornerBL = ((+0.5 - yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
/* quand on fait une rotation vers la gauche sur l'axe des z */
double rotLeftSideZ = zcLeft * cosine + xcLeft * sine;
/* Pour la droite */
double xcRight = ((xRight) - (right * rightCorrect)) * 2;
double zcRight = ((zDistanceRight) - (forward * forwardCorrect)) * 2;
double rotRightSideX = xcRight * cosine - zcRight * sine;
double yCornerTR = ((-yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
double yCornerBR = ((+0.5 - yHeight) - (-up * upCorrect + (walking * walkCorrect))) * 2;
double rotRightSideZ = zcRight * cosine + xcRight * sine;
double tex30 = 0;
double tex40 = 8;
double clip = 0.5;
if (rotLeftSideZ < clip && rotRightSideZ < clip) {
return;
}
if (rotLeftSideZ < clip) {
double clip0 = (clip - rotLeftSideZ) / (rotRightSideZ - rotLeftSideZ);
rotLeftSideZ = rotLeftSideZ + (rotRightSideZ - rotLeftSideZ) * clip0;
rotLeftSideX = rotLeftSideX + (rotRightSideX - rotLeftSideX) * clip0;
tex30 = tex30 + (tex40 - tex30) * clip0;
}
if (rotRightSideZ < clip) {
double clip0 = (clip - rotLeftSideZ) / (rotRightSideZ - rotLeftSideZ);
rotRightSideZ = rotLeftSideZ + (rotRightSideZ - rotLeftSideZ) * clip0;
rotRightSideX = rotLeftSideX + (rotRightSideX - rotLeftSideX) * clip0;
tex40 = tex30 + (tex40 - tex30) * clip0;
}
double xPixelLeft = (rotLeftSideX / rotLeftSideZ * height + width / 2);
double xPixelRight = (rotRightSideX / rotRightSideZ * height + width / 2);
/* si le coté gauche du mur passe au dela du coté droit */
if (xPixelLeft >= xPixelRight) {
return;
}
/*
* On cast les double en entier car les pixels sont placé dans un
* tableau d'entier
*/
int xPixelLeftInt = (int) (xPixelLeft);
int xPixelRightInt = (int) (xPixelRight);
/* Si ca depasse, on rend rien */
if (xPixelLeftInt < 0) {
xPixelLeftInt = 0;
}
if (xPixelRightInt > width) {
xPixelRightInt = width;
}
double yPixelLeftTop = (yCornerTL / rotLeftSideZ * height + height / 2.0);
double yPixelLeftBottom = (yCornerBL / rotLeftSideZ * height + height / 2.0);
double yPixelRightTop = (yCornerTR / rotRightSideZ * height + height / 2.0);
double yPixelRightBottom = (yCornerBR / rotRightSideZ * height + height / 2.0);
double tex1 = 1 / rotLeftSideZ;
double tex2 = 1 / rotRightSideZ;
double tex3 = 0 / rotLeftSideZ;
double tex4 = 8 / rotRightSideZ - tex3;
for (int x = xPixelLeftInt; x < xPixelRightInt; x++) {
double pixelRotation = (x - xPixelLeft) / (xPixelRight - xPixelLeft);
double zWall = (tex1 + (tex2 - tex1) * pixelRotation);
if(zBufferWall[x] > zWall){
continue;
}
zBufferWall[x] = zWall;
int xTexture = (int) ((tex3 + tex4 * pixelRotation) / (tex1 + (tex2 - tex1) * pixelRotation));
double yPixelTop = yPixelLeftTop + (yPixelRightTop - yPixelLeftTop) * pixelRotation;
double yPixelBottom = yPixelLeftBottom + (yPixelRightBottom - yPixelLeftBottom) * pixelRotation;
int yPixelTopInt = (int) (yPixelTop);
int yPixelBottomInt = (int) (yPixelBottom);
/* Si ca depasse, on rend rien */
if (yPixelTopInt < 0) {
yPixelTopInt = 0;
}
if (yPixelBottomInt > height) {
yPixelBottomInt = height;
}
for (int y = yPixelTopInt; y < yPixelBottomInt; y++) {
double pixelRotationY = (y - yPixelTop) / (yPixelBottom - yPixelTop);
int yTexture = (int) (8 * pixelRotationY);
// pixels[x + y * width] = xTexture * 100 + yTexture * 100 *
// 256;
pixels[x + y * width] = Texture.floor.pixels[(xTexture & 7) + 8 + (yTexture & 7) * 16];
zBuffer[x + y * width] = 1 / (tex1 + (tex2 - tex1) * pixelRotation) * 8;
}
}
}
我认为问题来自于此:
if (xPixelLeft >= xPixelRight) {
return;
}
为什么代码中包含导致墙壁消失的线条,以及如何从两侧看到墙壁?
答案 0 :(得分:0)
这是back-face culling,这种技术可以去除(通常)不可见的表面,因为它们位于不透明物体的远端。 (想想一个立方体:你只能同时看到它的三个面。)这样可以让程序更快,因为它可以减少工作量。
我认为你有两个主要选择:
您还可以对这些使用变体,例如在某些地方添加额外的曲面并在其他地方标记其他曲面,或在绘制背面时切换到其他纹理。
顺便说一句,尝试在游戏中设置noclip mode并飞到您通常受限的地方:您可能会看到这些和相关技术正在使用中。例如,在某些游戏中,天空只能在窗户内或室外区域的“天花板”上绘制。
答案 1 :(得分:0)
Thanx you deltab。
我写下这段代码:
if (xPixelLeft >= xPixelRight) {
double e = xPixelLeft;
xPixelLeft = xPixelRight;
xPixelRight = e;
e = rotLeftSideX;
rotLeftSideX = rotRightSideX;
rotRightSideX = e;
e = yCornerTL;
yCornerTL = yCornerTR;
yCornerTR = e;
e = yCornerBL;
yCornerBL = yCornerBR;
yCornerBR = e;
e = yPixelLeftTop;
yPixelLeftTop = yPixelRightTop;
yPixelRightTop = e;
e = yPixelLeftBottom;
yPixelLeftBottom = yPixelRightBottom;
yPixelRightBottom = e;
}
它有效! 我现在将解决这个问题,这将是一个很重要的问题......