# Probleme bei Sidescroller



## Maxim6394 (5. Apr 2012)

bei jeder kleinigkeit die ich verändern will treten immer wieder dutzende fehler auf die ich nicht nachvollziehen kann.
ich hab jetzt in dem spiel einen spieler, der sich korrekt bewegen kann, auch mit klettern und kollisionserkennung und springen und fallen etc.
jetzt hab ich eine gegnerklasse eingebaut. der gegner spawnt in der luft wie der spieler und fällt dann runter auf den boden, wie der spieler.
beide stehen dann richtig auf dem boden, so wie es sein sollte. aber wenn ich mit dem spielercharakter springe (yspeed wird ins negative verringert), sinkt der auf dem boden stehende gegner auf einmal in den boden sobald der spieler runterfällt(yspeed wird erhöht).
ich hab überhaupt keine ahnung wieso, es sind 2 voneinander unabhängige objekte.

ich hab hier die funktion um für alle sprite klassen den bewegungszustand zu updaten:

```
public void updateMovement() {
		
		if (climbing) {
			if (canClimb()) {

			} else {
				climbing = false;
				ySpeed = 0;
			updateMovement();
			
			}

		}

		else {
			if (onGround) {
				if (abstandUnten(gravity) > 0) {
					onGround = false;
				
				updateMovement();
				} else {

					ySpeed = 0;
				}
			} else {

				if (abstandUnten(gravity) < 1) {
					onGround = true;
				
				} else {
					if (this.ySpeed < this.gravity) {
						ySpeed += 2;

					}
				}
			}

		}

	}
```

und hier die methode für die eigentliche bewegung:

```
public void move(int x, int y) {

	

		int abstandRechts = abstandRechts();
		int abstandLinks = abstandLinks();
		int abstandUnten = abstandUnten(ySpeed);
		updateMovement();

			 if (ySpeed >= 0) {

					if (abstandUnten >= 0 && onGround==false) {
					this.y+=abstandUnten;
					}

		} 
		if (xSpeed > 0) {

			if (abstandRechts != 0) {
				this.x += abstandRechts; 
			} else {
				xSpeed = 0;
			}

		}

		else if (xSpeed < 0) {

			if (abstandLinks != 0) {

				this.x -= abstandLinks;
			} else {
				xSpeed = 0;
			}
		}

	}
```
die abstände gehen nur höchstens bis zur geschwindigkeit die sich das objekt pro loop bewegt.
hier zum beispiel abstandunten:

```
public int abstandUnten(int moveSpeed) {
		int abstand = 0;

		int limit = 0;
		if (moveSpeed < 0) {
			limit = -moveSpeed;
		} else if (moveSpeed > 0) {
			limit = moveSpeed;
		}

		for (int i = 0; i < limit; i++) {
			Rect bounds = new Rect(x, y + i, x + width, y + height + i);

			if (collision(gameView.sprites, bounds)) {
				break;
			}

			abstand++;
		}

		return abstand - 1;

	}
```

beim spieler hab ich die move funktion überschrieben, es wird dabei nicht das spielerobjekt selbst bewegt sondern jedes objekt in der gameView arraylist. da ist dann alles drin was im spiel zu sehen ist.


```
else if (ySpeed >= 0) {

			if (abstandUnten > 0) {
				gameView.moveLevel(0, -abstandUnten);
			}

		}
```


```
public void moveLevel(int x, int y) {

		this.x+=x;
		this.y+=y;
		
		for (Sprite s : sprites) {
			
			
				s.x += x;
				s.y += y
			
		}
	}
```

kann jemand irgendwas falsches erkennen?


----------



## Marco13 (5. Apr 2012)

Kann man anhand des geposteten kaum nachvollziehen. Ist irgendwo was 'static'?


----------



## Maxim6394 (5. Apr 2012)

ich hab für dieses problem jetzt wohl die lösung gefunden. bei der movelevel funktion hab ich vergessen die bounds zu updaten, das passiert dann erst viel zu spät und der gegner versinkt bisschen im boden wo er dann stecken bleibt.


----------



## Maxim6394 (9. Apr 2012)

ich hab jetzt das problem dass ich verschiedene ebenen haben will. einige sachen sollen also vor dem spieler sein, andere dahinter.
ich hab versucht jedem objekt eine layer variable zuzuweisen, momentan von 0 bis 3.
dann beim updaten bin ich erstmal in ner for schleife alle sprites durchgegangen um zu zählen wieviele ebenen es gibt. 
danach in einer for schleife die dinger in der richtigen reihenfolge malen. hier der code:

```
int layerCount=0;
	
			for (Sprite s : sprites) {
			
				if(s.layer>layerCount)
				{
					layerCount=s.layer;
				}
				s.onDraw(canvas);
			}
			
			if(player.layer>layerCount)
			{
				layerCount=player.layer;
			}

			
			for(int i=0;i<=layerCount;i++)
			{
				if(player.layer==i)
				{
					player.onDraw(canvas);
				}
				
				for(Sprite s:sprites)
				{
					if(s.layer==i)
					{
						
					
						s.onDraw(canvas);
					}
					
				
				}
			}
```

das problem ist jetzt, dass einige objekt wohl viel früher dargestellt werden als andere, dadurch heben sich zum beispiel die gegner vom boden ab, wenn sich der spieler grade bewegt. 
leider habe ich die ganzen update methoden bei ondraw integriert, also wird bei ondraw auch alles geupdatet. muss ich das darstellen des bildes und das updaten seperat machen oder hat jemand eine andere idee?


----------



## Fu3L (9. Apr 2012)

Ich würde eine LayerVariable nutzen und die Objekte direkt in einer HashMap<Integer, List<Entities>> speichern. So kannst du die Ebenen nacheinander zeichnen und hast keine Probleme rauszukriegen, wann was gezeichnet werden muss.


----------



## Maxim6394 (10. Apr 2012)

ich bin grade dabei meine gameloop zu optimieren, ich schaff es aber nicht dass das spiel immer gleichmäßig läuft. ich kann nicht erkennen ob die koordinaten etc. gleichmäßig geupdatet werden, aber auf jedenfalls wird es ungleichmäßig gemalt.
hier der code:

```
public void run() {

		double lastTick=0;
		int TPS=20;
		int MAX_FPS=40;
		double lastDraw=0;
		
		
		while (running) {

			
			double timeNow=System.currentTimeMillis();
			
			if(timeNow-lastTick>=1000/TPS)
			{
				lastTick=System.currentTimeMillis();
				
				view.updateGame();
				
			}
			
		
		
		if(timeNow-lastDraw>=1000/MAX_FPS)
		{
			lastDraw=timeNow;
			drawGame();
		}

}
```

ich versuche, das game höchstens 20 mal in der sekunde zu updaten, und höchstens 40 mal zu malen.
es ruckelt an manchen stellen ziemlich stark.
irgendwelche verbesserungsvorschläge?


----------

