# RPG Sprite-Player Anim Problem



## Polli85 (17. Okt 2007)

Hi Leute,
tolles Forum hier habe auch schon sehr häufig hier gute Informationen bekommen, 
nun muss ich aber mal etwas fragen. 


Und zwar mache ich als Schul-Projekt einen kleinen RPG GameEditor
bestehend aus zwei Hauptteilen:
  1. dem Game selber, wo man rumlaufen kann, Items sammeln etc (640*480)
 2. dem Editor, der mit dem SpielFrame zusammenarbeitet und Maps 
     bearbeiten und speichern kann 
     -die Maps sind Tile-basierend und werden mit Koordienaten in Dateien abgespeichert)
     -die Tiles sind 32*32 groß und auf eine map kommen 20*15 Tiles
     - wenn man über den Rand einer Map geht ist über Attribute die "NextMap" einstellbar

das meiste ist kein Problem, habe alles schön in Klassen aufgeteilt 
und bis jetzt läuft der Game und Editor-Modus ohne Probleme, durch double Buffering auch recht schnell.
Mein Problem besteht nun im animieren des Sprites(allgemein für NPC's und Players)
Bis jetzt sieht die selberstellte painting-Methode so aus, im Moment wird der Player auch nicht
animiert sondern nur zwischen FirstLevel und SecondLevel gezeichnet



```
public void painting(Graphics2D g){
		
		
		
		int j=0,k=0,l=0,m=0;
  		for(j=0; j < Map.viewBreite; j++){
  			for(k = 0 ; k < Map.viewHoehe; k++){
  				l=j*32;
  				m=k*32;
  				g.drawImage(ress.getMaps()[pl.getMapNr()].getIBottomTiles()[j][k],l,m,null);
  				
  			}
  		}
  		
  		j=0;k=0;l=0;m=0;
  		for(j=0; j < Map.viewBreite; j++){
  			for(k = 0 ; k < Map.viewHoehe; k++){
  				l=j*32;
  				m=k*32;
  				g.drawImage(ress.getMaps()[pl.getMapNr()].getIFirstLevelTiles()[j][k],l,m,null);
  				
  			}
  		}
  		
  --->>		g.drawImage(pl.getSpriteImage(),pl.getX(),pl.getY(),null);   <<----
  		j=0;k=0;l=0;m=0;
  		for(j=0; j < Map.viewBreite; j++){
  			for(k = 0 ; k < Map.viewHoehe; k++){
  				l=j*32;
  				m=k*32;
  				g.drawImage(ress.getMaps()[pl.getMapNr()].getISecondLevelTiles()[j][k],l,m,null);
  				
  			}
  		}
  		j=0;k=0;l=0;m=0;
  		if(edit){
  			for(j=0; j < Map.viewBreite; j++){
  				for(k = 0 ; k < Map.viewHoehe; k++){
  					l=j*32;
  					m=k*32;
  					if(!ress.getMaps()[pl.getMapNr()].getAttributeTilesLocArray()[j][k].equals("0\n")){
  						fAttr = new Font("Attribute",Font.BOLD, 12);
  						g.setColor(new Color(255, 0, 0));
  						g.setFont(fAttr);
  						g.drawString(ress.getMaps()[pl.getMapNr()].getAttributeTilesLocArray()[j][k], l+16, m+16);
  					
  					}
  				}
  			}
  		}
	}
```


Problem das ich nicht weiß wie ich den Sprite animieren soll (allgemein animieren), außerdem noch das der Hintergrund im Editor Modus dauernd aktualisiert werden muss und der Sprite zwischen den FirstLevelTiles und SecondLevelTiles gezeichnet werden sollte

Für Infos und Anregungen wäre ich sehr dankbar
Gruß Polli


----------



## Titanpharao (17. Okt 2007)

Ohne das ich dein Quellcode durchgelesen habe..

Habe das früher immer mit einer schleife gemacht, die denn NPC um x Felder versetzt hat.

Dannach repaint und schon haste ne Animation...nur muste dazu mit Thread.sleep(zeit); denn Frame Thread stilllegen...wie das geht bin ich auch noch am rätzlen...ging bis jetzt nur aus der Main herraus zu starten.

p.s.: Ich arbeite gerade an genau dem selben...und habe sowas ähnliches schonmal gemacht
Vergiss nicht das NPC's nicht durch Wände gehen können ;-)

http://img146.imageshack.us/my.php?image=ilsh2.jpg


----------



## Guest (17. Okt 2007)

lol ja NPC's und Players würde ich ja seperat von einer Sprite 
Klasse ableiten, damit dürfte das kein Problem sein 

aber das mit dem versetzen habe ich auch schon probiert aber entweder setzt 
das Hintergrundbild aus oder es fehlen die SecondLevel Tiles, oder der Sprite wird 
mit allen animImgaes hintereinander angezeigt, was ja eigentlich als abfolge sein soll
und nicht einfach zusammen angezeigt , bin am verzweifeln *heul*...

aber schon mal danke für die antwort


----------



## Polli85 (17. Okt 2007)

lol ja NPC's und Players würde ich ja seperat von einer Sprite 
Klasse ableiten, damit dürfte das kein Problem sein 

aber das mit dem versetzen habe ich auch schon probiert aber entweder setzt 
das Hintergrundbild aus oder es fehlen die SecondLevel Tiles, oder der Sprite wird 
mit allen animImgaes hintereinander angezeigt, was ja eigentlich als abfolge sein soll
und nicht einfach zusammen angezeigt , bin am verzweifeln *heul*...

aber schon mal danke für die antwort


----------



## Quaxli (18. Okt 2007)

Ich hab ja so gar nix verstanden, wo Euer Problem ist 
Wir sprechen ja von Java und Objektorientierung:

Damit ist üblicherweise Player eine eigene Klasse und Map eine eigene Klasse. Beide besitzen dann eine paint-Methode, die ein Graphics-Objekt übergeben bekommt und zwar das aus der paint-Methode des Game-Panel oder -Fensters.

Die Logik für das Zeichnen des Spielers und der Karte wird dann in den Methoden des jeweiligen Objektes erledigt. Alles andere macht auf Dauer keinen Spaß.


----------



## Polli85 (18. Okt 2007)

Hi Quaxli,
also das größte Problem besteht darin das ich nicht weiß
wie ich ne  NPC oder Player animieren soll.
ich habe für jede laufrichtung 3 Images, die eigentlich
flüssig angezeigt werden sollen wenn ich nen schritt
in irgendeine Richtung gehe(jeder Schritt ist im Moment 32 Pixel lang)
also so groß wie ein einzelnes Tile. Aber da ich nicht weiß wie 
ich das zeichnen kann oder das mit Threads steuern soll?!?! 
habe zwar schon ein bischen probiert aber das sieht eben nicht flüssig aus 

sowas wie das hier:


```
/*	public void anim(Graphics2D g){
double zeit = System.currentTimeMillis();

switch (direction){
// UP
case 0: {
	
	while(zeit > System.currentTimeMillis()-45){
		g.drawImage(spriteUp, x, y+32, null);
	}
	while(zeit > System.currentTimeMillis()-90){
		g.drawImage(spriteUp1, x, y+24, null);
	}
	while(zeit > System.currentTimeMillis()-135){
		g.drawImage(spriteUp2, x, y+16, null);
	}
	while(zeit > System.currentTimeMillis()-180){
		g.drawImage(spriteUp, x, y+8, null);
	}

	break;
}
// DOWN
case 1:{
	while(zeit > System.currentTimeMillis()-45){
		g.drawImage(spriteDown, x, y-32, null);
	}
	while(zeit > System.currentTimeMillis()-90){
		g.drawImage(spriteDown1, x, y-24, null);
	}
	while(zeit > System.currentTimeMillis()-135){
		g.drawImage(spriteDown2, x, y-16, null);
	}
	while(zeit > System.currentTimeMillis()-180){
		g.drawImage(spriteDown, x, y-8, null);
	}
	break;
}
// LEFT
case 2:{
	while(zeit > System.currentTimeMillis()-45){
		g.drawImage(spriteLeft, x+32, y, null);
	}
	while(zeit > System.currentTimeMillis()-90){
		g.drawImage(spriteLeft1, x+24, y, null);
	}
	while(zeit > System.currentTimeMillis()-135){
		g.drawImage(spriteLeft2, x+16, y, null);
	}
	while(zeit > System.currentTimeMillis()-180){
		g.drawImage(spriteLeft, x+8, y, null);
	}
	
	break;
}
// RIGHT
case 3:{
	while(zeit > System.currentTimeMillis()-45){
		g.drawImage(spriteRight, x-24, y, null);
	}
	while(zeit > System.currentTimeMillis()-90){
		g.drawImage(spriteRight1, x-16, y, null);
	}
	while(zeit > System.currentTimeMillis()-135){
		g.drawImage(spriteRight2, x-8, y, null);
	}
	while(zeit > System.currentTimeMillis()-180){
		g.drawImage(spriteRight, x-8, y, null);
	}
	break;
}
```


----------



## Titanpharao (18. Okt 2007)

Hier mal meine früherer Animation Klasse. Dabei muss ich sagen ist der nur "gesprungen".


```
class Animation extends Thread {
	int richtung;
	Engine fenster;
	public Animation(int richtung,Engine fenster){
		this.richtung=richtung;
		this.fenster=fenster;
	}
	public void run() {
		for (int i = 0; i < fenster.dbax / 8; ++i) {
		switch (richtung) {
		case 0:fenster.player.setXposi(fenster.player.getXposi() + fenster.dbax / 4);break;
		case 1:fenster.player.setYposi(fenster.player.getYposi() + fenster.dbay / 4);break;
		case 2:fenster.player.setXposi(fenster.player.getXposi() - fenster.dbax / 4);break;
		case 3:fenster.player.setYposi(fenster.player.getYposi() - fenster.dbay / 4);break;
		default:break;
		}
		fenster.repaint();
		/*try {
		Thread.sleep(75);
		} catch (InterruptedException e) {
		}*/
		}
	}
}
```

Würde das Thread.sleep() mal richtig laufen(wenn ich wüste wie) würde es "animiert" laufen.
Aber wir das mit deinen einzelbildern machen willst...meiner war "steif"  :meld:


----------



## Evil-Devil (18. Okt 2007)

So ähnlich würd ich es auch machen. Hier die Variante wie ich es bei nem 2D Shooter gemacht hab.


```
private final String[] TEXTURE_NAMES = {            
            "textures/ships/fly_frame0.png",    // standby / move
            "textures/ships/fly_frame1.png",    // standby / move
            "textures/ships/fly_frame2.png"     // attack
    };

public void standbyAnimation(Graphics g) {
        if (frameCounter < 10f) {
            frameCounter+= 0.5f;            
        } else {
            frameCounter = 0.0f;
            if (frame == 0)
                frame = 1;
            else frame = 0;
        }        
        textures[frame].drawTexture(position.getX(),position.getY(),g);        
    }

public void attackAnimation(Graphics g) {        
        fire();        
        if (frame == 1)
            textures[2].drawTexture(position.getX(),position.getY(),g);
        frame = 1;        
    }

public void drawActor(Graphics g) {       
        super.drawActor(g);
        if (System.currentTimeMillis() - lastFire < fireSpeed)
            standbyAnimation(g);
        else {
           attackAnimation(g);           
        }
        laser.drawWeaponShot(g);
    }
    
    public void fire() {		
		lastFire = System.currentTimeMillis();
        laser.fireWeaponShot();
    }
```

Natürlich kann sich der Actor während der Animation bewegen ^^


----------



## Evolver (18. Okt 2007)

Hast du nciht irgendwo eine update-Methode, die deine Objekte (Spieler, NPC, sonstwas) jenachdem, wieviel Zeit vergangen ist, aktualisiert? Also sagen wir die Spielfigug bewegt sich mit 10px pro Sekunden, dann findet die Verschiebung der Koordianten in der update-Methode satt, etwa so:
_if(bewegen==true) playerPos += 10*sekundenBruchteilSeitLetztemUpdate;_

Ist verständlich, was ich meine? In eben dieser update-Methode legst du dann auch fest, welche Animationsstufe beim nächsten Zeichnen ausgegeben wird, jenachdem, wieviel Zeit eben vergangen ist.
[/code]


----------



## Polli85 (18. Okt 2007)

Also erstmal danke für die Ideen 
das mit der Update Methode habe ich bis jetzt noch nicht,
oder besser gesagt bis jetzt habe ich nur eine Loop-fuction die 
als Thread dauerhaft am neuzeichnen ist. Aber ich denke 
das dürfte kein Problem sein das so umzutüfteln das daraus eine 
update Methode für deine genannte Idee wird.

Schonmal danke, werde mich sofort wieder ans Werk schmeißen 
damit ich irgendwann noch fertsch werde lol

falls es klappt oder nicht klappt melde ich mich morgen wieder cya leuts


----------



## Quaxli (18. Okt 2007)

Hier ist in epischer Breite meine Sprite-Klasse. Dort wird die Animation über ein Array gesteuert. Guck doch da mal rein, ist aber leider sehr viel Code.


----------



## Quaxli (18. Okt 2007)

Nachsatz: Die relevanten Methoden sind:

- doLogic
- doAnimation und 
- drawObject


----------

