0

私は Android プログラミングのほぼ初心者であり、現在キャンバス上で宇宙船ゲームを作成しています。このゲームでは、宇宙船を指で動かして迫り来る小惑星をかわすことができます。

今、コード全体を Canvas、具体的には surface-View に書きました。

4枚の写真があると、私のゲームはひどく遅れているようです...

私のキャンバスで1秒あたりのフレーム数を改善する方法はありますか、それともOpenGLまたはエンジンを使用する必要がありますか。

以下は私の長いコードです。FPS (1 秒あたりのフレーム数) を改善する方法があれば、コードを教えてください ありがとう

package com.zunairgames.zunair;

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 import android.view.View;
 import android.view.View.OnTouchListener;
 import android.view.Window;
import android.view.WindowManager;

public class GFXSurface extends Activity implements OnTouchListener {

MyBringBackSurface ourSurfaceView;
float x, y;
boolean testingFinger=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    ourSurfaceView = new MyBringBackSurface(this);
    ourSurfaceView.setOnTouchListener(this);
    x=0;
    y=0;

     requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,       WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(ourSurfaceView);//ourSurfaceView
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    ourSurfaceView.pause();
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    ourSurfaceView.resume();
}

public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub

    x= event.getX();
    y= event.getY();

     if (event.getAction()==MotionEvent.ACTION_DOWN) {
         testingFinger=true;
         return true;
     }
     if(event.getAction()==MotionEvent.ACTION_UP){
         testingFinger=false;
         return false;
     }



    return false;
}

public class MyBringBackSurface extends SurfaceView implements Runnable{
 //vertical
SurfaceHolder ourHolder;
Canvas canvas = (Canvas) ourHolder;
Thread ourThread = null;
boolean isRunning=false;
    int screenHeight;
    int screenWidth;

Random random = new Random ();
boolean loadStuff = false;

int posX=0;
int posY=0;
int posWidth=100;
int posHeight=100;


int numStars=4;
int starX[]=new int[numStars];
int starY[]=new int[numStars];
int starSpeed[]=new int[numStars];


int score=0;
int backgroundY=0;


Bitmap spaceship;
Bitmap background;
Bitmap starPic;


public MyBringBackSurface(Context context) {
    // TODO Auto-generated constructor stub
    super(context);
    ourHolder= getHolder();


}

public void pause(){
    isRunning=false;
    while(true){
        try {
            ourThread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        break;
    }
    ourThread=null;
}
public void resume(){
    isRunning=true;
    ourThread=new Thread(this);
    ourThread.start();
}



public int round(double d){
    double dAbs = Math.abs(d);
    int i = (int) dAbs;
    double result = dAbs - (double) i;
    if(result<0.5){
        return d<0 ? -i : i;            
    }else{
        return d<0 ? -(i+1) : i+1;          
    }
}

public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
    int width = bm.getWidth();

    int height = bm.getHeight();

    float scaleWidth = ((float) newWidth) / width;

    float scaleHeight = ((float) newHeight) / height;

    // create a matrix for the manipulation

    Matrix matrix = new Matrix();

    // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight);   
    // recreate the new Bitmap

    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);

    return resizedBitmap;

    }
public void run() {
    // TODO Auto-generated method stub


    while(isRunning){
        if(!ourHolder.getSurface().isValid())continue;

         canvas = ourHolder.lockCanvas();

         if(loadStuff==false){
                for (int i=0; i <numStars; i++){
                    starY[i]=-random.nextInt(200);
                    starX[i]=random.nextInt(canvas.getWidth()-50);
                    starSpeed[i]=1+random.nextInt(5);
                }
                 spaceship =     BitmapFactory.decodeResource(getResources(),R.drawable.spaceship);
                 background  =     BitmapFactory.decodeResource(getResources(),R.drawable.background);
                 starPic  =     BitmapFactory.decodeResource(getResources(),R.drawable.tile);

                     backgroundY=-(canvas.getHeight());

                     x=canvas.getWidth()/2;
                     y=canvas.getHeight()/2;
                loadStuff=true;
                }


        Paint paint = new Paint();
        paint.setColor(Color.GREEN);
        paint.setTextSize(40);

        for (int i=0; i <numStars; i++){
            starY[i]+=starSpeed[i];

            if(starY[i]>canvas.getHeight()){
                starY[i]=-random.nextInt(200);
                starX[i]=random.nextInt(canvas.getWidth()-50);
                starSpeed[i]=starSpeed[i]+random.nextInt(2);
            }

            if(x+posWidth>starX[i]&&x<starX[i]+50 && y+posHeight>starY[i]&&y<starY[i]+50){
                starY[i]=-random.nextInt(200);
                starX[i]=random.nextInt(canvas.getWidth()-50);
                starSpeed[i]=1+random.nextInt(10);
                score++;
            }
        }

        backgroundY++;
        if(backgroundY>-10){
            backgroundY=-canvas.getHeight();
    }
        canvas.drawRGB( 3, 120, 12);
        canvas.drawBitmap(getResizedBitmap(background,(canvas.getHeight())*2,(canvas.getWidth())), 0,backgroundY, null);

        for (int i=0; i <numStars; i++){
              canvas.drawBitmap(getResizedBitmap(starPic,50,50),starX[i] , starY[i],null);

        }
        canvas.drawText("SCORE : "+ score ,(canvas.getWidth()/2) -80, 100, paint);





        canvas.drawBitmap(getResizedBitmap(spaceship,100,100), x,y, null);


        ourHolder.unlockCanvasAndPost(canvas);

    //72
    }
4

2 に答える 2

2

あなたがやっている最大のパフォーマンスの間違いは次のとおりです。

 getResizedBitmap//This code is creating a new bitmap every time...

文字通り、レンダー サイクルごとに新しいビットマップを作成しており、この作成はすべて UI スレッドで実行されています。したがって、それを行う代わりに、可能な限りビットマップの作成を試みます。戦艦と starPic が常に同じである場合は、ビットマップを 1 回作成します。 onCreate 中または「初期化」機能で、そのビットマップの参照を保持し、メソッドを使用します。

canvas.drawBitmap(bitmap, sourceBitmapRect, trasnlateRect, paint);

既存のビットマップを再利用して、画面の任意の位置に描画できます。これにより、パフォーマンスが大幅に向上します。単純なレンダリング ゲームに OpenGL を使用する必要はありません。これを使用して、静かで複雑なレンダリング ゲームをいくつか開発しました。オブジェクトの作成とリソースの解放に細心の注意を払っている限り、テクニックと機能は非常に完璧です...

それが役に立てば幸い

よろしく!

于 2013-07-30T22:56:12.740 に答える
0

getResizedBitmapメインループで呼び出さないでください。フレームごとに新しいビットマップを作成してスケーリングしています。

于 2013-07-30T22:58:30.887 に答える