2016-07-05 27 views
7

Attualmente sto sviluppando un gioco Java 2D utilizzando Swing come componente di disegno principale. Ogni oggetto ha un'ombra (BufferedImage) ma ogni ombra si sovrappone ad altre ombre. È possibile solo che le ombre non si sovrappongano l'una all'altra? Perché voglio ancora che le ombre attirino il giocatore se l'oggetto è sotto di esso, e non se l'oggetto è sopra il giocatore. Ecco una foto per chiarezza:Gioco Java Ombre sovrapposte 2D con Swing

Screenshot

Ho guardato canale alfa, Credo che ho bisogno Fonte Out? Ho anche pensato che tutte le ombre (senza trasparenza) si disegnassero su un livello e poi lo disegnassero con trasparenza, ma poi non disegnerà sopra il giocatore e altri oggetti come prima.

Ho un oggetto Draw che è un JPanel e sovrascrive il metodo paintComponent. All'interno di questo metodo disegno il pavimento della stanza corrente e quindi eseguo un'iterazione sull'elenco di oggetti che appartengono alla stanza corrente e chiamiamo il metodo di disegno di ogni oggetto per disegnare tutto.

Il metodo draw oggetto:

public void draw(Graphics g) { 
    if (visible && checkInScreen()) { 

     // The required drawing location 
     int drawLocationX = getX() - globalCameraX; 
     int drawLocationY = getY() - globalCameraY; 

     if (shadow) { 
      g.drawImage(shadowImages.get(imageIndex), 
        drawLocationX + shadowOffset.x + (getImageWidth()/2), 
        drawLocationY + shadowOffset.y, null); 
     } 
     g.drawImage(images.get(imageIndex), drawLocationX, drawLocationY, null); 

     //Collisionbox 
     if (SHOW_COLLISION_BOXES){ 
      g.setColor(Color.WHITE); 
      g.drawRect(drawLocationX + getCollBoxX(), drawLocationY + getCollBoxY(), getCollBoxW() - getCollBoxX(), getCollBoxH() - getCollBoxY()); 
     } 
    } 
} 

Le mie scuse se questa domanda è già stata posta, ma non riuscivo a trovare qualcosa di simile come questo.

+0

Disegnare tutte le ombre su un livello è una buona idea. Se disegni le tue ombre per ultime, perché non attirano giocatori e oggetti? – eldo

+0

Ma le ombre non disegnerebbero l'oggetto che "proietta l'ombra"? Perché le ombre sono parzialmente dietro l'oggetto –

+0

No se le tue ombre sono solo parti che sono visibili in questo momento. Quindi un'ombra di alberi non coprirà mai l'albero stesso. – eldo

risposta

1

Quello che vorrei fare per risolvere questo è avere una bitmap a livello di ombra. Con il quale intendo: le trame shadow vengono salvate come array 2D di valori booleani (che rappresentano la posizione di un pixel ombra).

Quello che puoi fare con questo è logicamente o le mappe ombra insieme per creare un singolo livello, che può essere stratificato dietro le trame dell'albero per creare le ombre.

È possibile modificare i valori booleani in virgola mobile per rappresentare il colore/l'intensità dell'ombra, quindi disporre di un calcolo più ampio per unire le ombre.

La classe shadowmap seguito viene utilizzata per memorizzare i dati per ogni ombra:

class ShadowMap { 

    public int xPos, yPos; 
    public boolean[][] array; 

    public ShadowMap(int xPos, int yPos, boolean[][] array) { 
     this.xPos = xPos; 
     this.yPos = yPos; 
     this.array = array; 
    } 

} 

La classe ShadowLayer crea una matrice 2D per l'intero schermo, contenente se un'ombra è presente per ogni pixel:

class ShadowLayer { 

    public static boolean[][] array = new boolean[SCREEN_WIDTH][SCREEN_HEIGHT]; 

    public static makeNew(ShadowMap[] shadows) { 
     for (int x = 0; x < SCREEN_WIDTH; x++) { 
      for (int y = 0; y < SCREEN_HEIGHT; y++) { 
       array[x][y] = false; 
      } 
     } 
     for (ShadowMap map : shadows) { 
      for (int i = 0; i < SCREEN_WIDTH; i++) { 
       for (int j = 0; j < SCREEN_HEIGHT; j++) { 
        // Logical or such that the pixel at (x, y) has a shadow 
        // if any shadow map also has a shadow at pixel (x, y) 
        array[i + map.xPos][j + map.yPos] |= map.array[i][j]; 
       } 
      } 
     } 
    } 

} 

Utilizzando questa classe ShadowLayer, è solo bisogno di oscurare ogni pixel sullo schermo se lo shadowmap ha un'ombra sullo stesso pixel:

public static Color ajustPixelForShadows(int x, int y, Color pixel) { 
    return ShadowMap.array[x][y] ? pixel.darken() : pixel; 
}