我是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
}
答案 0 :(得分:2)
您正在做的最大的性能错误是:
getResizedBitmap//This code is creating a new bitmap every time...
你实际上是在每个渲染周期中创建一个新的位图,所有这些创建都在UI线程中运行,因此,如果战舰和starPic始终相同,则不要尝试尽可能多地创建位图,创建在onCreate或“初始化”功能期间,位图一次,保留该位图的引用并使用方法:
canvas.drawBitmap(bitmap, sourceBitmapRect, trasnlateRect, paint);
您可以重复使用现有的位图,并在屏幕上以任何您想要的位置绘制它, 这将大大提高性能,你不需要使用OpenGL进行简单的渲染游戏,我已经使用这种技术开发了几个安静复杂的渲染游戏,并且只要你非常小心对象创建和资源释放,它就会非常完美。 ..
希望有所帮助
问候!
答案 1 :(得分:0)
请勿在主循环中调用getResizedBitmap
。您正在每帧创建和缩放新的位图。