# Verbesserungvorschläge Spiel Z



## Seppel (16. Mrz 2012)

Hi, habe ein Spiel oder besser gesagt bin noch daran ein Spiel zu programmieren.
Das Gerüst sowie die Steuerung durch den Benutzer gehen schon fast vollständig.
Das Spiel basiert auf einen ähnlichen Konzept wie das Dos Spiel Z Z (Computerspiel) ? Wikipedia
Habe allerdings ätliche Änderungen vorgenommen und das Spiel Kinderfreundlicher und deutlich Lustiger gemacht.

Jetzt zu meiner Hauptfrage:
Ich habe 20 verschiedene Einheiten a 55 Gif Bilder. Manche nur 40*40 andere 100*100Pixel.
Die Bilder werden eingelsen und in einem Array abgepspeichert, welches zum Zeichen der Figuren benötigt wird. Da es zwei Manschaften geben soll und ich nicht alle Bilder doppelt malen wollte kam mir die Idee die alle Bilder zwei mal abzuspeichern. Einmal Original und einmal nach dem Austausch aller schwarzen Pixel durch Rote.
http://www.java-forum.org/awt-swing-swt/131785-pixel-gif-aendern.html

1. Das Ändern funktioniert nicht wirklich richtig
So werden die schwarzen Pixel nicht immer in Rot sondern auch in Orange oder Gelb geändert.
2. Gibt es eine bessere Möglichkeit die Bilder einzulesen und zu speichern, so das es schnell und weniger Speicherintensiv geht. Gut soviel ist es nicht, es dauert aber einige Zeit bis das Spiel startet...
3. Die Bilder sind alle in einem Ordner was kann ich machen damit ein Benutzer später mal, die Bilder nicht ändern kann. Was ich meine ist bei anderen Spielen findet man doch auch keine Bilder, selbst wenn man sieht das sie welche haben. (Ich hoffe ich ihr versteht mein Problem)

Hier mal die Komplette Funktion die die Bilder lädt:

```
public void bildladen() { 
        int i,j,k;      
        //Einheiten laden
        for(i=1;i<MAX_OBJEKTE_UND_EINHEITEN_ORDNER;i++){
            for(j=0;j<MAX_BILDER_PRO_ORDNER;j++){
                File weg1 =new File("Objekte"+ File.separator +i + File.separator +j+".Gif");
                try {  
                	einheitenBilder[i][j][0] = ImageIO.read(weg1);
                    //Alle Manschaften gleiche Bilder
                    for(k=1;k<MAX_MANSCHAFTEN;k++) {
                    	einheitenBilder[i][j][k] = ImageIO.read(weg1);
                    	//Für jede Manschaft andere Farbe
                        for(int x = 1; x<einheitenBilder[i][j][k].getWidth(this); x++){
                            for (int y = 1; y < einheitenBilder[i][j][k].getHeight(this); y++) {  
                                if(((BufferedImage) einheitenBilder[i][j][k]).getRGB(x,y)==Color.BLACK.getRGB()){  
                                    ((BufferedImage) einheitenBilder[i][j][k]).setRGB(x,y,(FARBE[k-1]).getRGB());
                                }   
                            } 
                        }
                    }
                    
                }
                catch (IOException e) {einheitenBilder[i][j] = null;}  
            } 
        }
        //Objekte und landschaft
        int groesse;
        for(i=0;i<2;i++){
        	if(i==-1)groesse=30;
        	else groesse=150;
	        for(j=0;j<MAX_OBJEKTE;j++){
	            File weg1 =new File("Objekte"+ File.separator +(i-1) + File.separator +j+".Gif");
	            try {                   
BufferedImage(groesse,groesse,BufferedImage.TYPE_INT_ARGB);
	            	objektBilder[i][j] = ImageIO.read(weg1);
	            }
	            catch (IOException e) {objektBilder[i][j] = null;}  
	        } 
        }
    }
```

Ich hoffe ihr könnt mit dem aus der Mitte gerissenen Code was anfangen.


----------



## Fu3L (16. Mrz 2012)

Zu 1) Das kann ich an deinem Code nicht nachvollziehen.

Zu 2) Lädst du mehrfach das gleiche Bild oder sind die alle für verschiedene Einheiten?

Zu 3) Wenn du Eclipse oder eine Vergleichbare IDE verwendest und dort ein "Runnable Jar File" erstellst, dann werden die Bilder, sofern sie sich im Source Ordner befinden mit in das jar kopiert. Allerdings kann man die da auch noch leicht ändern. Große Spiele nutzen meist ein eigenes Binärformat für ihre Grafiken und legen die so ab, dass sie direkt mit geringstmöglichen Aufwand in den Speicher geladen werden können. Um sowas würde ich mir erst Gedanken machen, wenn wirklich alles andere super läuft


----------



## Spacerat (17. Mrz 2012)

Fu3L hat gesagt.:


> Große Spiele nutzen meist ein eigenes Binärformat für ihre Grafiken und legen die so ab, dass sie direkt mit geringstmöglichen Aufwand in den Speicher geladen werden können. Um sowas würde ich mir erst Gedanken machen, wenn wirklich alles andere super läuft


Das ist zwar korrekt, aber um eines sollte man sich dabei schon Gedanken machen... Wie tausche ich im Nachhinein ein unperformantes Grafikformat gegen ein performantes für die komplette Anwendung mit möglichst wenig bis gar keinen Aufwand aus.
Die Farben in einem farbindizierten Bild (z.B. Gif) kannst du am besten über das Raster mit den Indices erreichen, vorrausgesetzt im ColorModel sind beide Farben vorhanden. Dazu holst du dir die beiden zu tauschenden Indices aus dem IndexColorModel, iterierst damit über die Raster-Elemente und tauscht so jeweils Index 1 mit Index 2.


----------



## Eiffelturm (17. Mrz 2012)

Allerdings, würde ich nicht Schwarz nehmen, und umändern, sondern die Flächen die geändert werden sollen, mit einer Farbe bepinseln, die man nicht braucht. (ich nehme immer 0xff00ff).

Viele Grüße


----------



## Seppel (17. Mrz 2012)

zu 1) Also Schwarz deswegen, weil ich das Bild dann gleich nutzen kann, sonst müsste ich bei zwei MAnschaften auch zwei mal ändern, das kostet Zeit. 
@ Spacerat mach ich das nicht bereit so? ich frag doch über indices und getRGB() die Farbe aus oder?
@ Fu3L das es nicht gehen soll, oder wie es gehen soll?

zu 2) es sind alles unterschiedliche Bilder
gut einige sind Spiegelverkehrt, die Frage ist hier nun ist es besser zur LAufzeit die Bilder ständig zu spiegeln oder lädt man jedes einfach einmal

zu 3) Eclipse, wenn das zusammengefasst wird ist das ja ne schlecht. Kennst sich jemand mit eigenen Binärformat erstellen aus, wie kann man da so ran gehen? Ich denke zwar nicht das wenn die Bilder einmal stehen noch viel geändert wird, man kann aber alles auch gleich richtig machen.

Danke für eure ersten Antworten


----------



## Marco13 (17. Mrz 2012)

Bis zu einem gewissen Grad unabhängig von den konkreten, sondern nur auf die allgemeine Frage (bzw. Verbesserungsvorschläge bezogen)

- Laden der Bilder und ändern der Pixelfarben in zwei verschiedene Methoden legen

- Nicht

```
int i;
for (i=0;i<MAX_WHATEVER; i++)
```
sondern

```
for (int i=0;i<MAX_WHATEVER; i++)
```

- Exceptions nicht verschlucken - Stacktrace ausgeben oder sonstige Fehlermeldung (oder ist es "Normal" dass bilder nicht gefunden werden?)

- 3D-Arrays sind höchst fragwürdig. Was sind die einzelnen Dimensionen?

- Wenn das ein Array von BufferedImages ist, dann auch als solchen speichern, und nicht als Image, dann kannst du dir die casts sparen

- Mehrfach verwendete Variablen (weniger wegen der Performance, sondern allein schon wegen der Übersichtlichkeit) zwischenspeichern:

```
for(int x = 1; x<einheitenBilder[i][j][k].getWidth(this); x++){
    for (int y = 1; y < einheitenBilder[i][j][k].getHeight(this); y++) {  
        if(((BufferedImage) einheitenBilder[i][j][k]).getRGB(x,y)==Color.BLACK.getRGB()){  
            ((BufferedImage) einheitenBilder[i][j][k]).setRGB(x,y,(FARBE[k-1]).getRGB());
        }   
    } 
}
```
->

```
Bufferedmage image = einheitenBilder[i][j][k];
for(int x = 0; x<image.getWidth(); x++){ // Hier sollte man wohl bei 0 anfangen
    for (int y = 0; y < image.getHeight(); y++) { // Hier sollte man wohl bei 0 anfangen
        if(image.getRGB(x,y)==Color.BLACK.getRGB()){  
            image.setRGB(x,y,(FARBE[k-1]).getRGB());
        }   
    } 
}
```
Wobei man da ggf. eine LookupOp (Java Platform SE 6) verwenden könnte, aber so weit muss man vielleicht gar nicht gehen.

BTW: Der Kommentar "[c] // Hier sollte man wohl bei 0 anfangen[/c]" bezieht sich nicht auf deinen Code oder Programmierstil, sondern auf die Indizes.

Wenn da am Ende sowas steht wie

```
List<BufferedImage> teamImages0 = loadTeamImages(0);
for (BufferedImage image : teamImages0)
{
    replaceColor(image, Color.BLACK, colors[0]);
}
```
oder so sieht das doch schon übersichtlicher aus.


----------



## Spacerat (17. Mrz 2012)

Seppel hat gesagt.:


> @ Spacerat mach ich das nicht bereit so? ich frag doch über indices und getRGB() die Farbe aus oder?


Äh... oder 
Wie du schon sagst, liest du den Farbwert, statt ihren Index im ColorModel aus. Anschliessend setzt du den Austauschwert ebenfalls wieder mit setRGB(). Das funktioniert aber nur bei nicht indizierten (A)RGB-Bildern korrekt. Bei indizierten Bildern aber wird der Farbwert vorher validiert. Das heisst, es wird fesgestellt, ob er in der Palette vorhanden ist und falls nicht wird einer gewählt, der dem gewünschten am ehesten entspricht.


----------



## Seppel (17. Mrz 2012)

@ Spacerat jetzt sehe ich den Unterschied danke
werde es mir mal näher anschauen

@ Marco13
1.- Laden der Bilder und ändern der Pixelfarben in zwei verschiedene Methoden legen
--> Sehr gute Idee

2.
Nicht? Wieso sollte das int in das for rein? BEi C geht es nicht anders, ist es auf Grund der Übersicht oder Performance bei Java?

- Exceptions nicht verschlucken - Stacktrace ausgeben oder sonstige Fehlermeldung (oder ist es "Normal" dass bilder nicht gefunden werden?)
Im Moment leider noch, denn ich habe erst die ein viertel aller Bilder gemalt und möchte nicht die Konsole voll Fehlermeldungen haben. Fehlende Bilder werden beim zeichnen im moment durch ein Testbild ersetzt.

- 3D-Arrays sind höchst fragwürdig. Was sind die einzelnen Dimensionen?
-->Typ der Einheit, im moment 20
-->Bild der Einheit,  max 60
-->Manschaftsfarbe, werden wohl 2-3 werden, wobei 3 nur dann eingeführt wird wenn ein Multiplayer Spiel gestartet wird, vorausgesetzt ich habe dazu noch Lust, nach dem ich eine KI gebastelt habe.

- Wenn das ein Array von BufferedImages ist, dann auch als solchen speichern, und nicht als Image, dann kannst du dir die casts sparen
Was ist besser? BufferedImages oder nur Image? Performance und Qualität sollen im Einklang gebracht werden. Auf meinen Rechnern merkt man keinen Unterschied.

- Mehrfach verwendete Variablen (weniger wegen der Performance, sondern allein schon wegen der Übersichtlichkeit) zwischenspeichern:
--> muss ich meinen Code noch mal überarbeiten, sehr guter hinweis danke

Weiter Fragen:
4.--> Ich habe zwar eine Idee für die KI, da ich aber nie vom Code oder besser gesagt der Struktur meiner KI's aus der Vergangenheit zufrieden war, suche ich neue Ideen dafür. Außerdem sollte während der Berechnung für die Züge der KI die PaintComponed Funktion nicht aussetzen. Ich möchte keinen Konkreten Code. Vieleicht kennt jemand einen Link oder hat disbezüglich sehr gute Erfahrung gemacht.
5--> Ich wollte während ein Spiel geladen wird im LadeBildschirm immer wieder ein neues Bild hinzublenden. MEine Idee mit einer variablen die hochgezählt wird, und die Paint funktion dadurch mehr zeichnen lässt funktioniert nicht, da während des ladens der Bilder die Paintfunktion nicht zeichnet.


----------



## Fu3L (17. Mrz 2012)

> Nicht? Wieso sollte das int in das for rein? BEi C geht es nicht anders, ist es auf Grund der Übersicht oder Performance bei Java?



Man soll den Scope der Variablen möglichst gering halten. So kann i nur in der Schleife genutzt werden.



> Was ist besser? BufferedImages oder nur Image? Performance und Qualität sollen im Einklang gebracht werden. Auf meinen Rechnern merkt man keinen Unterschied.



Es ist egal, ob dus Image nennst, so lange ein BufferedImage drin ist, ist nunmal ein BufferedImage drin. Performancetechnisch ändert sich nichts. (Edit: Das soll jetzt heißen: Nimm Marcos Vorschlag an^^)



> 4.--> Ich habe zwar eine Idee für die KI, da ich aber nie vom Code oder besser gesagt der Struktur meiner KI's aus der Vergangenheit zufrieden war, suche ich neue Ideen dafür. Außerdem sollte während der Berechnung für die Züge der KI die PaintComponed Funktion nicht aussetzen. Ich möchte keinen Konkreten Code. Vieleicht kennt jemand einen Link oder hat disbezüglich sehr gute Erfahrung gemacht.
> 5--> Ich wollte während ein Spiel geladen wird im LadeBildschirm immer wieder ein neues Bild hinzublenden. MEine Idee mit einer variablen die hochgezählt wird, und die Paint funktion dadurch mehr zeichnen lässt funktioniert nicht, da während des ladens der Bilder die Paintfunktion nicht zeichnet.



Du wirst ja vermutlich irgendwo einen GameLoop haben, wenn dein Design nicht hoffnungslos verkehrt ist. In dem rufst du die Methode zum Laden auf (zumidnest indirekt). In dieser Methode kannst du ja immer wieder ein repaint() feuern.
Die KI Berechnung solltest du in noch einen extra Thread auslagern, wenn sie wirklich so lange dauert. Dann wird auch der GameLoop nichtblockiert (und ruft weiter repaint() auf).

Zur KI kann ich sonst nichts sagen, noch nichts großartiges gemacht^^


----------



## Marco13 (17. Mrz 2012)

Seppel hat gesagt.:


> - 3D-Arrays sind höchst fragwürdig. Was sind die einzelnen Dimensionen?
> -->Typ der Einheit, im moment 20
> -->Bild der Einheit,  max 60
> -->Manschaftsfarbe, werden wohl 2-3 werden, wobei 3 nur dann eingeführt wird wenn ein Multiplayer Spiel gestartet wird



Ja aber wo und wann werden die Bilder denn Verwendet? Hast du nicht eine klasse "Unit" oder so, wo jeweils EIN bild drin liegen könnte? Mit diesem Array wirkt das schon sehr befremdlich...


----------



## Seppel (18. Mrz 2012)

Naja ich habe ein Array von Elementen der Klasse "Einheiten".
In der Paintfunktion wird dann für jedes Element abgefragt ob die EIgenschaft "aktiv" wahr ist (also das element exestiert im Spiel und kann gezeichnet werden. Wenn dem so ist wird der Typ der Figur, die Richtung in der gelaufen wird, sowie der schritt zustand(damit eine Bewegung zustande kommt) ermittelt und daraus folg dann das entsprechende Bild. NAch dem versteberne der Einheit kann das Element neu vergeben werden. Ich hatte mir gedacht wenn ich die die Bilder in die Kalsse packe müsste ich bei jeder änderung des Typen der Figur die Bilder aktualiesieren, da hatte ich es weggelassen...

Was die ZEichen MEthode angeht, so bin ich selbst noch nicht zufrieden. BEvor ich sie reinstelle werde ich erstmal noch einiges anarbeit inverstieren.


----------



## Fu3L (18. Mrz 2012)

> Ich hatte mir gedacht wenn ich die die Bilder in die Kalsse packe müsste ich bei jeder änderung des Typen der Figur die Bilder aktualiesieren, da hatte ich es weggelassen...



Das verstehe ich nicht ganz.

Im Normalfall hält eine Figur eine Referenz auf das Array seiner Animation. So können viele verschiedene Einheiten ein und die selbe Animation nutzen. Ändert sich die Bewegungsrichtung und du willst eine andere Animation anzeigen, musst du nur die Referenz austauschen und auf ein anderes Array zeigen. Das dauert wenns wirklich hoch kommt mit Überprüfung ein paar Nanosekunden^^ Für ein anderes Bild innerhalb einer Animation musst du auch so nur einen Index weiter (oder auf 0 zurück) gehen, was auch effizient ist^^


----------



## Spacerat (18. Mrz 2012)

[ot]Zum Thema Animation...
Da fällt mir gerade in Sachen GIF immer ein (mal wieder) total verhunztes Event-System (wenn man es so nennen möchte) des AWT ein. Warum müssen es eigentlich immer Arrays, Listen oder was auch immer sein, um die Bilder einer Animation zu speichern? Das die drawImage-Methoden eines Graphics-Objektes immer einen ImageObserver haben wollen, sollte ja jedem bekannt sein. Wer aber weis noch, was es damit auf sich hat? Selbiges gilt für ImageConsumer und ImageProducer.

```
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.ColorModel;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.util.Hashtable;

import javax.swing.JFrame;
import javax.swing.JPanel;


public final class GifAnimator
extends JPanel
{
	private static final long serialVersionUID = 4967963349618686309L;

	private final ImageObserver obs = new ImageObserver()
	{
		@Override
		public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
		{
//			repaint(x, y, width, height); // AAARRRRGGGHHH... wrong coordinates?
			repaint();
			return true;
		}
	};

	private final Image toDraw;

	public GifAnimator()
	{
		toDraw = Toolkit.getDefaultToolkit().createImage(getClass().getResource("myImageRessource.gif"));
		Dimension size = new Consumer(toDraw.getSource()).getSize();
		setMaximumSize(size);
		setMinimumSize(new Dimension(1, 1));
		setPreferredSize(size);
		setSize(size);
	}

	@Override
	protected void paintComponent(java.awt.Graphics g)
	{
		g.setColor(getBackground());
		g.fillRect(0,0, getWidth(), getHeight());
		g.drawImage(toDraw, 0, 0, getWidth(), getHeight(), obs);
	};

	public static void main(String[] args)
	{
		JFrame f = new JFrame("GifAnimator");
		f.add(new GifAnimator());
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.pack();
		f.setVisible(true);
	}

	/**
	 * A Class that waits for Image to become loaded
	 */
	private class Consumer
	implements ImageConsumer
	{
		private Dimension size;

		private Consumer(ImageProducer ip)
		{
			ip.startProduction(this);
			synchronized(this) {
				try {
					wait();
				} catch(InterruptedException e) {
					// nothing
				}
			}
		}

		public Dimension getSize()
		{
			return size;
		}

		@Override
		public void setDimensions(int width, int height)
		{
			size = new Dimension(width, height);
		}

		@Override
		public void setProperties(Hashtable<?, ?> props)
		{
		}

		@Override
		public void setColorModel(ColorModel model)
		{
		}

		@Override
		public void setHints(int hintflags)
		{
		}

		@Override
		public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize)
		{
		}

		@Override
		public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize)
		{
		}

		@Override
		public void imageComplete(int status)
		{
			synchronized(this) {
				notify();
			}
		}
	}
}
```
Das Ganze funktionierte schon lange vor ImageIO, mit ImageIO funktioniert es dagegen so leider gar nicht. ImageIO bringt einen nur auf die Idee Arrays von BufferedImage zu verwenden. Toolkit unterstüzt leider nur die Formate GIF, PNG und JPEG.[/ot]
Ach ja... warum ich das Ganze hier poste hat natürlich auch einen Grund... Man kann nun die einzelnen Animationen direkt als GIF nutzen bzw. refenenzieren weil für die Bilder keine Arrays mehr benötigt werden. Allerdings müssten die Animatonen nun vorher per externem Zeichenprogramm (z.B. PhotoShop/ImageReady oder CorelDraw) erstellt und ggf. auch verschieden eingefärbt werden.


----------



## Seppel (18. Mrz 2012)

@ Fu3L gut richtig hätte ich ne abfrage weniger


> Im Normalfall hält eine Figur eine Referenz auf das Array seiner Animation...


aber dann hätte ich doch wieder Arrays, nur mehrere halt!?
und statt einen Verweis auf das richtige array habe ich halt 2variablen über die ich das Bild wähle


----------



## Fu3L (18. Mrz 2012)

Aber es wäre wesentlich leichter zu überblicken^^ Man muss Performance und Übersichtlichkeit gegeneinander abwägen. Wie sagt man? "Divide and Conquer"?


----------



## Seppel (22. Mrz 2012)

So hier bin ich wieder.
Bin zwar noch immer am verbessern des Codes, und da gibt es sicherlich doch noch bissel Arbeit, habe aber mal zum Spaß das Projekt sammt Bilder Musik .. exportieren wollen.

Also habe ich Export--> jar File--> dann da Projekt samt aller Ordner die ich brauche ausgewählt und bin auf exportieren gegangen. Nach dem dritten Anlauf waren dann alle Fehler beseitigt und er hat eine jar-Datei erstellt.

Mein Problem:
Ich kann das Spiel über die jar Datei nur starten wenn alle Ordner Original imVverzeichniss sind. Ansonsten findet er nichts und zeigt somit auch nichts an. Außer ein weißer Bildschirm natürlich. und die Schrift.

Aber wie ich weiter oben schon schrieb will ich dem "Kunden" oder "Spieler" die Bilder im Original nicht geben, sondern die sollten nicht bearbeitbar sein.

Aber es soll ja gehen:


> Fu3L
> ...
> Zu 3) Wenn du Eclipse oder eine Vergleichbare IDE verwendest und dort ein "Runnable Jar File" erstellst, dann werden die Bilder, sofern sie sich im Source Ordner befinden mit in das jar kopiert. Allerdings kann man die da auch noch leicht ändern. Große Spiele nutzen meist ein eigenes Binärformat für ihre Grafiken und legen die so ab, dass sie direkt mit geringstmöglichen Aufwand in den Speicher geladen werden können. Um sowas würde ich mir erst Gedanken machen, wenn wirklich alles andere super läuft



Werde mal noch bissel experimentieren, vielleicht find ich den Fehler. Beim erzeugen, hat er aber alle Datein nach einander geladen.

Was könnte ich falsch gemacht haben.
Danke schon mal


----------



## Marco13 (22. Mrz 2012)

Sowas wie   
File weg1 =new File("Objekte"+ File.separator +i + File.separator +j+".Gif");
ist in einer JAR schwierig. Dort muss man mit getClass().getResourceAsStream() auf die Daten zugreifen.


----------



## Seppel (22. Mrz 2012)

Na dann muss ich halt das ändern:

vorher:

```
/*public void Menuebildladen() { 
        //MenüBilder
	    for(int j=1;j<MAX_MENUE_BILDER;j++){
	        File weg1 =new File("Objekte"+ File.separator + "OUTGAME" + File.separator +(j)+".Gif");
	        try {MenueBilder[j] = ImageIO.read(weg1);}
	        catch (IOException e) {MenueBilder[j] = null;}  
	    } 
    }*/
```

nachher:

```
public void Menuebildladen() { 
 for(int j=1;j<MAX_MENUE_BILDER;j++){
     try {
	    InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(File.separator+"Objekte"+ File.separator + "OUTGAME" + File.separator +(j)+".Gif");
	    if (is == null)	System.out.println(System.getProperty("user.dir")+"#"+File.separator+"Objekte"+ File.separator + "OUTGAME" + File.separator +(j)+".Gif" );
	    else   			MenueBilder[j] = ImageIO.read(is);
     } catch (IOException ioe) { ioe.printStackTrace(); MenueBilder[j] = null; }	    	
  } 
}
```

Geht dennoch ne da "is" immer null ist. da ich das Beispiel was ich gefunden habe 1:1 abgetippt habe (hoffentlich) müsste der Fehler bei mir liegen, nur für mich leider nicht sichtbar

@Marco13 du sagtest schwierig, ist also aber möglich...
nun gut wenn es dannach geht wie gewollt habe ich nix gegen die Änderung


----------



## Seppel (27. Mrz 2012)

zum Problem mit dem Pixel konvertieren find ich weder ein Beispiel noch ein einfaches zum Index Color Model was mir wirklich hilft. Im Gegenteil habe einige Beispiele gefunden bei dennen das genauso wie bei mir gemacht wurde. (Erfolg konnte ich nicht feststellen)

Hier noch mal der Code den ich zuerst hatte. Der neue Versuch mit dem IndexColorModel gelang nicht. Da habe ich es nicht mal geschaft das er die richtigen Pixel findet


```
public void konvertImage(BufferedImage BildSpeicher,int Manschaft){
        Color Farbe=FARBE[Manschaft-1];
	for(int x = 1; x<BildSpeicher.getWidth(this); x++){
            for (int y = 1; y < BildSpeicher.getHeight(this); y++) {              	
                if(BildSpeicher.getRGB(x,y)==Color.BLACK.getRGB()){  
                    BildSpeicher.setRGB(x,y,Farbe.getRGB());
                }   
            } 
       }
}
```

Die Schwarzen Pixel findet er ja, aber die neue Farbe stimmt nicht, obwohl Farbe.getRGB() immer gleich ist. Außerdem habe ich drei viele Bilder bei dennen ich immer exakt die gleichen Farben verwendet habe und dennoch ist die neue Farbe  immer anders, aber auch für jdes Bild konstant.
1. warum geht es hier? http://www.java-forum.org/awt-swing-swt/129747-setrgb-funktioniert.html
2. kennt jemand ein gutes Beispiel hierfür bzw für die anwendung mit dem IndexColorModel.

Danke


----------



## Fu3L (27. Mrz 2012)

```
if(BildSpeicher.getRGB(x,y)==Color.BLACK.getRGB()){  
                    BildSpeicher.setRGB(x,y,Farbe.getRGB());
                }
```

Hast du hier mal ein System.out reingesetzt, ob es aufgerufen wird? Hatte das, als ich sowas machte, auch. Es lag dann daran, dass gif oder in meinem Fall jpg bei der Komprimierung doch recht eigenwillig sind und meine Ursprungsfarbe gar nicht mehr vorhanden war. Ansonsten sieht das recht gut aus^^


----------



## Seppel (27. Mrz 2012)

ja er springt rein und wenn ich nach dem speichern das Bild wieder öffne mit irgend ein Malprogramm ist die Farbe gleich.

einer hat ja bei diesem Thema geschrieben das man ein IndexColorModel nutzen soll damit es immer klappt... doch wie?


----------



## Spacerat (28. Mrz 2012)

Ich war das mit dem IndexColorModel 
Also: Wie es aussieht lädst du Gif-Dateien als Einzelbilder. Dabei handelt es sich schon mal um eines der besagten Formate, welches ein IndexColorModel (eine Farbpalette) verwendet. Diese Farbpalette ist in Java Immutable, also in Anzahl der Farben sowie den einzelnen Farbinformationen festgelegt. Lädt man die Bilder nun als Einzelbilder ist nicht festgelegt, dass alle ein und dieselbe Palette haben und deswegen kann bei dem ein oder anderen Bild eine andere Farbe besser zur geforderten passen. Ich weis nicht, wie du deine Gifs erstellst, aber versuche mal, es hinzubekommen, dass alle erstellten Gifs eine einheitliche Palette verwenden, z.B. 216RGBCube+Grayscales (lässt sich z.B. bei PhotoShop einstellen). Damit kann man gewährleisten, dass eine gewählte Farbe stets gleiche Ergebnisse liefert.
Noch besser wäre aber die Methode ganze Gif-Animationen in verschiedenen Farben zu erstellen und diese dann wie schon gesagt zu animieren.


----------



## Seppel (28. Mrz 2012)

Hab alle mit Paint NET gezeichnet. BEsse gesagt eine gezeichnet (Mit vier Grundlegenden Farben) und dann 60 mal kopiert. Anschließend nur noch die Bilder geändert.

Bei Paint NEt kann man auch eine Farbpalette verwalten und die scheint immer gleich zu sein, schon deswegen weil ich eigentlich nix geändert habe. LAde aber mal Photo Shop herunter. 
Wenn alles ne hilft habe ich shon ne gute alternative: Alle Figuren gleich, aber je nach MAnschaft komt eine Art Overall drüber und die kann ich ja fertig machen.

Solange das mit dem Photoshop braucht (leider aufgrund ner technischen Störung mehrere Stunden) zu meinen anderen Problem:

Siehe meine Antwort vom 22.03.2012 16:21 mit dem exportieren als Jar und dem Problem mit dem richtigen laden. Irgend wo war da noch ein Fehler meiner seits.
Wäre für Hilfe dankbar


----------



## Fu3L (28. Mrz 2012)

Ich nutze dafür 


```
URL location = getClass().getClassLoader().getResource(path);
BufferedImage pic = null;
try {
	pic = ImageIO.read(location);
	return pic;
} catch (Exception ex) {
```

Das funktionierte bei mir immer. Gibt es im jar den Ordner img, so wäre path "img/bild.jpg" oder ähnlich.

Der Versuch es mit Photoshop zu probieren, ist es wert, aber ich denke nicht, dass es an Paint.NET liegt..


----------



## Spacerat (28. Mrz 2012)

Dran denken... mit ImageIO funktioniert die Gifanimation wie oben gezeigt nicht mehr, weil man nur das erste Bild vom Loader bekommt. Um mit ImageIO zu animieren benötigst du zusätzlich noch den entsprechenden Decoder.
Falls sichergestellt ist, das du Gifanimationen verwenden willst, kannst du die "location" auch per AWT-Toolkit in ein Image laden und wie oben beschrieben animieren.


----------



## Seppel (28. Mrz 2012)

Ging doch schneller als erst angezeigt.

Laut Photoshop sind die Bilder  indiziert und die Palette ist die normale RGB Palette.

zum exportieren: also die url ist immer null und das obwohl der Pfad eigentlich stimmt
Fehler: Input ImageIO.read  input == null!
aber: er braucht den Ordner nach dem erxportieren nicht mehr. Es geht also in die richtige Richtung:


```
public void Menuebildladen() { //MenüBilder
	    for(int j=1;j<MAX_MENUE_BILDER;j++){
	    	String pfad=new String(File.separator + "Objekte"+ File.separator + "OUTGAME" + File.separator +(j)+".Gif"); //es geht mit oder ohne dem ersten "File.separator +" nicht
		    URL location = getClass().getClassLoader().getResource(pfad);
			try {MenueBilder[j] = ImageIO.read(location);} 
			catch (Exception ex) {ex.printStackTrace(); MenueBilder[j] = null;}	    		
	    } 
    }
	    

//So geht es, aber nur mit Ordner nach dem Exportieren    	
public void Menuebildladen() { 
        //MenüBilder
	    for(int j=1;j<MAX_MENUE_BILDER;j++){
	        File weg1 =new File("Objekte"+ File.separator + "OUTGAME" + File.separator +(j)+".Gif");
	        try {MenueBilder[j] = ImageIO.read(weg1);}
	        catch (IOException e) {MenueBilder[j] = null;}  
	    } 
    }
```

@ Spacerat kann man die geschwindigkeit der animation auch wärend des Spieles noch regulieren?
ich schau mirs mal noch an. MEld mich dazu noch mal. Im Moment habe ich h erst mal ein laden Problem


----------



## Spacerat (29. Mrz 2012)

Du könntest in der update-Methode des ImageObservers eine Verzögerung einbauen.


----------



## Seppel (29. Mrz 2012)

wäre ne Idee,..
und zu dem anderen mit dem laden?


----------



## Seppel (5. Apr 2012)

Gut habe jetzt den Fehler bezüglich dem laden der Bilder über URl gefunden. Damit er das Bild lädt müssen sich die Bilder alle unter "bin" befinden


```
public void Menuebildladen() { //MenüBilder
	    for(int j=1;j<MAX_MENUE_BILDER;j++){
	    	String pfad=new String("Objekte"+ File.separator + "OUTGAME" + File.separator +j+".Gif");    
	    	URL location=null;
		    location = getClass().getClassLoader().getResource(pfad);
			try {MenueBilder[j] = ImageIO.read(location);} 
			catch (Exception ex) {/*ex.printStackTrace();/**/ 
				MenueBilder[j] = null; 
				logEintragen(" Fehler beim Bild lesen: ");
				logEintragen(System.getProperty("user.dir")+pfad);
				logEintragen(location+"");
			}	    		
	    } 
    }
```

Wenn ein Bild dirket im bin Ordner ist findet er es, tiefer verschachtelt nicht.

Hier mal ne Struktur, vileicht hilft die ja den Fehler zu finden:
E:\Programme\Eclipse\Workspace\2DWelt\bin
--> Alle Klassen
--> Der Komplette Ordner mi allen Bildern "Objekte"
--> Das TestBild 24.gif was er findet (auch nach dem exportieren wenn es gar nicht da ist
den Ordner mit samt Bilder findet er nie

E:\Programme\Eclipse\Workspace\2DWelt\bin\Objekte\OUTGAME
--> Hier sind die Bilder für das Menü der Ordner war bisher immer im HAptverzeichnis also:

E:\Programme\Eclipse\Workspace\2DWelt\Objekte\OUTGAME

Was habe ich übersehen bzw müsste ich anders machen? will nicht alle Bilder direkt unter bin ablegen, da das mehr als 1000 sind

Danke frohe Ostern


----------



## Landei (5. Apr 2012)

Schlecht: [c]String pfad=new String("Objekte"+ File.separator + "OUTGAME" + File.separator +j+".Gif");[/c]    
Gut: [c]String pfad="Objekte"+ File.separator + "OUTGAME" + File.separator +j+".Gif";[/c]

Strings sind unveränderlich, es gibt nur einen vernünftigen Grund, neue String-Objekte zu erzeugen, und der ist sehr speziell und liegt hier nicht vor ([c]substring[/c] o.ä. verhindert die Garbage-Collection des Original-Strings) .


----------



## Seppel (5. Apr 2012)

Habe ich geändert macht aber nichts aus.
Die Ausgabe die in der log.txt geschrieben wird ist immer noch für jedes Bild:

Thu Apr 05 16:06:15 CEST 2012--> Fehler beim Bild lesen: 
Thu Apr 05 16:06:15 CEST 2012-->E:\Programme\Eclipse\Workspace\Z2 fertigObjekte\OUTGAME\59.Gif
Thu Apr 05 16:06:15 CEST 2012-->null


----------



## Seppel (26. Apr 2012)

Und jemand ne Idee?


----------

