Guten Abend,
ich habe die letzten Tage mich mit der Struktur von Videospielen beschäftigt und dabei ein Programm geschrieben, welches dafür sorgt, dass in einem gegebenen JFrame jeder Pixel einzeln gesteuert werden kann. Dafür wollte ich ein Bild einladen welches daraufhin auf den Bildschirm gerendert wird.
Zuerst habe ich einen Spritesheet erstellt der das Bild einlädt (die Importe und nicht relevanten Methoden sind wie auch bei den folgenden Klassen ausgelassen):
Aus diesem Sheet wird dann der gewünschte Bereich, in diesem Fall das gesamte Bild ausgewählt und einem Pixelarray zugewiesen:
Danach wird der Pixelarray des Sprites in den Pixelarray des Bildschirms übertragen:
Zum Schluss wird in der Anwendung in einer sich immer wiederholenden Schleife (Für den Fall das sich Bild noch verändert) das Bild im JFrame angezeigt:
Zur Funktionsweise:
Am Anfang werden aus dem Bild (Tisch.jpg) in ein zugeschnittenes Array die RGB-Werte der Pixel geladen. In der Spriteklasse wird ein Pixel nach dem anderen einem exakt gleichen Array zugewiesen, da ja hier der Sprite gleich dem Spritesheet ist. Auch in der Bildschirmklasse sind die Pixel des Bildschirm die gleichen wie die des Sprites und in der Anwendung wird daraus dann ein Bild gemacht, welches dann im JFrame angezeigt wird. Man könnte also erwarten das im JFrame das ursprüngliche Bild angezeigt wird, jedoch erscheint nur ein seltsam verzerrtes halb ausgefülltes Bild(1.PNG).
Wenn ich in der Sprite-Klasse die Zeile
zu
änderte, bekomme ich zumindest ein unverzerrtes Bild (2.PNG).
Dazu ein paar Bemerkungen:
1: Die ausgefüllte Fläche ist nicht beliebig groß. Sie beträgt immer c.a. 60,3% also genau das Verhältnis von Hähe zu Breite des Bildes.
2: Die schwarze Fläche entsteht vermutlich daher, das in den Arrays manche Elemente keinen Wert zugewiesen bekommen haben, also standartgemäß den Wert 0 haben.
3: Im Terminal steht nichts von einer ArrayOutOfBounds-Exceptions jedoch steht dort, dass die Components eine "valid peer" haben müssen.
4: Bei 1.PNG sieht mann dass die Zeilen anscheinend nur die falsche Länge haben (vielleicht die der Höhe statt der Breite), da man klar sieht, dass die Zeilen vertikal nicht glatt ineinander übergehen, wodurch nur 60,3 % des Bildes erreicht werden
5: Wenn man den Befehl:
pixels[x+y*LAENGE] = sheet.pixels[(int)(x + y*sheet.HOEHE)];
benutzt, müssten doch manche Pixel des Sprites auf den gleichen Wert des Sheets zugreifen,
z.B. bei (x=1000, y=0) und (x=307, y=1)
Wenn jemand weiß was hier falsch läuft würde ich mich echt freuen, ich kann schon seit zwei Tagen nicht mehr gut schlafen
ich habe die letzten Tage mich mit der Struktur von Videospielen beschäftigt und dabei ein Programm geschrieben, welches dafür sorgt, dass in einem gegebenen JFrame jeder Pixel einzeln gesteuert werden kann. Dafür wollte ich ein Bild einladen welches daraufhin auf den Bildschirm gerendert wird.
Zuerst habe ich einen Spritesheet erstellt der das Bild einlädt (die Importe und nicht relevanten Methoden sind wie auch bei den folgenden Klassen ausgelassen):
Java:
public class SpriteSheet {
private String path;
public final int LAENGE, HOEHE;
public int[] pixels;
public static SpriteSheet Tisch = new SpriteSheet("/Tisch.jpg", 1000, 603);
public SpriteSheet(String path, int laenge, int hoehe){
this.path = path;
LAENGE = laenge;
HOEHE = hoehe;
pixels = new int [LAENGE*HOEHE];
load();
}
private void load(){
try{
BufferedImage image = ImageIO.read(SpriteSheet.class.getResource(path));
int w = image.getWidth();
int h = image.getHeight();
image.getRGB(0, 0, w, h, pixels, 0, w);
} catch (IOException e) {e.printStackTrace();}
}
}
Aus diesem Sheet wird dann der gewünschte Bereich, in diesem Fall das gesamte Bild ausgewählt und einem Pixelarray zugewiesen:
Java:
public class Sprite {
public final int LAENGE,HOEHE;
private int x,y;
public int[] pixels;
private SpriteSheet sheet;
public static Sprite Tisch = new Sprite(1000,603,0,0, SpriteSheet.Tisch);
public Sprite (int laenge, int hoehe, int x, int y, SpriteSheet sheet){
LAENGE = laenge;
HOEHE = hoehe;
pixels = new int [LAENGE * HOEHE];
this.sheet = sheet;
load();
}
private void load(){
for (int y = 0; y < HOEHE; y++){
for (int x = 0; x < LAENGE; x++){
pixels[x+y*LAENGE] = sheet.pixels[(int)(x + y*sheet.LAENGE)];}
}
}
Danach wird der Pixelarray des Sprites in den Pixelarray des Bildschirms übertragen:
Java:
public class Bildschirm {
private int höhe, länge;
public int [] pixels;
public Bildschirm (int höhe, int länge) {
this.höhe = höhe; //Macht die Parameter auch außerhalb des Konstruktors abrufbar
this.länge = länge;
pixels = new int[höhe*länge];
}
public void clear () {
for (int i=0; i < pixels.length; i++){pixels[i] = 0;}
}
public void render () {
for (int y = 0; y < höhe; y++){
for (int x = 0; x < länge; x++){
pixels[x+y*länge] = Sprite.Tisch.pixels[(x + y* Sprite.Tisch.LAENGE)];
}
}
}
}
Java:
private int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
public Anwendung()
{
Dimension Groeße = new Dimension (laenge,hoehe);
setSize (Groeße);
bildschirm = new Bildschirm (laenge,hoehe);
frame = new JFrame ();
key = new Tastatur();
addKeyListener (key);
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
bildschirm.clear();
bildschirm.render();
for (int i = 0;i < pixels.length; i++){
pixels[i] = bildschirm.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
Am Anfang werden aus dem Bild (Tisch.jpg) in ein zugeschnittenes Array die RGB-Werte der Pixel geladen. In der Spriteklasse wird ein Pixel nach dem anderen einem exakt gleichen Array zugewiesen, da ja hier der Sprite gleich dem Spritesheet ist. Auch in der Bildschirmklasse sind die Pixel des Bildschirm die gleichen wie die des Sprites und in der Anwendung wird daraus dann ein Bild gemacht, welches dann im JFrame angezeigt wird. Man könnte also erwarten das im JFrame das ursprüngliche Bild angezeigt wird, jedoch erscheint nur ein seltsam verzerrtes halb ausgefülltes Bild(1.PNG).
Wenn ich in der Sprite-Klasse die Zeile
Java:
pixels[x+y*LAENGE] = sheet.pixels[(int)(x + y*sheet.LAENGE)];
zu
Java:
pixels[x+y*LAENGE] = sheet.pixels[(int)(x + y*sheet.HOEHE)];
änderte, bekomme ich zumindest ein unverzerrtes Bild (2.PNG).
Dazu ein paar Bemerkungen:
1: Die ausgefüllte Fläche ist nicht beliebig groß. Sie beträgt immer c.a. 60,3% also genau das Verhältnis von Hähe zu Breite des Bildes.
2: Die schwarze Fläche entsteht vermutlich daher, das in den Arrays manche Elemente keinen Wert zugewiesen bekommen haben, also standartgemäß den Wert 0 haben.
3: Im Terminal steht nichts von einer ArrayOutOfBounds-Exceptions jedoch steht dort, dass die Components eine "valid peer" haben müssen.
4: Bei 1.PNG sieht mann dass die Zeilen anscheinend nur die falsche Länge haben (vielleicht die der Höhe statt der Breite), da man klar sieht, dass die Zeilen vertikal nicht glatt ineinander übergehen, wodurch nur 60,3 % des Bildes erreicht werden
5: Wenn man den Befehl:
pixels[x+y*LAENGE] = sheet.pixels[(int)(x + y*sheet.HOEHE)];
benutzt, müssten doch manche Pixel des Sprites auf den gleichen Wert des Sheets zugreifen,
z.B. bei (x=1000, y=0) und (x=307, y=1)
Wenn jemand weiß was hier falsch läuft würde ich mich echt freuen, ich kann schon seit zwei Tagen nicht mehr gut schlafen
Anhänge
Zuletzt bearbeitet von einem Moderator: