Hallo Forum
Ich schreibe gerade mein Java-Spiel für Android um. Es funktioniert schon ganz ordentlich, aber es ruckelt immer ein Wenig. Ich habe mal in der LogCat geschaut und festgestellt, dass es die Funktion "SurfaceHolder.unlockCanvasAndPost(Canvas)" ist. Sie benötigt meist zwischen 40 und 100 Millisekunden, das ist einfach zu viel.
Hier mein Code:
Der Game-Loop:
Ausschnitt aus LogCat:
Weiss jemand, wie man dieses Problem beheben kann?
Mit freundlichen Grüssen, Faberix
Ich schreibe gerade mein Java-Spiel für Android um. Es funktioniert schon ganz ordentlich, aber es ruckelt immer ein Wenig. Ich habe mal in der LogCat geschaut und festgestellt, dass es die Funktion "SurfaceHolder.unlockCanvasAndPost(Canvas)" ist. Sie benötigt meist zwischen 40 und 100 Millisekunden, das ist einfach zu viel.
Hier mein Code:
Java:
public void repaint() {
if(!surfaceHolder.getSurface().isValid())
return false;
long start = System.currentTimeMillis();
Canvas canvas = surfaceHolder.lockCanvas();
System.out.println("lockCanvasTime: " + (System.currentTimeMillis() - start));
paint(canvas);
start = System.currentTimeMillis();
surfaceHolder.unlockCanvasAndPost(canvas);
System.out.println("unlockCanvasTime: " + (System.currentTimeMillis() - start));
}
Java:
protected void paint(Canvas canvas) {
long start = System.currentTimeMillis();
canvas.drawBitmap(background, new Rect(backgroundX,(int)(screenHeight), backgroundX + width, (int) (screenHeight + height)), new Rect(0, 0, width, height), null);
level.drawLevel(new Rect(strecke, (int)(screenHeight), strecke + width, (int)(screenHeight + height)), canvas);
for(EntityMonster monster : level.activeMonsters) {
monster.draw(canvas, strecke, (int)screenHeight);
}
if(equiptedPowerUp != null) {
if(!equiptedPowerUp.isDrawAfterCharacter())
equiptedPowerUp.draw(canvas, strecke, (int)screenHeight);
}
if(isGhost)
canvas.drawBitmap(currentCharacter, playerRelativePosX , PlayerRelativeHeight, ghostPaint);
else
canvas.drawBitmap(currentCharacter, playerRelativePosX, PlayerRelativeHeight, null);
for(EntityCoin coin : level.activeCoins) {
if(coin.isCollected) {
coin.draw(canvas, strecke, (int)screenHeight);
}
else {
canvas.drawBitmap(coinImgs[coinImgNum], coin.getRelativePositionX(strecke), coin.getRelativePositionY((int)screenHeight), null);
}
}
for(EntityPowerUp powerUp : level.activePowerUps) {
powerUp.draw(currentScreenGraphics, strecke, (int)screenHeight);
}
if(equiptedPowerUp != null) {
if(equiptedPowerUp.isDrawAfterCharacter())
equiptedPowerUp.draw(currentScreenGraphics, strecke, (int)screenHeight);
}
for(EntityFlyPlatform platform : level.activeMovingSolids) {
platform.draw(currentScreenGraphics, strecke, (int)screenHeight, flyPlatformImgNum);
}
canvas.drawBitmap(healthImages[Health], width - healthImageWidth, 4, null);
canvas.drawBitmap(coinImgs[0], 4, coinImgPosY, null);
canvas.drawText(collectedCoins + "", collectedCoinsTextX, collectedCoinsTextY, textPaint);
canvas.drawBitmap(powerUpDisplay[powerUpFuel], 10, height - powerUpDisplay[0].getHeight() - 10, null);
if(isPaused){
Paint pausePaint = new Paint();
pausePaint.setColor(Color.BLACK);
pausePaint.setAlpha(100);
pausePaint.setStyle(Style.FILL);
canvas.drawRect(new Rect(0,0,width,height), pausePaint);
canvas.drawText("Pausiert", (float)(width/2 - (90 * GameActivity.scaleFactorX)), (float)(height/2 - (200 * GameActivity.scaleFactorY)), textPaint);
}
else if(isDead) {
Paint deathPaint = new Paint();
deathPaint.setColor(Color.RED);
deathPaint.setAlpha(100);
deathPaint.setStyle(Style.FILL);
canvas.drawRect(new Rect(0,0,width,height), deathPaint);
canvas.drawText("Du bist gestorben", (float)(width/2 - (200 * GameActivity.scaleFactorX)), (float)(height/2 - (200 * GameActivity.scaleFactorY)), textPaint);
}
System.out.println("paintTime: " + (System.currentTimeMillis() - start));
}
Der Game-Loop:
Java:
while(running) {
startTime = System.currentTimeMillis();
while(!finished) {
System.out.println("waiting for game2");
try {
Thread.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
repaint();
System.out.println("gameTimeRepaint: " + (System.currentTimeMillis() - startTime));
synchronized(game2) {
game2.notify();
}
synchronized(entityManager) {
entityManager.notify();
}
if(isPaused || isDead) {
synchronized(this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
startTime = System.currentTimeMillis();
}
System.out.println("gameTime: " + (System.currentTimeMillis() - startTime));
sleepTime = TPS - (System.currentTimeMillis() - startTime);
if(sleepTime < 0)
sleepTime = 10;
try {
if(pressedSpace) {
pressedSpaceTime += sleepTime;
if(pressedSpaceTime > maxPressedSpaceTime) {
pressedSpaceTime = 0;
pressedSpace = false;
}
}
System.out.println("sleepTime: " + sleepTime);
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(strecke + characterWidth2 >= maxWidth)
running = false;
}
Ausschnitt aus LogCat:
09-19 12:14:41.171: I/System.out(2259): lockCanvasTime: 1
09-19 12:14:41.224: I/System.out(2259): unlockCanvasTime: 51
09-19 12:14:41.272: I/System.out(2259): lockCanvasTime: 2
09-19 12:14:41.324: I/System.out(2259): unlockCanvasTime: 51
09-19 12:14:41.351: I/System.out(2259): lockCanvasTime: 1
09-19 12:14:41.406: I/System.out(2259): unlockCanvasTime: 52
09-19 12:14:41.437: I/System.out(2259): lockCanvasTime: 1
09-19 12:14:41.498: I/System.out(2259): unlockCanvasTime: 60
09-19 12:14:41.532: I/System.out(2259): lockCanvasTime: 2
09-19 12:14:41.583: I/System.out(2259): unlockCanvasTime: 50
09-19 12:14:41.224: I/System.out(2259): unlockCanvasTime: 51
09-19 12:14:41.272: I/System.out(2259): lockCanvasTime: 2
09-19 12:14:41.324: I/System.out(2259): unlockCanvasTime: 51
09-19 12:14:41.351: I/System.out(2259): lockCanvasTime: 1
09-19 12:14:41.406: I/System.out(2259): unlockCanvasTime: 52
09-19 12:14:41.437: I/System.out(2259): lockCanvasTime: 1
09-19 12:14:41.498: I/System.out(2259): unlockCanvasTime: 60
09-19 12:14:41.532: I/System.out(2259): lockCanvasTime: 2
09-19 12:14:41.583: I/System.out(2259): unlockCanvasTime: 50
Weiss jemand, wie man dieses Problem beheben kann?
Mit freundlichen Grüssen, Faberix