Timebased tile scrolling wirkt unsauber.

Status
Nicht offen für weitere Antworten.

icerain

Mitglied
Hi,

ich hab beim scrollen meiner Tilebased Map leichte Probleme, das ganze wirkt sehr unsauber.

Erstmal grob was ich mache und am Ende 3 bsp zum ansehen:

Code:
public void loop() {
	long lastLoopTime = System.nanoTime();
	while (true) {
		long delta = System.nanoTime() - lastLoopTime;
		lastLoopTime = System.nanoTime();
		logic(delta);
		draw();
	}
}

public void logic(long delta) {
	lastLogicUpdate += delta;
	
	int factor = 1;
	if (keys[KeyEvent.VK_SHIFT])
		factor = 10;

	if (keys[KeyEvent.VK_LEFT])
		view.scroll((-delta * dx*factor) / ONE_SECOND, 0);
	if (keys[KeyEvent.VK_RIGHT])
		view.scroll((delta * dx*factor) / ONE_SECOND, 0);
	if (keys[KeyEvent.VK_UP])
		view.scroll(0, (-delta * dy*factor) / ONE_SECOND);
	if (keys[KeyEvent.VK_DOWN])
		view.scroll(0, (delta * dy*factor) / ONE_SECOND);		
}

public void draw() {
	Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
	g.setColor(Color.CYAN);
	g.fillRect(0,0,WIDTH,HEIGHT);
	view.draw(g); // draws the map
	g.dispose();
	strategy.show();
}

public void scroll(double dx, double dy) {
	screenAnchor.x += dx;
	screenAnchor.y += dy;
	// prevent from leaving the map
	if(screenAnchor.x < anchorSpace.x) screenAnchor.x = 0;
	if(screenAnchor.x > anchorSpace.width) screenAnchor.x = anchorSpace.width;
	if(screenAnchor.y < anchorSpace.y) screenAnchor.y = 0;
	if(screenAnchor.y > anchorSpace.height) screenAnchor.y = anchorSpace.height;
}

public void draw(Graphics2D g) {
	int tiles_x = screenSpace.width / tileSize.width;
	int tiles_y = screenSpace.height / tileSize.height;
	int sa_x = (int)screenAnchor.x;
	int sa_y = (int)screenAnchor.y;
	int ox = sa_x / tileSize.width;
	int oy = sa_y / tileSize.height;
	for(int y=0;y<tiles_y+1;y++) {
		for(int x=0;x<tiles_x+1;x++) {
			g.drawImage(map.map[oy+y][ox+x].image,
				x * tileSize.width - sa_x % tileSize.width,
				y * tileSize.height - sa_y % tileSize.height,
				null);
		}
	}
}
Wobei map[][] nen stink normales 2D Array vom Typ Tile ist.


So in Test 1 (Webstart 46kb) werden Zeilen 18-25 ersetzt druch
Code:
if (keys[KeyEvent.VK_LEFT])
	view.scroll(-1*factor, 0);
if (keys[KeyEvent.VK_RIGHT])
	view.scroll(1*factor, 0);
if (keys[KeyEvent.VK_UP])
	view.scroll(0, -1*factor);
if (keys[KeyEvent.VK_DOWN])
	view.scroll(0, 1*factor);
es findet also gar kein Timebased movement statt, was ehr schlecht is wenn man die fps nicht festsetzt, is nur als vergleich dabei, wobei ich finde, das das auch nicht viel besser aussieht.

In Test 2 (Webstart 46kb) ist der eigentliche Test wie er ganz oben steht ohne Veränderungen.

In Test 3 (Webstart 46kb) werden die Zeilen 50+51 ersetzt durch:
Code:
int sa_x = (int)Math.round(screenAnchor.x);
int sa_y = (int)Math.round(screenAnchor.y);
was aber auch nicht wirklich Linderung bringt...

Langsam gehen mir dir Ideen aus, vielleicht kann mir ja einer von euch weiterhelfen.
 

André Uhres

Top Contributor
Was meinst du mit unsauber? Bei mir laufen alle Tests einwandfrei.
Oder ist da irgendeine spezielle Bedienung zu beachten?
 

icerain

Mitglied
Bedienung... hmm ne mit cursorn scrollen und mit shift schneller.

Ich find das schmiert/verwackelt ein wenig und ruck ab und zu, in kurzen Intervallen, vorallem wenn man shift hält um schneller zu scrollen.
 

André Uhres

Top Contributor
icerain hat gesagt.:
Bedienung... hmm ne mit cursorn scrollen und mit shift schneller.

Ich find das schmiert/verwackelt ein wenig und ruck ab und zu, in kurzen Intervallen, vorallem wenn man shift hält um schneller zu scrollen.
Naja, wenn ich sehr genau hingucke, dann seh ich schon was in der Richtung, dabei hab ich aber noch keine besondere Grafikkarte.
 

Marco13

Top Contributor
Kann die Beispiele hier nicht starten, aber eine mögliche Ursache ist, dass System.nanoTime nicht besonders genau ist - das kann auch mal um 10, 20 ms falsch liegen. Eine weitere Mögliche Ursache: Was macht

strategy.getDrawGraphics();

???
(Ich habe da schon so eine Vermutung :roll: )
 

icerain

Mitglied
Ja strategy is eine Instanz der Klasse BufferStrategy und System.nanoTime is (zumindest auf Windows Rechnern) relativ genau, ich denke du meinst System.currentTimeMillis() das is nen Schätzeisen.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben