Non si può semplicemente utilizzare lo stesso codice di disegno per pareti come per pavimenti perché le pareti e pavimenti non sono sullo stesso piano: pavimenti sono piatte (orizzontale) mentre le pareti sono verticali. Quindi devi disegnarli in modo leggermente diverso.
vostre coordinate X e Y, nel caso piano significano qualcosa come "destra/sinistra" e "avanti/indietro" in termini di posizionamento delle piastrelle. Per i mattoni, sinistra e destra hanno ancora senso, ma vogliamo sostituire avanti/indietro con su e giù per riflettere la direzione verticale. Quindi la nostra "y" ha un nuovo significato.
Ora, in matematica, l'asse y di solito rivolta verso l'alto, mentre in grafica 2D per computer è rivolta verso il basso. Puoi scegliere: il codice sottostante presuppone che punti verso l'alto in modo che y = 0
significhi "al livello del pavimento".
Quindi iniziamo a pensare all'ordine. Il mattone di esempio che hai pubblicato è per un muro che sarebbe l'estremità sinistra (in alto) di un piano. A causa delle parti nere del mattone (la profondità del muro), dobbiamo assicurarci di disegnare i mattoni che sono più a destra prima in modo che la profondità nera sul lato sinistro sia coperta da mattoni più vicini. Lo stesso argomento vale per il nero sulla parte superiore del muro, dobbiamo prima disegnare i mattoni inferiori.
Se ci atteniamo alle direzioni x e y come discusso prima (x va da sinistra a destra, y va dal basso verso l'alto), questo significa che dobbiamo eseguire entrambi i nostri punti di forenza in direzioni negative:
for (int y = 3; y >= 0; y--) {
for (int x = 5; x >= 0; x--) {
...
}
}
la questione principale è ora quanto abbiamo per compensare il disegno di ogni mattone rispetto agli altri mattoni. Facciamo una sola direzione alla volta, iniziando dalla direzione x.
Immaginiamo solo due mattoni uno accanto all'altro:
La sinistra dei due ha la parte di profondità nera visibile ma il diritto non si dovrebbe vedere.Quindi non possiamo semplicemente compensare l'immagine giusta per l'intera larghezza del PNG. In effetti, supponendo che i mattoni si allineino con le piastrelle del pavimento, la larghezza della parte anteriore effettiva del muro dovrebbe essere uguale alla metà della larghezza di una piastrella.
int xCo = x * tileWidth/2;
La profondità muro nero a sinistra non dovrebbe essere ignorato, perché probabilmente vogliamo per compensare ogni mattone un po 'a sinistra in modo che la coordinata x del angolo anteriore delle linee parete al passo con i piastrelle del pavimento, non la coordinata x dell'angolo posteriore.
Ora, la coordinata y di ogni mattone è un po 'più complicata perché non dipende solo dalla riga del mattone, dipende anche dalla coordinata x: più a destra più in alto dovremmo disegnare. Ma ignoriamo direzione x per un attimo e cercare di disegnare semplicemente una colonna di mattoni:
Nuovamente, il delta tra le coordinate y dei due mattoni non è l'altezza del PNG . A differenza del caso di sinistra/destra in cui abbiamo ipotizzato che i mattoni si allineano con le tessere che ci hanno permesso di usare tileWidth
come delta-x, i mattoni possono avere altezze arbitrarie. Ma possiamo ancora calcolare l'effettiva altezza del mattone dall'altezza dell'immagine perché sappiamo che la profondità sul lato sinistro e la profondità sulla parte superiore devono essere allineate.
Se osserviamo il piccolo triangolo trasparente nell'angolo in alto a destra del PNG di mattoni, notiamo che il rapporto tra larghezza e altezza deve essere uguale al rapporto tra larghezza e altezza di una piastrella. Che ci permette di calcolare una YOffset dal xoffset calcolato sopra, e di utilizzare quella di dedurre l'altezza effettiva del mattone:
int yoffset = xoffset * tileHeight/tileWidth;
int wallHeight = wallHeight() - tileHeight/2 - yoffset;
Si noti che questo funziona solo sotto l'ipotesi che non c'è spazio vuoto al confine il PNG e potrebbe ancora fallire a causa di errori di arrotondamento. Quindi potresti aggiungere uno Math.ceil()
(o semplicemente + 1
) qui se necessario.
Quindi per le colonne semplici, siamo a posto ora: possiamo semplicemente moltiplicare la nostra variabile con il precedente wallHeight
. Ma come notato prima, la posizione x di un mattone influenza anche la coordinata del pixel y. Se guardiamo di nuovo la prima immagine con i due mattoni uno accanto all'altro, quanto abbiamo dovuto spostare il mattone destro per allineare il mattone sinistro? Bene, questo è in realtà facile, perché è lo stesso delle piastrelle del pavimento: metà dell'altezza di una piastrella!
Quindi siamo a posto. Se mettiamo tutto insieme, si finisce con un po 'di codice come questo:
int xoffset = wallWidth() - tileWidth/2;
int yoffset = xoffset * tileHeight/tileWidth;
int wallHeight = wallHeight() - tileHeight/2 - yoffset;
for (int y = 3; y >= 0; y--) {
for (int x = 5; x >= 0; x--) {
int xCo = x * tileWidth/2;
int yCo = y * wallHeight - x * tileHeight/2;
walls.draw(g, xCo - xoffset, yCo - yoffset);
}
}
(sto supponendo che wallWidth() e wallHeight() restituiscono la larghezza e l'altezza del mattone PNG.)
Si noti che le tre costanti prima dei cicli for possono essere spostate fuori dal codice di disegno effettivo - dipendono solo dalle proprietà dell'immagine e da altre costanti e non devono essere ricalcolate ogni volta che si disegna il muro.
Grazie per aver reso visibili le mie foto. Ho postato anche su gamedev.stackexchange e sono estremamente restrittivi su link e immagini, quindi non ho provato qui. –
Ho notato un motivo con le pareti: il bordo orizzontale superiore anteriore della prima parete è collineare con il bordo orizzontale inferiore anteriore della terza parete. Inoltre, il bordo verticale anteriore destro della prima parete è collineare con il bordo verticale posteriore sinistro della terza parete. Lo stesso vale per la seconda e quarta parete. Quindi sono un po 'in fila. Solo non nel modo che vuoi. – Kevin
Haha sì, è vero.In questo mi consolerò, ma non sono sicuro di cosa farne a parte "il mio metodo è solo a metà sbagliato" –