2017-11-18 148 views
0
我目前使用pygame的光線投射引擎,pyray( https://github.com/oscr/PyRay/blob/master/pyray.py),並有一些問題我想問一下

添加精靈要Pygame的光線投射引擎

1)你如何添加一個精靈這是不一個細胞,就像Wolfenstein 3D中的敵人一樣?

2)你如何製作牆壁圖像,而不是顏色塊?

+0

我認爲這是唯一的發動機怎麼看光線投射作品,而不是引擎來創建遊戲 - 它沒有任何功能來放置精靈並繪製圖像。您必須自行添加此功能。 – furas

+0

我完成了我的答案的編輯。 – Spektre

回答

0
  1. 紋理

    第一次看到Ray Casting with different height size

    你需要的是改變你的引擎使用紋理的掃描線渲染。上述鏈接中的代碼僅供初學者使用(在代碼中查找// render scan line),並且可用於牆壁,但天花板和地板會出現扭曲。要解決您的問題,您需要申請perspective correct texture mapping

    這是怎麼樣子(後我把它落實到以前的代碼我聯繫)

    void Doom3D::draw_scanline(int sx,int sy0,int sy1,int sz0,int sz1,int symin,int tx0,int ty0,int tx1,int ty1,DWORD li) 
        { 
        // 
        union { DWORD dd; BYTE db[4]; } cc; 
        int Txs=txs*tn; 
        if (sz0==sz1) // affine texture mapping (front side of walls) 
         { 
         int sy,tx,ty,ktx,kty,dtx,dty,ctx,cty,dsy; 
           dsy=sy1-sy0; if (dsy<0)      dsy=-dsy; 
         ktx=0; dtx=tx1-tx0; if (dtx>0) ktx=+1; else { ktx=-1; dtx=-dtx; } tx=tx0; ctx=0; 
         kty=0; dty=ty1-ty0; if (dty>0) kty=+1; else { kty=-1; dty=-dty; } ty=ty0; cty=0; 
         if (dsy) for (sy=sy0;sy>=sy1;sy--) 
          { 
          if ((sy>=0)&&(sy<sys)&&(sy<=symin)) 
          if ((tx>=0)&&(tx<Txs)&&(ty>=0)&&(ty<tys)) 
           { 
           cc.dd=ptxr[ty][tx]; 
           cc.db[0]=DWORD((DWORD(cc.db[0])*li)>>8); 
           cc.db[1]=DWORD((DWORD(cc.db[1])*li)>>8); 
           cc.db[2]=DWORD((DWORD(cc.db[2])*li)>>8); 
           pscr[sy][sx]=cc.dd; 
           } 
          for (ctx+=dtx;ctx>=dsy;) { ctx-=dsy; tx+=ktx; } 
          for (cty+=dty;cty>=dsy;) { cty-=dsy; ty+=kty; } 
          } 
         } 
        else{   // perspective correct mapping (floor, top side of walls, ceiling) 
         int sy,tx,ty,dsy,dtx,dty,_n,n,dn; 
         int a,b,_z0,_z1; 
         const int acc=15; 
         dsy=sy1-sy0; n=abs(dsy); dn=n; 
         dtx=tx1-tx0; n=abs(dtx); if (dn<n) dn=n; 
         dty=ty1-ty0; n=abs(dty); if (dn<n) dn=n; 
         if (sz0==0) return; _z0=(1<<acc)/sz0; 
         if (sz1==0) return; _z1=(1<<acc)/sz1; 
         if (dn) for (n=0;n<=dn;n++) 
          { 
          sy=sy0+((n*dsy)/dn); 
          tx=tx0+((n*dtx)/dn); 
          ty=ty0+((n*dty)/dn); 
          // perspective correction (https://en.wikipedia.org/wiki/Texture_mapping) 
          _n=dn-n; 
          a=(_n*tx0*_z0) + (n*tx1*_z1); 
          b=(_n *_z0) + (n *_z1); tx=a/b; 
          a=(_n*ty0*_z0) + (n*ty1*_z1); 
          b=(_n *_z0) + (n *_z1); ty=a/b; 
          if ((sy>=0)&&(sy<sys)&&(sy<=symin)) 
          if ((tx>=0)&&(tx<Txs)&&(ty>=0)&&(ty<tys)) 
           { 
           cc.dd=ptxr[ty][tx]; 
           cc.db[0]=DWORD((DWORD(cc.db[0])*li)>>8); 
           cc.db[1]=DWORD((DWORD(cc.db[1])*li)>>8); 
           cc.db[2]=DWORD((DWORD(cc.db[2])*li)>>8); 
           pscr[sy][sx]=cc.dd; 
           } 
          } 
         } 
        } 
    

    sx,sy0,sy1是屏幕的協調掃描線tx0,ty0,tx1,ty1的是紋理座標和l0,l1從相機的距離。 li只是光線強度。紋理座標是每個網格單元命中座標的小數部分。使用的紋理是圖集,因此x座標也編碼使用哪個紋理。

    在此之上,你還應該添加紋理貼圖(接近投射單元尺寸使用的紋理分辨率),這將避免像素的遠處波光粼粼的牆壁上,而移動或轉身......

  2. 精靈

    對於每個對象計算其相對於玩家的極座標。所以你會有角度(相對於視圖方向)​​和距離。您可以從遠處直接從角度和屏幕y0,y1計算屏幕x。從那裏只是渲染每個掃描線+/-計算位置周圍的精靈寬度。你不需要爲精靈透視修正紋理映射,因爲它們總是垂直於玩家...

    所需的計算在這裏:Theory behind Wolfenstein-style 3D rendering