2013-10-24 74 views
1

我知道這個問題之前已經被問到過,但不幸的是我對這門語言很陌生,所以我發現的複雜解釋並沒有幫助我至少。基於網格的2D照明問題

我需要爲我的遊戲設計一個照明引擎,並且我嘗試了一些程序照明系統。此方法效果最佳:

if (light[xx - 1, yy] > light[xx, yy]) light[xx, yy] = light[xx - 1, yy] - lightPass; 
if (light[xx, yy - 1] > light[xx, yy]) light[xx, yy] = light[xx, yy - 1] - lightPass; 
if (light[xx + 1, yy] > light[xx, yy]) light[xx, yy] = light[xx + 1, yy] - lightPass; 
if (light[xx, yy + 1] > light[xx, yy]) light[xx, yy] = light[xx, yy + 1] - lightPass; 

(由「lightPass」變量,如果他們更明亮減去相鄰值) (這是在爲()循環)

這是所有好,除了花花公子幾個明顯的原因:

  1. 該系統有利於任何第一值到來時,在這種情況下向左(X - 1)
  2. 系統無法具有較深的值替換打火機值時,光源被刪除

這是上面的代碼是什麼樣的應用到我的比賽: Light

如果我能得到創建一個新的程序或其他照明系統,我真的很感激一些幫助!

+0

你可能想看看我們的姊妹網站:HTTP ://gamedev.stackexchange.com/ 我們很多人都急於幫助你。 :) –

回答

0

首先,我愛你的藝術風格:)基於

網格照明是一個艱難的一個我一直在尋找,最終我發現這樣做的方法。基本上每塊有一個Light價值,它發出多少光。和一個Absorb價值,它吸收多少光。

空白塊,一天中,可能有:

Light = 1; (Or Color.White for color) 
Absorb = 15; //Light flows for 15 blocks through blank tiles 

一條土塊,將有:

Light = 0; (Or Color.Black for color) //Emits nothing 
Absorb = 6; //Light flows for 6 blocks 

有了這個,你可以輕鬆地配置任何塊。在這個例子中,我會假設你有某種類中的一瓦片陣列,說Tile,其中包含一個Block,與LightAbsorb

我也會說,每一幀必須重置所有的照明與其默認值(空白爲1,灰塵爲0),然後重新計算照明(除非當然沒有任何變化,這會跳過重置和照明)

在我展示代碼之前,讓我解釋執行此操作所需的步驟:

基本上我們做的是循環遍歷所有的瓷磚,從頂部開始,如果瓷磚是空白的,請設置CurrentLight變量到最大亮度,如果我們找到一個實體瓷磚,將其設置爲CurrentLight變量,並從CurrentLight中減去「吸收」量。這樣,在我們下一個固體瓷磚上,當我們將瓷磚設置爲CurrentLight的值時,它會稍微更少。重複這個過程直到數組迭代。

Demo

現在,將創建一個從上到下的照明效果,循環必須重複,從右到左,從左到右,並從下到上。

用於在環路中的每個瓦片的代碼是:

if (tile.Light > CurrentLight) //If this tile is brighter than the last, set the current light to the tiles light 
    CurrentLightR = tile.Light; 
else if (CurrentLight != 0f) //If it is less, and isn't dark, then set the tile to the current light 
    tile.Light = CurLightR; 
if (tile.Light == CurLightR) //If it is the same, subtract absorb values 
    CurrentLight -= tile.Absorb; 

您還可以看到我是如何做到「平穩」的照明,here