简体   繁体   English

Android Studio-游戏(开发中)运行时间越长,速度越慢

[英]Android studio - game (in development) slows down the longer it runs

I am designing a game on android studio and the game slows to a crawl the longer I run the code. 我正在android studio上设计游戏,而我运行代码的时间越长,该游戏的爬行速度就越慢。 The game so far is just blue balls flying across the screen. 到目前为止,游戏只是蓝球在屏幕上飞舞。 There is no interaction there yet. 尚无互动。

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.

    }

}

}

this is the main code. 这是主要代码。

Below is what pops up in the logcat after running the app for about a minute. 下面是运行该应用程序大约一分钟后在logcat中弹出的内容。 The number that prints out with System..out is the frames per second programmed in another class which I am adding below this readout. 用System..out打印出的数字是每秒在另一类中编程的帧,我在此读数下方添加了该类。 THe arraylist sugarflake is 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);
    }

This moves down the screen as the app runs. 当应用运行时,它会在屏幕上向下移动。

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

This the frame rate simulator 这个帧率模拟器

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;}
}

Let me know if any more information is needed. 让我知道是否需要更多信息。 Thank you. 谢谢。

Looks like you're creating new instances of SugarFlake repeatedly, and adding and removing them from the ArrayList every call to 'update'. 似乎您正在重复创建SugarFlake的新实例,并在每次调用“ update”时将它们从ArrayList中添加和删除。

I'd recommend allocating all of those objects at the start, and just recycling them as needed. 我建议一开始就分配所有这些对象,然后根据需要回收它们。 Relying on the garbage collector to get rid of them is probably causing the performance problem. 依靠垃圾收集器摆脱它们可能会导致性能问题。

Check out ' object pooling ' for more on this. 有关更多信息,请查看“ 对象池 ”。

maybe it's all those 也许就是这些

sF.add(new SugarFlake(sugarPosition, 0));

and

sF.add(new SugarFlake(WIDTH / 2 + 8, -25));

you have in the code that cause the slowness.. 您在代码中会导致运行缓慢。

You are allocating memory and never releasing it, those are memory leaks 您正在分配内存而从不释放它,那是内存泄漏

You should just move the SugarFlake to new positions instead of create new one everytime. 您应该只是 SugarFlake移到新位置,而不是每次都创建一个新位置。 Reuse them and set an upper limit on the number of SugarFlakes 重用它们并设置SugarFlakes数量的上限

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM