表面视图中的Android游戏滞后峰值

时间:2013-05-20 11:18:33

标签: android canvas surfaceview frame-rate

人。我正在玩我的第一款Android游戏,但偶然发现了一个问题。帧率似乎有随机延迟峰值。如果我评论背景,帧速率会变得更加平滑。我环顾四周,无法找到解决问题的方法。我觉得它与每次绘制时分配特定时间有关,但我不知道如何正确实现这样的功能。有什么建议?顺便说一下,试过硬件交流,反等等。

这是启动surfaceview的类:

package com.example.glassrunner;

Imports Here

public class Game extends Activity 
{



MySurfaceView mySurfaceView;
public SoundPool spool;
private int soundID;
int length=0;


/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    this.setVolumeControlStream(AudioManager.STREAM_MUSIC);






    mySurfaceView = new MySurfaceView(this);

    setContentView(mySurfaceView);


}



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

    mySurfaceView.onResumeMySurfaceView();

}

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

@Override
protected void onDestroy()
{
    super.onDestroy();
    mySurfaceView = null;
}



}

这是surfaceview类:

package com.example.glassrunner;

Imports here

 public class MySurfaceView extends SurfaceView implements Runnable
 {
public static boolean gameOver = false;

SurfaceHolder surfaceHolder;

Thread thread = null;



public Integer score=0;


public SoundPool spool;
private int soundID;
int length=0;
public static MediaPlayer mp;

volatile boolean running = false;
int Yposition = 450;
int Xposition = 50;

Paint textPaint;
long mLastTime;    
Bitmap background;
Bitmap background2;
Bitmap lines;
Bitmap runSprite;
Bitmap box;

Paint bitmapPaint ;
Paint textPaint2;
Bitmap scaledBackground ;
Bitmap scaledBackground2 ;
Bitmap scaledLines ;
Bitmap scaledBox;
Canvas canvas;
Paint paint;
int SpX=0;
int SpY=0;
Bitmap[][] sprite;



/** Variables for the counter */
int frameSamplesCollected = 0;
int frameSampleTime = 0;
int fps = 0;
int speed = 5;

Toast GameOverToast; 

Context context;
MediaPlayer mMediaPlayer;

public MySurfaceView(Context context) 
{
    super(context);
    this.context = context;
    // TODO Auto-generated constructor stub
    surfaceHolder = getHolder();
    surfaceHolder.setFormat(PixelFormat.RGB_565); 

    CharSequence text = "Game Over!";
    int duration = Toast.LENGTH_SHORT;
    GameOverToast = Toast.makeText(context, text, duration);
    spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
    soundID = spool.load(context, R.raw.jump, 1);
    mp = MediaPlayer.create(context, R.raw.saturdaymorningfunk); 




    initialization();
}

public void initialization()
{


    mp.setLooping(true);
    mp.start();



    Options options = new Options();    
    options.inSampleSize = 1/4;
    options.inPreferredConfig = Bitmap.Config.RGB_565; 


    background=BitmapFactory.decodeResource(getResources(),R.drawable.background,options);
    lines=BitmapFactory.decodeResource(getResources(),R.drawable.lines);// getting the png from drawable folder
    background2=BitmapFactory.decodeResource(getResources(),R.drawable.background2,options);
    runSprite=BitmapFactory.decodeResource(getResources(),R.drawable.runsprite);
    box=BitmapFactory.decodeResource(getResources(),R.drawable.box);
    bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // tool for painting on the canvas
    bitmapPaint.setAntiAlias(true);
    bitmapPaint.setFilterBitmap(true);



    textPaint = new Paint();
    textPaint.setColor(Color.RED);
    textPaint.setTextSize(32);
    textPaint2 = new Paint();
    textPaint2.setColor(Color.BLUE);
    textPaint2.setTextSize(50);



    scaledBackground = Bitmap.createScaledBitmap(background, 2560, 500, true);
    scaledBackground2 = Bitmap.createScaledBitmap(background2, 2560, 400, true);
    scaledLines = Bitmap.createScaledBitmap(lines, 2560, 30, true);
    runSprite = Bitmap.createScaledBitmap(runSprite, 1400, 1000, true);
    scaledBox = Bitmap.createScaledBitmap(box, 100, 100, true);


    sprite = new Bitmap[4][7]; 





    for(int row=0;row<=3;row++)
    {

        for(int col=0;col<=6;col++)
        {
            sprite[row][col] = Bitmap.createBitmap(runSprite, SpX, SpY, 200, 250);
            SpX+=200;
        }
        SpX=0;
        SpY+=250;





    }
}

public void onResumeMySurfaceView()
{
    mp.seekTo(length);
    mp.start();
    running = true;
    thread = new Thread(this);
    thread.start();





}

public void onPauseMySurfaceView()
{
    mp.pause();
    length=mp.getCurrentPosition();
    boolean retry = true;
    running = false;
    while(retry){
        try {
            thread.join();

            retry = false;
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


}

public void onDestroyMySurfaceView()
{

    mp.stop();
    running = false;
    thread = null;
    thread.stop();



}


private void fps()  
{
    long now = System.currentTimeMillis();

    if (mLastTime != 0) 
    {

        //Time difference between now and last time we were here
        int time = (int) (now - mLastTime);
        frameSampleTime += time;
        frameSamplesCollected++;

        //After 10 frames
        if (frameSamplesCollected == 10) 
        {

            //Update the fps variable
            fps = (int) (10000 / frameSampleTime);

            //Reset the sampletime + frames collected
            frameSampleTime = 0;
            frameSamplesCollected = 0;
        }  

    }

    mLastTime = now;
}
public boolean pressDown = false;
public long pressTime;
public boolean onTouchEvent(MotionEvent event)
{

    if (event != null)
    {

        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {   if(Yposition == orgPos)
        {
            spool.play(soundID, 15, 15, 1, 0, 1f);
            pressDown = true;
            pressTime = System.currentTimeMillis();
        }


        }else if (event.getAction() == MotionEvent.ACTION_UP)
        {
            pressDown = false;
        }
    }

    return true;
}

int x=0;
int y=100;
int x2=0;
int y2=20;
int row=0;
int col=0;
int limit = 100;
int orgPos = 450;
int Xbox = 1280;
int Ybox = 580;
Random r = new Random();
int RBox;

public static String Fscore;

boolean onTop = false;
long now;

long start;
long stop;
long time ;

int spritePosition = 0 ;
int spriteSize;

@Override
public void run() 
{



    while(running)
    {
        canvas = null;


        if(surfaceHolder.getSurface().isValid())
        {   
            canvas = surfaceHolder.lockCanvas();


            fps(); // fps

            // Update screen parameters
            update();   
            draw();
            surfaceHolder.unlockCanvasAndPost(canvas);

        }
    }
}

public void update()
{

    if(score<500)
    {
        speed = 7;
    }
    else if(score%500 == 0)
    {
        speed = 7 + (score / 500);
    }
    if(col==6)
    {
        row++;
        col=0;
    }
    if(row==4)
    {
        row=0;

    }

    score++;
    Fscore =  score.toString();

    if(x>-1280)
    {
        x-=speed;
    }else if(x<=-1280)
    {
        x=0;
    }

    if(x2>-1280)
    {
        x2-=5;
    }else if(x2<=-1280)
    {
        x2=-0;
    }

    RBox = r.nextInt(999)+1280;

    if(Xbox > -100)
    {
        Xbox-=speed;
    }else if(Xbox<=-100)
    {
        Xbox=RBox;
    }
    if( (Xposition + 200 == Xbox +40 )&&(Yposition + 250 > Ybox+20)||( Xposition+200<=Xbox+70)&&( Xposition+200>=Xbox+20)&&(Yposition + 250 > Ybox+30) ) // collision
    {
        GameOverToast.show();

        running = false;



        spool.release();
        mp.release();
        Looper.prepare();
        Intent database = new Intent(context, MainHighscore.class);
        database.putExtra("score", Fscore);
        context.startActivity(database);


        onDestroyMySurfaceView();



    }






    now = System.currentTimeMillis();
    if(( now - pressTime) <= 600)
    {
        if(Yposition > limit)
        {
            Yposition -= 10;
        }
    }
    onTop = false;

    if((now - pressTime) >= 600 && (now - pressTime) <= 1200)
    {
        if(!(Yposition == orgPos))
        {


            if(Yposition+250 >= Ybox && Xposition+200>=Xbox+70 && Xposition <= Xbox+40)
            {
                onTop=true;
                Yposition = 340;
            }else
            {
                Yposition += 10;
            }
        }


    }
    if((now - pressTime) >= 1200)
    {

        if(Yposition < 450) Yposition +=10;
        else Yposition = 450;

    }







}
public void draw()
{

    canvas.drawColor(Color.WHITE);
    //canvas.drawBitmap(scaledBackground, x2,y2, bitmapPaint);
    canvas.drawBitmap(scaledBackground2, x,y, bitmapPaint);
    canvas.drawBitmap(scaledLines, x,650, bitmapPaint);
    canvas.drawText(Fscore, 1050, 50, textPaint2);
    canvas.drawText(fps + " fps", getWidth() / 2, getHeight() / 2, textPaint);
    canvas.drawBitmap(sprite[row][col],Xposition,Yposition,bitmapPaint );
    canvas.drawBitmap(scaledBox,Xbox,Ybox,bitmapPaint);

    col++;
}


 }

1 个答案:

答案 0 :(得分:0)

我认为你的问题可能实际上是一个动人的部分。你只是绘制了太多的东西,而SurfaceView并不适用于此。