Determina cosa disegnare in base alle tessere vicine?

1

Ho una tilemap e voglio aggiungervi dei muri. Ho dipinto 16 immagini, una per ogni combinazione possibile. Ad esempio:

  • Una tessera solitaria otterrebbe un'immagine con muri intorno.
  • Un angolo otterrebbe quattro delle immagini d'angolo.
  • Un'intersezione a T otterrebbe una delle 4 intersezioni a T.
  • ecc ...

Potrei fare 16 affermazioni, ma mi chiedevo se ci sarebbe stato un modo migliore per determinare quale piastrella deve essere posizionata. Ho visto un po 'di codice molto tempo fa, dove hanno usato il confronto dei bit per i muri, ma non so se potrebbe essere usato per questo specifico problema.

Un'altra opzione sarebbe utilizzare muri trasparenti e dipingerli dove necessario, quindi confrontarli e disegnare un'immagine di connessione nell'angolo poiché si sovrapporrebbe.

Per chiarimenti, incollo qui il mio metodo attuale. Che mi sembra amatoriale.

private void setCeilingTexture(Map map, int x, int y) {
    if (map.isWall(x - 1, y) && map.isWall(x, y + 1) && map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_open"));
        return;
    }
    //T intersections
    if (!map.isWall(x - 1, y) && map.isWall(x, y + 1) && map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_leftclosed"));
        return;
    }
    if (map.isWall(x - 1, y) && !map.isWall(x, y + 1) && map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_topclosed"));
        return;
    }
    if (map.isWall(x - 1, y) && map.isWall(x, y + 1) && !map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_rightclosed"));
        return;
    }
    if (map.isWall(x - 1, y) && map.isWall(x, y + 1) && map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_bottomclosed"));
        return;
    }

    //Single openings
    if (map.isWall(x - 1, y) && !map.isWall(x, y + 1) && !map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_leftopen"));
        return;
    }
    if (!map.isWall(x - 1, y) && map.isWall(x, y + 1) && !map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_topopen"));
        return;
    }
    if (!map.isWall(x - 1, y) && !map.isWall(x, y + 1) && map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_rightopen"));
        return;
    }
    if (!map.isWall(x - 1, y) && !map.isWall(x, y + 1) && !map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_bottomopen"));
        return;
    }

    //straight
    if (map.isWall(x - 1, y) && !map.isWall(x, y + 1) && map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_leftright"));
        return;
    }
    if (!map.isWall(x - 1, y) && map.isWall(x, y + 1) && !map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_topbottom"));
        return;
    }
    ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_single"));

    //corners
    if (map.isWall(x - 1, y) && map.isWall(x, y + 1) && !map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_topleftopen"));
        return;
    }
    if (!map.isWall(x - 1, y) && map.isWall(x, y + 1) && map.isWall(x + 1, y) && !map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_toprightopen"));
        return;
    }
    if (!map.isWall(x - 1, y) && !map.isWall(x, y + 1) && map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_bottomrightopen"));
        return;
    }
    if (map.isWall(x - 1, y) && !map.isWall(x, y + 1) && !map.isWall(x + 1, y) && map.isWall(x, y - 1))
    {
        ((Wall)map.getTileMap()[x][y]).setCeilingTexture(randomTexture("ceiling_bottomleftopen"));
        return;
    }
}

Funziona perfettamente, eppure ci deve essere un modo migliore di questo muro di dichiarazioni.

    
posta Madmenyo 28.02.2016 - 19:47
fonte

1 risposta

1

Se vuoi solo migliorare la leggibilità, perché non estrarre alcuni booleani per quelle condizioni? Allora le cose sarebbero più leggibili.

In alternativa, se vuoi un altro approccio, ecco cosa mi è venuto in mente:

Potresti farlo con alcune maschere di bit senza troppi problemi e semplificherebbe notevolmente il tuo codice. In pratica hai 4 flag: uno per ogni "muro".

Dichiariamo 4 flag per te.

public enum Flag {
    UP, DOWN, LEFT, RIGHT;
}

Grande. Ora dichiariamo un flag:

EnumSet<Flag> wallFlags

Crea un set basato sui muri. Lascerò questo come esercizio per te. Quindi, qui ci sono chiaramente alcune combinazioni che ti interessano, quindi cerchiamo di mappare quelle qui, creeremo una HashMap:

directionMap = new HashMap<Flag, String>();
directionMap.put(Flags.Up,  "myfilenamehere"
...

Questo potrebbe non essere compilato in quanto non ho lavorato in Java da un po 'ma dovrebbe essere vicino. Certo, hai ancora un bel po 'di codice di codice qui, ma ora mi appare subito ovvio come lettore. Puoi dire cosa sta succedendo senza leggere un gruppo di if che sono MOLTO simili.

    
risposta data 28.02.2016 - 21:45
fonte

Leggi altre domande sui tag