0

我是 android 编程的初学者,我目前正在画布上制作宇宙飞船游戏,您可以在其中用手指移动宇宙飞船以躲避迎面而来的小行星。

现在,我已经在 Canvas 上编写了整个代码,具体来说是在 Surface-View 上。

有四张图片,我的游戏似乎严重滞后......

那么是否有某种方法可以提高画布上的每秒帧数,或者我必须使用 OpenGL 或某些引擎来做到这一点。

以下是我的长代码,如果您发现任何提高 FPS(每秒帧数)的方法,请告诉我代码谢谢

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 始终相同,则创建一次位图在 onCreate 或“初始化”功能中,保持对该位图的引用并使用方法:

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

您可以重用已经存在的位图并将其绘制在屏幕上您想要的任何位置,这将大大提高性能,您不需要将 OpenGL 用于简单的渲染游戏,我已经使用它开发了几个安静的复杂渲染游戏只要您在对象创建和资源释放方面非常小心,技术和工作都会非常完美......

希望能帮助到你

问候!

于 2013-07-30T22:56:12.740 回答
0

不要getResizedBitmap在你的主循环中调用。您正在每帧创建和缩放新的位图。

于 2013-07-30T22:58:30.887 回答