# Tutorial von Quaxli (Problem)



## Honkisponk (27. Jun 2009)

huhu bin neu hier im Forum 

vorerst will ich mich mal bei Quaxli für das geile Tutorial (spiele programmierung) bedanken.
Aber bei diesem tutorial bin ich jetzt auf ein problem gestoßen.

Ich hab das jetzt bis seite 23 gemacht und wollte den heli anzeigen lassen, leider wirft er mir immer eine illegalArgumentException. Hab jetzt meinen code sogar mit dem fertigen code verglichen, aber ich finde einfach keinen Fehler. Jetzt hab ich mir gedacht das es evtl. an der java version liegen könnte, das ursprungsprogramm ist ja in 1.5 geschrieben. Vllt. hat sich da ja bis jetzt irgendwas geändert? Da ich aber erst seit ca. einem jahr (wegen Studium) java programmiere hab ich davon natürlich keine ahnung ^^

also ich tu mal hier meinen code rein, und hoff das mir irgendjemand helfen kann. Wollte nämlich umbedingt das tutorial fertig machen und mich dann in den Semesterferien in ein großes projekt stürzen . 


```
package volley;

import java.awt.*;

public interface Drawable {
	
	public void drawObject(Graphics g);

}
------------------------------------------------
package volley;

public interface Movable {
	
	public void doLogic(long delta);
	
	public void move(long delta);
	
}
------------------------------------------------
package volley;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*;

public class GamePanel extends JPanel implements Runnable {

	private static final long serialVersionUID = 1L;
	boolean game_running = true;
	long delta = 0;
	long last = 0;
	long fps = 0;
	
	Sprite copter;
	Vector<Sprite> actors;
	
	public static void main(String[] args) {
		new GamePanel(800,600);
	}
	
	public GamePanel(int w, int h) {
		this.setPreferredSize(new Dimension(w,h));
		JFrame frame = new JFrame("Volley");
		frame.setLocation(100,100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
		doInitializations();
	}
	
	private void doInitializations() {
		
		last = System.nanoTime();
		
		actors = new Vector<Sprite>();
		BufferedImage[] heli = loadPics("pics/heli.gif", 4);
		copter = new Sprite(heli,400,300,100,this);
		actors.add(copter);
		
		Thread t = new Thread(this);
		t.start();
		
	}
	
	public void run() {
		while(game_running) {
			
			computeDelta();
			doLogic();
			moveObjects();
			
			repaint();
			
			try {
				Thread.sleep(10);
			}
			catch(InterruptedException e) {
				
			}
		}
	}
	
	private void doLogic() {
		for(Movable mov:actors) {
			mov.doLogic(delta);
		}
	}
	
	private void moveObjects() {
		for(Movable mov:actors) {
			mov.move(delta);
		}
	}
	
	private void computeDelta() {
		delta = System.nanoTime() - last;
		last = System.nanoTime();
		
		fps = ((long) 1e9) / delta;
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		g.setColor(Color.red);
		g.drawString("FPS: " + Long.toString(fps), 20, 10);
		
		if(actors!=null) {
			for(Drawable draw:actors) {
				draw.drawObject(g);
			}
		}
	}
	
	private BufferedImage[] loadPics(String path, int pics) {
		
		BufferedImage[] anim = new BufferedImage[pics];
		BufferedImage source = null;
		
		URL pic_url = getClass().getClassLoader().getResource(path);
		
		try{
			source = ImageIO.read(pic_url);
		}
		catch(IOException e) {
		}
		
		for(int x=0;x<pics;x++){
			anim[x] = source.getSubimage(x*source.getWidth()/pics, 0, 
					source.getWidth()/pics, source.getHeight());
		}
		
		return anim;
	}
	
}
-----------------------------------------------------------------------------------------
package volley;

import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

public class Sprite extends Rectangle2D.Double implements Drawable, Movable {
	
	long delay;
	long animation = 0;
	GamePanel parent;
	BufferedImage[] pics;
	int currentpic = 0;
	protected double dx;
	protected double dy;
	
	public Sprite(BufferedImage[] i, double x, double y, long delay, GamePanel p) {
		pics = i;
		this.x = x;
		this.y = y;
		this.delay = delay;
		this.width = pics[0].getWidth();
		this.height = pics[0].getHeight();
		parent = p;
	}
	
	public void drawObject(Graphics g) {
		g.drawImage(pics[currentpic], (int) x, (int) y, null);
	}
	
	public void doLogic(long delta) {
		animation += (delta/1000000);
		if(animation > delay) {
			animation = 0;
			computeAnimation();
		}
	}
	
	private void computeAnimation() {
		
		currentpic ++;
		
		if(currentpic > pics.length) {
			currentpic = 0;
		}
		
	}

	public void move(long delta) {
		
		if(dx != 0) {
			x += dx*(delta/1e9);
		}
		
		if(dy != 0) {
			y += dy*(delta/1e9);
		}
		
	}
	
	public void setVerticalSpeed(double d) {
		this.dy = d;
	}
	public void setHorizontalSpeed(double d) {
		this.dx = d;
	}
	public double getVerticalSpeed() {
		return dy;
	}
	public double getHorizontalSpeed() {
		return dx;
	}
	

}
```

wenn das thema hier falsch ist, bitte ich um entschuldigung.

danke

mfg 
Honkisponk


----------



## Illuvatar (27. Jun 2009)

Wie lautet denn die genaue Fehlermeldung?


----------



## Honkisponk (27. Jun 2009)

das hab ich jetzt in der eile total vergessen ^^




> Exception in thread "main" java.lang.IllegalArgumentException: input == null!
> at javax.imageio.ImageIO.read(Unknown Source)
> at volley.GamePanel.loadPics(GamePanel.java:109)
> at volley.GamePanel.doInitializations(GamePanel.java:42)
> ...


----------



## Illuvatar (27. Jun 2009)

Das sieht so aus, als würde er das Bild "pics/heli.gif" nicht finden. Ist es sicher in dem Ordner / der jar?


----------



## Honkisponk (27. Jun 2009)

hab noch garkeine .jar gemacht. Da ich das prog mit eclipse geschrieben habe, ist das bild in \bin\volley\pics

(Mein Project/Package heißt volley weil ich auf grundlage des tuts ein kleines spiel ala BlobbyVolley programmieren wollte )

das komische ist, dass wenn ich die das prog aus dem Tutorium lade, der selbe fehler kommt.


----------



## SlaterB (27. Jun 2009)

wenn du
/bin/volley/pics
im Programm eintippen würdest, ginge es wieder,
oder besser die Bilder entsprechend aus bin verschieben,

relative Pfade beziehen sich normalerweise auf das Grundverzeichnis des Projekts


----------



## Honkisponk (27. Jun 2009)

danke für die antwort

also es hat jetzt funktioniert als ich "volley/pics/heli.gif" eingetippt habe.
irgendwie hat dein lösungsvorschlag net gefuntzt, aber erst dadurch bin ich draufgekommen *danke* 

jetzt startet er zwar das prog (bild wird auch angezeigt), aber jetzt kommt so eine Fehlermeldung



> at java.awt.EventDispatchThread.run(Unknown Source)
> Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 4
> at volley.Sprite.drawObject(Sprite.java:28)
> at volley.GamePanel.paintComponent(GamePanel.java:96)
> ...



die immer größer wird (wenn das programm läuft)



edit: ok hab grad den fehler selbst gefunden



> private void computeAnimation() {
> 
> currentpic ++;
> 
> ...



dort hat das "=" bei der if schleife gefehlt. (ich hoffe zumindest das es jetzt so stimmt, aber komisch ist das es in der ursprungsdatei vom tutorial ohne "=" ist)

also nochmal danke für die Hilfe, das forum hier ist echt genial


----------



## SlaterB (27. Jun 2009)

if-schleife.de


----------



## Quaxli (29. Jun 2009)

SlaterB hat gesagt.:


> if-schleife.de



:lol::lol::lol:


----------



## caphunter (23. Jul 2009)

Moin,

hab auch ein Problem mit dem Tutorial von Quaxli.

Und zwar wenn ich cloud.gif über loadPics() laden will bekomme ich immer diese Fehlermeldung:


```
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
        at javax.imageio.ImageIO.read(ImageIO.java:1362)
        at game.GamePanel.loadPics(GamePanel.java:171)
        at game.GamePanel.createClouds(GamePanel.java:237)
        at game.GamePanel.doInitialisations(GamePanel.java:73)
        at game.GamePanel.<init>(GamePanel.java:53)
        at game.GamePanel.main(GamePanel.java:58)
```

Das Bild befindet sich im selben Ordner wie heli.gif (pics). Würde ich createClouds() unter Kommentar setzen läuft alles wie gewohnt nur ohne Wolken. Weiß jemand wo das Problem liegen könnte?

Hier nochmal der Source vom GamePanel


```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.*;

/**
 *
 * @author HEADSHOT
 */
public class GamePanel extends JPanel implements Runnable, KeyListener
{
    private static final long serialVersionUID = 1L;
    boolean game_running = true;
    boolean started = false;
    boolean once = false;

    long delta = 0;
    long fps = 0;
    long last = 0;

    Heli copter;
    Vector<Sprite> actors;

    boolean up = false;
    boolean down = false;
    boolean left = false;
    boolean right = false;
    int speed = 50;

    public GamePanel(int w, int h)
    {
        this.setPreferredSize(new Dimension(w,h));
        JFrame frame = new JFrame("GameDemo");
        frame.setLocationByPlatform(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(this);
        frame.add(this);
        frame.pack();
        this.setBackground(Color.cyan);
        frame.setVisible(true);
        doInitialisations();
    }

    public static void main(String[] args)
    {
        new GamePanel(800,600);
    }

    private void doInitialisations()
    {
        last = System.nanoTime();

        actors = new Vector<Sprite>();

        BufferedImage[] heli = this.loadPics("pics/heli.gif", 4);

        copter = new Heli(heli, 400, 300, 100, this);

        actors.add(copter);

        createClouds();

        if(!once)
        {
            once = true;
            Thread t = new Thread(this);
            t.start();
        }
    }

    public void run()
    {
        while (game_running)
        {
            computeDelta();
            if (isStarted())
            {
                checkKeys();
                doLogic();
                moveObject();
            }
            repaint();

            try
            {
                Thread.sleep(10);
            }
            catch(InterruptedException e)
            {

            }
        }
    }

    private void computeDelta()
    {
        delta = System.nanoTime() - last;
        last = System.nanoTime();

        fps = ((long)1e9)/delta;
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.drawString("FPS: "+(long)fps, 10, 20);

        if(!isStarted())
        {
            return;
        }

        if (actors != null)
           for (Drawable draw:actors)
           {
               draw.drawObjects(g);
           }
    }

    private void checkKeys()
    {
        if (up)
            copter.setVerticalSpeed(-speed);
        if (down)
            copter.setVerticalSpeed(speed);
        if (right)
            copter.setHorizontalSpeed(speed);
        if (left)
            copter.setHorizontalSpeed(-speed);
        if (up && down)
            copter.setVerticalSpeed(0);
        if (left && right)
            copter.setHorizontalSpeed(0);
    }

    private void doLogic() {
        for (Movable mov:actors)
        {
            mov.doLogic(delta);
        }
    }

    private void moveObject() {
        for (Movable mov:actors)
        {
            mov.move(delta);
        }
    }
    public BufferedImage[] loadPics(String path, int pics)
    {
        BufferedImage[] anim = new BufferedImage[pics];
        BufferedImage source = null;
        URL pic_url = getClass().getClassLoader().getResource(path);

        try
        {
            source = ImageIO.read(pic_url);
        }
        catch(IOException ex) {ex.printStackTrace();}

        for (int x = 0; x < pics; x++)
        {
            anim[x] = source.getSubimage(x*source.getWidth()/pics, 0,
                    source.getWidth()/pics, source.getHeight());
        }
        return anim;
    }

    public void keyTyped(KeyEvent e) {

    }

    public void keyPressed(KeyEvent e)
    {
        if (e.getKeyCode() == KeyEvent.VK_UP)
            up = true;
        if (e.getKeyCode() == KeyEvent.VK_DOWN)
            down = true;
        if (e.getKeyCode() == KeyEvent.VK_LEFT)
            left = true;
        if (e.getKeyCode() == KeyEvent.VK_RIGHT)
            right = true;
    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP)
            up = false;
        if (e.getKeyCode() == KeyEvent.VK_DOWN)
            down = false;
        if (e.getKeyCode() == KeyEvent.VK_LEFT)
            left = false;
        if (e.getKeyCode() == KeyEvent.VK_RIGHT)
            right = false;

        if (e.getKeyCode() == KeyEvent.VK_ENTER)
        {
            doInitialisations();
            setStarted(true);
        }

        if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
        {
            if (isStarted())
                setStarted(false);
            else
            {
                setStarted(false);
                System.exit(0);
            }
        }
    }

    public boolean isStarted() {
        return started;
    }

    public void setStarted(boolean started) {
        this.started = started;
    }

    private void createClouds()
    {
        BufferedImage[] ci = this.loadPics("pics/cloud.gif", 1);

        for (int y=10; y < getHeight(); y+= 50)
        {
            int x = (int)(Math.random()*getWidth());
            Cloud cloud = new Cloud(ci, x, y,1000, this);
            actors.add(cloud);
        }
    }
    
}
```

EDIT:
So hab mal in der Methode createClouds() das cloud.gif mit heli.gif ersetzt - jetzt hab ich den Bildschirm voller fröhlicher Heli's^^
Kanns am GIF liegen? Ich habs mit selbsterstellten und die von quaxli probiert - cloud hat nie gefunzt.


----------



## Quaxli (23. Jul 2009)

Du solltest für ein neues Problem einen neuen Fred aufmachen....

Heißt Dein Bild auch genauso? clouds.gif? Nicht etwas z. B. clouds.GIF oder sonstige Varianten?


----------



## caphunter (23. Jul 2009)

Das Bild an sich heißt cloud.gif und es funzt nicht. Wenn ich aber heli.gif anstatt cloud.gif als Bild angebe, gehts. Wenn ich aber cloud.gif an der Stelle von heli.gif (BufferedImage[] heli ...) funktionierts ebenso nicht.

Ich versteh das echt nicht mehr...


----------



## Quaxli (23. Jul 2009)

Dann pack' doch mal alles und hänge es hier an.


----------



## caphunter (23. Jul 2009)

So, hier.


----------



## MiDniGG (23. Jul 2009)

Hmm... Ich build-ordner ist nur das heli-bild drin... vllt liegts daran.. kannst ja mal manuell noch da einfügen und nomma testen...


----------



## caphunter (23. Jul 2009)

Danke, jetzt funktionierts (...endlich!!!)


----------



## MiDniGG (23. Jul 2009)

caphunter hat gesagt.:


> Danke, jetzt funktionierts (...endlich!!!)



Na das ist aber toll. Nur komisch, dass das Bild bei nem build (^^) nicht mitkopiert wird...


----------

