# Fehler beim Laden eines 2D-Bildes



## Ramhotep (6. Feb 2016)

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):


```
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:


```
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:


```
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)];
     }
  }
}
}
```
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:


```
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();
    }
```
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


```
pixels[x+y*LAENGE] = sheet.pixels[(int)(x + y*sheet.LAENGE)];
```

zu 


```
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


----------



## Flown (7. Feb 2016)

Bitte benutz doch keine Farben, sonder Code-Tags, damit du den Code formatierst: [code=java]//Java Code HERE[/code]


----------



## Eichelhäer (19. Feb 2016)

Das hat er doch gemacht du Vogel !!!


----------



## Joose (19. Feb 2016)

Eichelhäer hat gesagt.:


> Das hat er doch gemacht du Vogel !!!



Nein hat er nicht. Flown hat den Beitrag editiert und angepasst.
Und Beleidigungen (auch wenns nichts schlimmes ist) sind im Forum nicht erwünscht.


----------

