簡體   English   中英

Android Studio 2D游戲fps問題

[英]Android studio 2d game fps issue

我正在嘗試開發可能在2D中首次使用的Android游戲。 我打算在不使用引擎的情況下從頭開始構建它。 我設法創建以下線程:

import android.graphics.Canvas;
import android.view.SurfaceHolder;


public class MainThread extends Thread {
private int FPS = 30;
private double averageFPS;
private GamePanel gamePanel;
private SurfaceHolder surfaceHolder;
private boolean running;
public static Canvas canvas;

public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) {
    super();
    this.surfaceHolder = surfaceHolder;
    this.gamePanel = gamePanel;
}


@Override
public void run() {
    long startTime;
    long timeMillis;
    long waitTime;
    long totalTime = 0;
    int frameCount = 0;
    // how many milliseconds it take to run through the loop
    long targetTime = 1000 / FPS;

    while (running) {
        startTime = System.nanoTime();
        canvas = null;

        // try to lock the canvas for pixel editing
        try {
            canvas = this.surfaceHolder.lockCanvas();
            synchronized (surfaceHolder) {
                // the main game loop
                this.gamePanel.update();
                this.gamePanel.draw(canvas);

            }
        } catch (Exception e) {
        } finally {
            if (canvas != null) {
                try {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        timeMillis = (System.nanoTime() - startTime) / 1000000;
        waitTime = targetTime - timeMillis;

        try {
            System.out.println(waitTime);
            this.sleep(waitTime);
        } catch (Exception e) {
        }

        totalTime += System.nanoTime() - startTime;
        frameCount++;

        if (frameCount == FPS) {
            averageFPS = 1000 / ((totalTime / frameCount) / 1000000);
            frameCount = 0;
            totalTime = 0;
            System.out.println(averageFPS);
        }
    }
}

我的問題是,在向游戲中添加內容時,平均FPS不斷下降。 在只有背景的情況下,它在Nexus 5上的工作頻率為30,但是在添加了角色和障礙物后,它降至22-21。 無論如何,我可以做些優化嗎?

謝謝

更新:我的GamePanel看起來像這樣:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.Random;


public class GamePanel extends SurfaceView implements SurfaceHolder.Callback     {

public static final int WIDTH = 1920;
public static final int HEIGHT = 1080;
public static float MOVESPEED = -12;

private Random rand = new Random();

private MainThread thread;
private Background bg;
private Treadmill tm;
private Player player;

private ArrayList<Box> boxes;

private int minDistance = 600;
private int score;

public GamePanel(Context context) {
    super(context);

    // add callback service to the holder to intercept events
    getHolder().addCallback(this);


    // make gamePanel focusable so it can handle events
    setFocusable(true);
}


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    while (retry) {
        try {
            thread.setRunning(false);
            thread.join();
            retry = false;
            thread = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // instantiate objects
    thread = new MainThread(getHolder(), this);
    bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.background));
    tm = new Treadmill(BitmapFactory.decodeResource(getResources(), R.drawable.ground));
    player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.character));

    boxes = new ArrayList<Box>();


    //start game loop
    thread.setRunning(true);
    thread.start();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {

        if (player.jump == false) {
            player.setVelocity(-14f);
            player.setJump(true);
        }
        return true;
    }

    return super.onTouchEvent(event);

}

public void update() {

    bg.update();
    tm.update();
    player.update();

    if (boxes.size() == 0) {
        boxes.add(new Box(BitmapFactory.decodeResource(getResources(), R.drawable.box),
                WIDTH));
    } else if (boxes.get(boxes.size() - 1).getX() < WIDTH) {
        if (WIDTH - boxes.get(boxes.size() - 1).getX() < minDistance) {
            boxes.add(new Box(BitmapFactory.decodeResource(getResources(), R.drawable.box),
                    rand.nextInt(400 - 50) + WIDTH + minDistance));

        }
    }

    for (int i = 0; i < boxes.size(); i++) {
        if (boxes.get(i).getX() <= player.getX() && boxes.get(i).getX() >= player.getX() - 12) {
            score++;
            MOVESPEED -= 0.2;
            System.out.println(MOVESPEED);
        }
        if (collision(boxes.get(i), player)) {
            boxes.remove(i);
            break;
        }

        if (boxes.get(i).getX() < -100) {
            boxes.remove(i);
            break;
        }

    }
    for (int i = 0; i < boxes.size(); i++) {
        boxes.get(i).update();
    }

}

@Override
public void draw(Canvas canvas) {
    final float scaleFactorX = getWidth() / (WIDTH * 1.f);
    final float scaleFactorY = getHeight() / (HEIGHT * 1.f);

    if (canvas != null) {
        final int saveState = canvas.save();

        canvas.scale(scaleFactorX, scaleFactorY);
        // draw the background
        bg.draw(canvas);

        tm.draw(canvas);

        player.draw(canvas);

        for (Box bx : boxes) {
            bx.draw(canvas);
        }

        drawText(canvas);
        canvas.restoreToCount(saveState);
    }
}

public boolean collision(GameObject a, GameObject b) {
    if (Rect.intersects(a.getRectangle(), b.getRectangle())) {
        return true;
    }
    return false;
}

public void drawText(Canvas canvas) {
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    paint.setTextSize(50);
    paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
    canvas.drawText("Score: " + (score), 15, HEIGHT - 20, paint);
}

謝謝你到目前為止的所有幫助

這個問題似乎不在Main Thread Activity中,您按照教程進行操作就很好了(除了該行-System.out.println(waitTime);-但我不認為這就是問題的原因。)問題出在大多數可能在GamePanel中。 ;)

永遠不要在游戲循環中使用Thread.sleep() 不保證可以在指定的時間內睡眠。

無論如何,我認為這是使用Canvas時的預期行為。 如果您是我,我會考慮將OpenGL ES用於圖形渲染之類的事情。 無疑,這會使它變得更加復雜(即使Android已經為您完成了許多工作)。 但是好處非常明顯-您可以獲得實際的實時圖形性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM