我想要開發可能在2d的第一個android遊戲。我打算從頭開始構建而不使用引擎。我已經設法創建以下線程:Android studio 2d遊戲fps問題
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);
}
}
}
我遇到的問題是,當向我的遊戲添加東西時,averageFPS一直在下降。只有背景,它在我的Nexus 5上可以工作在30,但是在增加角色和障礙後,它會下降到22-21。 無論如何,我可以做到這一點來優化嗎?
謝謝
UPDATE:我的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);
}
謝謝所有幫助到目前爲止
您是否在Android上編寫實時遊戲(https://youtu.be/U4Bk5rmIpic和https://youtu.be/7-62tRHLcHk) –