我正在Android studio上设计游戏,游戏速度越慢,我运行代码的时间越长。到目前为止,这场比赛只是蓝色的球飞过屏幕。那里还没有互动。
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
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 = 1600;
public static final int HEIGHT = 2560;
private FirstThread fT;
private Background logo;
private ArrayList<SugarFlake> sF;
private long sugarTime;
Random rm = new Random();
public int movement = -5;
public GamePanel(Context context) {
super(context);
getHolder().addCallback(this);
setFocusable(true);// definition: Set whether this view can receive the focus. Setting this to false will also ensure that this view is not focusable in touch mode.
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
logo = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.company_name));
sF = new ArrayList<SugarFlake>();
fT = new FirstThread(getHolder(), this);
numOfflakes = 15;
sugarTime = System.nanoTime();
fT.setRunning(true);
fT.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
int counter = 0;
while (retry && counter < 1000) {
counter++;
try {
fT.setRunning(false);
fT.join();
retry = false;
fT = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void update() {
long currentTime = System.nanoTime();
int sugarPosition;
int t = 1;
while (t < 200) {
if (sF.size() == 0) {
sF.add(new SugarFlake(WIDTH / 2 + 8, -25));
}
if (currentTime > sugarTime) {
sugarPosition = (int) (rm.nextDouble() * 10 + (WIDTH / 4 * rm.nextDouble() * 10));
if (sugarPosition < WIDTH && sugarPosition > 25)
sF.add(new SugarFlake(sugarPosition, 0));
}
sugarTime = System.nanoTime();
for (int i = 0; i < 1; i++) {
sF.get(i).update();
if (sF.get(i).getY() > HEIGHT -20) {
sF.remove(i);
}
}
t++;
}
}
public void draw(Canvas canvas) {
super.draw(canvas);
final float scaleFactorX = getWidth() / (WIDTH * 1.f);
final float scaleFactorY = getHeight() / (HEIGHT * 1.f);
if (canvas != null) {
final int savedState = canvas.save();// canvas.save definition: Saves the current matrix and clip onto a private stack.
canvas.scale(scaleFactorX, scaleFactorY);
logo.draw(canvas);
Paint p = new Paint();
p.setColor(Color.BLUE);
p.setStyle(Paint.Style.FILL);
canvas.drawRect((WIDTH / 2 - 5), HEIGHT, (WIDTH / 2 + 5), 0, p);
for (SugarFlake sugarFlake : sF) {
sugarFlake.draw(canvas);
// System.out.println("this is che draw method, blah");
}
canvas.restoreToCount(savedState); // definition: Efficient way to pop any calls to save() that happened after the save count reached saveCount. It is an error for saveCount to be less than 1.
}
}
}
这是主要代码。
以下是运行应用程序约一分钟后在logcat中弹出的内容。 使用System..out输出的数字是在另一个类中编程的每秒帧数,我将在此读数下面添加。 arraylist sugarflake是
public void oneFlake(Canvas canvas){
Paint p = new Paint();
p.setColor(Color.BLUE);
p.setStyle(Paint.Style.FILL);
canvas.drawCircle(x - r, y - r, r, p);
}
当应用程序运行时,这会在屏幕上向下移动。
08-17 10:44:53.073 15757-15765/com.example.vitaliy_2.thegame W/art: Suspending all threads took: 33.752ms
08-17 10:44:53.083 15757-15772/com.example.vitaliy_2.thegame I/art: Background sticky concurrent mark sweep GC freed 2767(92KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 64MB/64MB, paused 1.708ms total 255.645ms
08-17 10:44:53.253 15757-15772/com.example.vitaliy_2.thegame I/art: Background partial concurrent mark sweep GC freed 231598(15MB) AllocSpace objects, 0(0B) LOS objects, 24% free, 48MB/64MB, paused 1.983ms total 139.678ms
08-17 10:44:53.583 15757-15927/com.example.vitaliy_2.thegame I/System.out: 16.0
08-17 10:44:55.615 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:44:57.637 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:44:59.409 15757-15927/com.example.vitaliy_2.thegame I/System.out: 17.0
08-17 10:45:01.301 15757-15927/com.example.vitaliy_2.thegame I/System.out: 15.0
08-17 10:45:03.123 15757-15927/com.example.vitaliy_2.thegame I/System.out: 16.0
08-17 10:45:05.005 15757-15927/com.example.vitaliy_2.thegame I/System.out: 16.0
08-17 10:45:07.057 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:45:09.129 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:45:11.441 15757-15927/com.example.vitaliy_2.thegame I/System.out: 12.0
08-17 10:45:12.091 15757-15765/com.example.vitaliy_2.thegame W/art: Suspending all threads took: 6.225ms
08-17 10:45:12.091 15757-15772/com.example.vitaliy_2.thegame W/art: Suspending all threads took: 6.195ms
08-17 10:45:12.182 15757-15772/com.example.vitaliy_2.thegame I/art: Background sticky concurrent mark sweep GC freed 2156(72KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 64MB/64MB, paused 8.361ms total 275.787ms
08-17 10:45:12.292 15757-15772/com.example.vitaliy_2.thegame I/art: Background partial concurrent mark sweep GC freed 232889(15MB) AllocSpace objects, 0(0B) LOS objects, 24% free, 48MB/64MB, paused 1.251ms total 110.168ms
08-17 10:45:13.673 15757-15927/com.example.vitaliy_2.thegame I/System.out: 13.0
08-17 10:45:15.785 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:45:18.268 15757-15927/com.example.vitaliy_2.thegame I/System.out: 12.0
08-17 10:45:20.540 15757-15927/com.example.vitaliy_2.thegame I/System.out: 13.0
08-17 10:45:22.902 15757-15927/com.example.vitaliy_2.thegame I/System.out: 12.0
08-17 10:45:25.064 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:45:27.206 15757-15927/com.example.vitaliy_2.thegame I/System.out: 14.0
08-17 10:45:27.987 15757-15757/com.example.vitaliy_2.thegame I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@ecdb605 time:47113609
这是帧速率模拟器
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class FirstThread extends Thread{
private final SurfaceHolder surfaceHolder;
private GamePanel gP;
private boolean running;
public static Canvas canvas;
public FirstThread(SurfaceHolder surfaceHolder, GamePanel gP){
super();
this.surfaceHolder = surfaceHolder;
this.gP = gP;
}
@Override
public void run() {
long startTime;
long timeMillis;
long waitTime;
long totalTime = 0;
int frameCount = 0;
final int FPS = 30;
long targetTime = 1000/FPS;
while(running){
startTime = System.nanoTime();
canvas = null;
try{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
this.gP.update();
this.gP.draw(canvas);
}
}catch(Exception ignored){}finally{
if(canvas != null){
try{surfaceHolder.unlockCanvasAndPost(canvas);}catch(Exception e){e.printStackTrace();}
}
}
timeMillis = (System.nanoTime() - startTime) / 100000;
waitTime = targetTime - timeMillis;
try {sleep(waitTime);} catch (Exception ignored){}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == FPS){
double averageFPS = 1000 / ((totalTime / frameCount) /1000000);
frameCount = 0;
totalTime = 0;
System.out.println(averageFPS);
}
}
}
public void setRunning(boolean b){running = b;}
}
如果需要更多信息,请与我们联系。 谢谢。
答案 0 :(得分:2)
看起来你正在重复创建SugarFlake的新实例,并在每次调用'update'时从ArrayList添加和删除它们。
我建议在开始时分配所有这些对象,并根据需要回收它们。依靠垃圾收集器来摆脱它们可能会导致性能问题。
有关详情,请查看“object pooling”。
答案 1 :(得分:1)
也许就是那些
sF.add(new SugarFlake(sugarPosition, 0));
和
sF.add(new SugarFlake(WIDTH / 2 + 8, -25));
你在代码中导致缓慢..
您正在分配内存并且从不释放内存,这些是内存泄漏
你应该将移动 SugarFlake到新的位置而不是每次创建新的位置。重复使用它们并设置SugarFlakes数量的上限