# Laufanimation eines Sprites



## Eichelhäer (2. Sep 2015)

Hallo,

wie erstellt man eine saubere Laufanimation einer aus mehreren Einzelbildern bestehenden Animation?  Ich habe bereits mit einem Timer rumexperimentiert allerdings ohne zufriedenstellendes Ergebnis. Auch das Youtube Video von LionLek der die Interpolation beschreibt konnte mir nicht helfen.

Hier mal meine Player Klasse:


```
package game;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.Timer;

public class Robin {

    public int x = 200;
    public int y = 100;
    public int speed = 2;
    public boolean down;
    public int counter;
    Timer timer;
   
    public int imgcounter;
   
    BufferedImage[] robinimg;
   
    public Robin(){
       
        robinimg = new BufferedImage[9];
       
        try {
            //down
            robinimg[0] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(7,14,18,18);
            robinimg[1] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(28,14,18,18);
            robinimg[2] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(50,14,18,18);
            //right
            robinimg[3] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(7,37,17,20);
            robinimg[4] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(26,36,17,20);
            robinimg[5] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(46,36,16,20);
            //up
            robinimg[6] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(5,61,19,19);
            robinimg[7] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(27,60,17,20);
            robinimg[8] = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pics/Hood.png")).getSubimage(50,61,18,19);
       
        } catch (IOException e) {e.printStackTrace();}
    }
   
   
   
    public void update(){
       
        if(Keys.up){
            y -= speed;
           
            imgcounter = 6;
            imgcounter++;
            if(imgcounter==8){
                    imgcounter = 6;
            }
           
        }
       
        if(Keys.down){
            y += speed;
           
            imgcounter = 0;
            
        }
        if(Keys.left){
            x -= speed;
        }
        if(Keys.right){
            x += speed;
            imgcounter = 3;
        }
    }
   
    public void render(Graphics g){
        g.drawImage(robinimg[imgcounter], x, y,null);
    }
}
```

Wäre für Hilfe dankbar.


----------



## RalleYTN (2. Sep 2015)

Zu erst einmal warum lädst du ein und das selbe Bild 9 Mal. So wäre es performanter:

```
BufferedImage spriteBuffer = ImageIO.read(this.getClass().getClassLoader().getResourceAsStream("pics/Hood.png"));
BufferedImage[] tiles = new BufferedImage[9];
tiles[0] = spriteBuffer.getSubimage(7, 14, 18, 18);
....
```
Achja und versuch deinen Timer mal mit nem System.currentTimeMillis(). da brauchst du dann jedes Mal einen startTimer und einen updateTimer aber es funktioniert. Wenn man es richtig macht.


----------



## System.exit(0) (4. Sep 2015)

Es wäre auch einfacher, mit Frames per Second zu arbeiten.
Du lässt dir bei jedem Schleifendurchlauf die Zeit ausgeben, die seit dem letzten Aufruf vergangen ist.
Dann rechnest du die Bildfrequenz aus.
Weiterhin legst du die Bewegungsgeschwindigkeit in Pixeln pro Sekunde fest.
Nun brauchst du nur noch die inkrementelle Bewegung pro Bildaufbau auszurechnen und umzusetzen.

x = x + v / fps

mfg

System.exit(0)


----------



## RalleYTN (4. Sep 2015)

System.exit(0) hat gesagt.:


> Es wäre auch einfacher, mit Frames per Second zu arbeiten.


Mein ich doch.


----------



## Eichelhäer (17. Sep 2015)

Hallo,
danke für die Antworten.
Zum Problem... .
Ich habe die Bildfrequenz erfolgreich ausgerechnet beträgt 21 fps.
Der Wert für die Geschwindigkeit beträgt 3 Pixel.
In der update Methode des Sprites, dort wo die Tasten abgefragt werden, brauch ich nun noch etwas Hilfe.
Also:


```
...
public void update(long fps){
if(Taste.right){
x = x + (speed/fps);
```

Wo lade ich hier die einzelnen Bilder??


----------



## Eichelhäer (17. Sep 2015)

Hallo nochmal!!

Ich habs jetzt fast.

Das Problem it nun folgendes:

Die Animation läuft sehr, sehr schnell ab, während sich das Sprite als solches kaum vorwärts bewegt.

Hier mal der Code für nach Rechts gehen:


```
if(Taste.right){
//Bewegung
x = x + (speed/fps);
//Bildladen
counter++;
counter = counter%3;
imgcounter = counter+3;//das plus 3 ist nur ab welchem Sprite auf dem Spritesheet gezählt werden soll.
...
```

Die Geschwindigkeit pro Pixel beträgt momentan 100 und die fps betragen konstante 30.

Wäre für einen Denkantoß oder gar die Lösung ehr dankbar.

Grus Eichelhäer


----------



## Eichelhäer (18. Sep 2015)

Hallo,

habs gelöst. Der counter muss um einen niedrigeren Wert bei mir 0.25f hochgezählt werden dann gehts.


----------

