2012-07-03 13 views
7

Więc tworzę grę opartą na kafelkach i chciałbym dodać do płytek fałszywe cienie. To trochę trudne do wytłumaczenia więc zrobię to ze zdjęciami:Jak skutecznie wykonać fałszywe cienie płytek?

Powiedzmy to moja dachówka świat:

world

I chcę go mieć cienie jak to:

shadows

Ponieważ świat jest oparty dachówka, mogę podzielić wszystkie części cień do oddzielnych obrazów:

parts

Ale teraz nie mam pojęcia, jak wprowadziłbym to do kodu. Cóż, tak naprawdę mam pomysły, ale są one niesamowicie nudne i nie działają optymalnie.

Próbowałem masywny if-oświadczenie ...

bool ul = adjacentBlocks[0, 0] == Block.Type.Rock; //Upper Left 
bool um = adjacentBlocks[1, 0] == Block.Type.Rock; //Upper Middle 
bool ur = adjacentBlocks[2, 0] == Block.Type.Rock; //Upper Right 

bool ml = adjacentBlocks[0, 1] == Block.Type.Rock; //Center Left 
//bool cm = adjacentBlocks[1, 1] == Block.Type.Rock; //CURRENT BLOCK - NOT NEEDED 
bool mr = adjacentBlocks[2, 1] == Block.Type.Rock; //Center Right 

bool ll = adjacentBlocks[0, 2] == Block.Type.Rock; //Lower Left 
bool lm = adjacentBlocks[1, 2] == Block.Type.Rock; //Lower Middle 
bool lr = adjacentBlocks[2, 2] == Block.Type.Rock; //Lower Right 

if (ml) { texture = "Horizontal"; flipX = false; flipY = false; } 
if (mr) { texture = "Horizontal"; flipX = true; flipY = false; } 
if (um) { texture = "Vertical"; flipX = false; flipY = false; } 
if (lm) { texture = "Vertical"; flipX = false; flipY = true; } 
if (ml && ul && um) texture = "HorizontalVertical"; 
//More if statements I can't be bothered to write 
if (ul && um && ur && ml && mr && ll && lm & lr) texture = "Full"; 

I masywna tabeli odnośników ...

var table = new List<TextureBlockLayout> 
             { 
              new TextureBlockLayout("Horizontal", false, false, new[,] 
                         { 
                          { true, true, false }, 
                          { true, true, false }, 
                          { true, true, false } 
                         }), 
              new TextureBlockLayout("Horizontal", true, false, new[,] 
                         { 
                          { false, true, true }, 
                          { false, true, true }, 
                          { false, true, true } 
                         }), 
              new TextureBlockLayout("Full", false, false, new[,] 
                         { 
                          { true, true, true }, 
                          { true, true, true }, 
                          { true, true, true } 
                         }) 
             }; 

Ale albo robię coś źle lub po prostu odmówić do pracy w ogóle. Jakieś pomysły?

+0

Co masz na myśli mówiąc „nie chcą pracować w ogóle?” – millimoose

+0

Zasadniczo dają całkowicie błędne tekstury cieni. – Dlaor

+0

Okay, ale ponieważ nie podano żadnego kodu rysunku, "całkowicie źle" niewiele pomaga. – millimoose

Odpowiedz

3

Każda płytka ma ośmiu sąsiadów. Każdy sąsiad ma dwa możliwe stany. Odwzorowuj stany sąsiednich na bity w bajcie i używaj bajtu jako indeksu w tabeli wyszukiwania zawierającej 256 elementów.

Tak, to jest rozwiązanie "brutalnej siły", a ty możesz być w stanie uzyskać o wiele mniejszą tabelę przy użyciu bardziej sprytnego podejścia. Ale 256 elementów nie jest tak wiele (możesz je łatwo załadować z pliku danych), a miłą rzeczą w tym podejściu jest to, że jest on całkowicie ogólny: — możesz mieć wszystkie 256 płytek wyglądać subtelnie inaczej, jeśli chcesz.


OK, biorąc bliżej przyjrzeć się drodze Twojej przykład płytki są zacienione, wygląda naprawdę tylko potrzeba czterech bitów (a zatem Tablica 16-elementowa):

  1. ustawić ten bit jeśli północ, zachód i północny zachód sąsiadami są zielone.
  2. Ustaw ten bit, jeśli sąsiedzi z północy, wschodu i północnego kraju są zieloni.
  3. Ustaw ten bit, jeśli południowi, zachodni i południowo-zachodni sąsiedzi są zieloni.
  4. Ustaw ten bit, jeśli południowi, wschodni i południowo-wschodni sąsiedzi są zieloni.

Nawet niektóre z tych 16 płytek są nadal obracanymi/lustrzanymi wersjami siebie, ale najłatwiej jest zapisać orientację w tabeli obok wskaźnika płytki, zamiast próbować obliczyć ją w kodzie.

0

chciałbym spróbować coś takiego:

struct surroundingTiles 
{ 
    static bool blockNE; 
    static bool blockN; 
    static bool blockNW; 
    static bool blockW; 
    static bool blockSW; 
    static bool blockS; 
    static bool blockSE; 
    static bool blockE; 
} 
foreach(object tile in floor) 
{ 
    if(currentTile.surroundingTiles.blockW && currentTile.surroundingTiles.blockNW && currentTile.surroundingTiles.blockN) 
     useTexture(currentTile, shadowSEtexture); 
} 
+0

Jeśli cienie mają znajdować się w ścianach, możesz spojrzeć na foreach jako (obiekt w ścianie) – impyre