Android studio - 游戏(开发中)减慢了它运行的时间

时间:2016-08-17 15:05:06

标签: java performance android-studio

我正在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;}
}

如果需要更多信息,请与我们联系。 谢谢。

2 个答案:

答案 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数量的上限