Hallo zusammen, ich brauche Hilfe bei der Verwendung von Offscreen Images und habe einige Fragen dazu. Ich hoffe, ihr könnt mir helfen.
Momentan versuche ich ein kleines Spiel zu programmieren (so eine Art primitives 2D Rollenspiel, in dem man bis jetzt noch nichts machen kann).
Dazu habe ich ein 2dimensionales Array erstellt, das für die Darstellung der Welt dient, indem ich in jedem Tupel abspeicher, welches Bild dort gemalt werden soll.
Dazu verwende ich BufferedImages, die ich im Konstruktor einlese. Meine Klasse, in der gezeichnet werden soll, ist ein JPanel. Ich habe das ganze nun zuerst ohne Offscreen Images realisiert und das Flackern hielt sich auch in Grenzen. Alles wird per repaint() in der Klasse, die ein Objekt dieses JPanels erstellt, alle 30ms neu gezeichnet.
(game.getMapY1() ist hier der obere Rand des sichtbaren Bereichs, game.getMapY2(), der untere. Dasselbe mit X für linken und rechten Rand. game.getView.. sorgt für das Verschieben des sichtbaren Ausschnitts der Welt.)
Dann kam mir die dumme Idee, Lichtquellen in der Welt zu benutzen und damit fing mein Ärger an und dort liegt auch mein Problem.
Da ich nämlich 1) statische Lichtquellen einbauen wollte, habe ich zusätzlich in jedem Tupel festgelegt, ob dort eine Lichtquelle sein soll oder nicht. Entsprechend bin ich nochmals das ganze Array durchgegangen und habe entweder ein halbtransparentes schwarzes Bildchen über das alte Bild gemalt oder ein schwarzes, beinahe vollkommen transparentes, damit das alte Bild darunter noch gut zu sehen ist.
So weit, so gut. Aber damit war ich leider nicht zufrieden. Da der Charakter nahezu ständig im Dunkeln tappte, 2) sollte es auch bei ihm hell sein. Deshalb habe ich ein komplett schwarzes Bild, was zur Mitte hin transparent wird über das gesamte Panel gezeichnet (der Charakter steht immer in der Mitte vom Panel).
Dabei habe ich jedoch nicht bedacht, dass ich die Dunkelheit mit 1) und 2) doppelt gemalt habe und auch die transparenten Stellen einmal übermalt werden.
Darum habe ich mir überlegt, dass ich die Dunkelheit mitsamt den transparenten Stellen aus 1) zuerst auf ein Offscreen Image zeichne und dann alle Pixel mit dem Bild aus 2) vergleiche, jeweils den helleren Pixel wähle und das neu entstandene Bild über das Panel zeichne. Und wo ich gerade eh dabei bin, ein Offscreen Image zu erstellen, hatte ich auch vor, das bisherige Bild zuerst auf so ein Offscreen Image zu zeichnen und danach erst auf das Panel.
--
An dieser Stelle muss ich sagen, dass mein Panel fast 600x400 groß ist und ihr spätestens hier schon aufhören könnt soviel Text zu lesen, wenn ihr denkt, dass das ganze viel zu viele Rechnungen benötigt, um den ganzen Vorgang ca. alle 30ms zu wiederholen.
--
Wenn es jedoch möglich ist, freue ich mich schonmal.
Ich habe dann folgende Images und Graphics-Objekte erstellt:
im Konstruktor:
(komische Größe, ich weiß)
Alles was vorher mit 'g.draw' anfing, habe ich mit durch 'off1.draw' ersetzt, am Anfang der paint()-Methode rufe ich jetzt noch
und am Ende
auf.
1. Problem: Das funktioniert - aber leider nur beinahe. Denn gezeichnet wird zwar auf diese Art und Weise, jedoch kommt es ab und zu immer noch vor, dass das Bild flackert und ich weiß nicht, woran das liegt, denn eigentlich wird ja nur noch ein einziges Bild gezeichnet und nicht mehr viele kleine. Muss ich vielleicht die update-methode überschreiben? Irgendwo habe ich sowas mal gelesen.
2. Problem: Das andere Offscreen Image (offScreen2), dass ein halb transparentes Schwarzes Bild mit "transparenten Löchern" darstellt, kann ich nicht über das erste malen, da der Hintergrund des Graphics-Objektes nicht transparent ist. Gibt es dafür eine Möglichkeit?
3. Problem: Falls das alles mal klappen sollte, bin ich nicht ganz sicher, wie ich die einzelnen Pixel der Bilder vergleichen kann. ???:L
Am meisten stört mich momentan das Geflacker...
Ich hoffe, ich habe nicht zuviel geschrieben oder versuche etwas zu absurdes zu realisieren. Vielleicht könnt ihr mir ja helfen.
Lieben gruß, Zul
Momentan versuche ich ein kleines Spiel zu programmieren (so eine Art primitives 2D Rollenspiel, in dem man bis jetzt noch nichts machen kann).
Dazu habe ich ein 2dimensionales Array erstellt, das für die Darstellung der Welt dient, indem ich in jedem Tupel abspeicher, welches Bild dort gemalt werden soll.
Java:
private Tiles[][] world;
Java:
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
for (int j = game.getMapY1(); j < game.getMapY2() && j < world[0].length; j++) {
for (int i = game.getMapX1(); i < game.getMapX2() && i < world.length; i++) {
if(world[i][j].getTerrain()!=null){
if (world[i][j].getTerrain() == "grass"){
g.drawImage(grass, i * TILESIZE + game.getViewX(), j * TILESIZE
+ game.getViewY(), null);
}
}
}
}
//usw
}
Dann kam mir die dumme Idee, Lichtquellen in der Welt zu benutzen und damit fing mein Ärger an und dort liegt auch mein Problem.
Da ich nämlich 1) statische Lichtquellen einbauen wollte, habe ich zusätzlich in jedem Tupel festgelegt, ob dort eine Lichtquelle sein soll oder nicht. Entsprechend bin ich nochmals das ganze Array durchgegangen und habe entweder ein halbtransparentes schwarzes Bildchen über das alte Bild gemalt oder ein schwarzes, beinahe vollkommen transparentes, damit das alte Bild darunter noch gut zu sehen ist.
So weit, so gut. Aber damit war ich leider nicht zufrieden. Da der Charakter nahezu ständig im Dunkeln tappte, 2) sollte es auch bei ihm hell sein. Deshalb habe ich ein komplett schwarzes Bild, was zur Mitte hin transparent wird über das gesamte Panel gezeichnet (der Charakter steht immer in der Mitte vom Panel).
Dabei habe ich jedoch nicht bedacht, dass ich die Dunkelheit mit 1) und 2) doppelt gemalt habe und auch die transparenten Stellen einmal übermalt werden.
Darum habe ich mir überlegt, dass ich die Dunkelheit mitsamt den transparenten Stellen aus 1) zuerst auf ein Offscreen Image zeichne und dann alle Pixel mit dem Bild aus 2) vergleiche, jeweils den helleren Pixel wähle und das neu entstandene Bild über das Panel zeichne. Und wo ich gerade eh dabei bin, ein Offscreen Image zu erstellen, hatte ich auch vor, das bisherige Bild zuerst auf so ein Offscreen Image zu zeichnen und danach erst auf das Panel.
--
An dieser Stelle muss ich sagen, dass mein Panel fast 600x400 groß ist und ihr spätestens hier schon aufhören könnt soviel Text zu lesen, wenn ihr denkt, dass das ganze viel zu viele Rechnungen benötigt, um den ganzen Vorgang ca. alle 30ms zu wiederholen.
--
Wenn es jedoch möglich ist, freue ich mich schonmal.
Ich habe dann folgende Images und Graphics-Objekte erstellt:
Java:
private BufferedImage offScreen1;
private Graphics2D off1;
private BufferedImage offScreen2;
private Graphics2D off2;
Java:
offScreen1= new BufferedImage(544,416,BufferedImage.TYPE_INT_ARGB);
off1= offScreen1.createGraphics();
offScreen2= new BufferedImage(544,416,BufferedImage.TYPE_INT_ARGB);
off2= offScreen2.createGraphics();
Alles was vorher mit 'g.draw' anfing, habe ich mit durch 'off1.draw' ersetzt, am Anfang der paint()-Methode rufe ich jetzt noch
Java:
off1.clearRect(0,0,544,416);
Java:
g.drawImage(offScreenImageDay,0,0,null);
1. Problem: Das funktioniert - aber leider nur beinahe. Denn gezeichnet wird zwar auf diese Art und Weise, jedoch kommt es ab und zu immer noch vor, dass das Bild flackert und ich weiß nicht, woran das liegt, denn eigentlich wird ja nur noch ein einziges Bild gezeichnet und nicht mehr viele kleine. Muss ich vielleicht die update-methode überschreiben? Irgendwo habe ich sowas mal gelesen.
2. Problem: Das andere Offscreen Image (offScreen2), dass ein halb transparentes Schwarzes Bild mit "transparenten Löchern" darstellt, kann ich nicht über das erste malen, da der Hintergrund des Graphics-Objektes nicht transparent ist. Gibt es dafür eine Möglichkeit?
3. Problem: Falls das alles mal klappen sollte, bin ich nicht ganz sicher, wie ich die einzelnen Pixel der Bilder vergleichen kann. ???:L
Am meisten stört mich momentan das Geflacker...
Ich hoffe, ich habe nicht zuviel geschrieben oder versuche etwas zu absurdes zu realisieren. Vielleicht könnt ihr mir ja helfen.
Lieben gruß, Zul