2015-04-12 32 views
0

我目前正在研究創建3D迷宮遊戲的Java項目,但我遇到了牆壁問題。事實上,當我們圍着一堵牆走時,它就消失了。就好像從後面看不到牆。爲什麼我的牆壁從後面看不見?

這裏是我的代碼(主要從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

嗨喬丹,歡迎來到堆棧溢出!謝謝你的問題。我編輯了它,以便它詢問我認爲你想知道的內容。 – deltab

+0

將問題移至問題開頭 – UmNyobe

回答

0

這是back-face culling,這是一種去除(通常)由於它們位於不透明物體的遠側上而不可見的表面的技術。 (想想一個立方體:你一次只能看到它的三個面)。這使得程序更快,因爲它的工作量較少。

你有兩個主要選擇,我想:

  • 刪除您所確定的線條:這將使所有的表面雙面,使他們無論他們面對哪種方式繪製。請注意,牆壁將非常薄,紋理鏡像在另一側。
  • 在需要它們的地方增加額外的(單面)表面。這使您可以在每一面上使用不同的紋理和光照,並且可以分離這些表面以便牆壁具有厚度。

您也可以使用這些變體,例如在某些位置添加額外的曲面並將其他標記爲雙面,或在繪製背面時切換到其他紋理。

順便嘗試在遊戲中設置noclip mode並在正常情況下限制的地方飛行:您可能會看到正在使用的這些和相關技巧。例如,在某些遊戲中,天空只能在窗戶內或室外區域的「天花板」上畫出。

+0

我不確定我是否同意立方體的觀點。我相信(對於一個立方體),如果你在立方體內部,就會呈現6個邊,但是(由於背面剔除),你不會看到它 –

0

感謝你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; 
    } 

和它的作品! 我現在正在研究碰撞問題,這將是一個很大的部分...

相關問題