2016-08-17 9 views
0

私はアンドロイドスタジオでゲームをデザインしています。これまでのゲームは、画面上を飛行している青いボールだけです。そこにはまだ対話はありません。Androidスタジオ - 開発中のゲームが遅くなると実行速度が遅くなります

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. 

    } 

} 

} 

これがメインコードです。

以下は、アプリケーションを約1分間実行した後、logcatにポップアップ表示されるものです。 System..outでプリントアウトする番号は、この読み取り値の下に追加している別のクラスでプログラミングされた1秒あたりのフレーム数です。 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: [email protected] 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;} 
} 

任意のより多くの情報が必要な場合、私に教えてください。 ありがとうございます。

答えて

1

SugarFlakeの新しいインスタンスを繰り返し作成していて、 'update'を呼び出すたびにArrayListに追加して削除するようです。

これらのオブジェクトはすべて最初から割り当てて、必要に応じてリサイクルすることをおすすめします。ガベージコレクタに依存してそれらを取り除くことは、おそらくパフォーマンスの問題を引き起こしています。

詳細については、object poolingをご覧ください。

+1

ありがとうございました。私はそれを調べます。 –

1

多分それはあなたがメモリを割り当て、決してそれを解放しているあなたは遅さの原因となるコードを持っているすべてのものを

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

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

..

だ、それらはメモリですリーク

あなたはちょうどに移動する必要があります SugarFlakeを毎回新しい場所に作成するのではなく、新しい場所に追加する。それらを再利用し、SugarFlakesの数に上限を設定してください

関連する問題