ANDROID:如何消除滞后和Android中画布SurfaceView提高FPS? [英] ANDROID: How to eliminate lag and improve FPS in Android Canvas SurfaceView?

查看:172
本文介绍了ANDROID:如何消除滞后和Android中画布SurfaceView提高FPS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个初学者附近的Andr​​oid程序员,我已经取得了surfaceView一类简单的2D飞船游戏,你可以用手指控制spacehip,你有躲闪迎面而来的对象。

I am a near beginner android programmer, and i have made a simple 2D spaceship game in surfaceView class where you can control the spacehip with your finger and you have dodge oncoming objects.

然而,现在我使用了很多位图我的比赛似乎要落后一点。

However, now that i am using a lot of bitmaps my game seems to be lagging a bit.

所以我想知道有没有办法在使用它们后销毁/垃圾的照片,这样他们就不会创造这么多的滞后。 (因为我认为,照片所创建的滞后)

So i was wondering is there a way to destroy/garbage pictures after you use them, so they don't create so much lag. (because i think, the pictures are creating the lag)

请告诉我另一种简单的方式让我的游戏没有延迟更平稳,请告诉我有关帆布东西,因为我想留在Android的画布,而不是与发动机或OpenGL

Please tell me another simple way to make my game smoother without lags, and please tell me something related to canvas, since i want to stay with android canvas, not with an engine or OpenGL

非常感谢

下面是我的code如果你想看看....

below is my long code if you want to check it out....

package com.zunairgames.zunair;

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
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.util.DisplayMetrics;
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);
    setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);     /////////////////////////////////////////////////CHECK THIS MIGHT NOT WORK
    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;

    DisplayMetrics metrics = new DisplayMetrics ();
    // getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int screenWidth = metrics.widthPixels;
    int screenHeight = metrics.heightPixels;

    int scrWidth = getWindowManager ().getDefaultDisplay ().getWidth ();
    int scrHeight = getWindowManager ().getDefaultDisplay ().getHeight ();
    int scrRes = getWindowManager ().getDefaultDisplay ().getPixelFormat ();
    Random random = new Random ();

    boolean loadStuffPlayGame = false;
    boolean loadStuffMenu = false;


    boolean onGame = false;
    boolean onMenu = true;
    boolean onInstruction = false;



    int shipX = 0;
    int shipY = 0;
    int shipWidth = 0;
    int shipHeight = 0;


    int numStars = 4;
    int starX[] = new int [numStars];
    int starY[] = new int [numStars];
    int starWidth = 0;
    int starHeight = 0;
    int starSpeed[] = new int [numStars];


    int score = 0;
    int backgroundY = 0;

    Bitmap menuScreenBackground;
    Bitmap playGameButton;
    Bitmap instructionButton;
    //playGamePictures////
    Bitmap spaceship;
    Bitmap background;
    Bitmap starPic;
    ///end of playGame Pics//

    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 dpToPx (int dp)
    {
        DisplayMetrics displayMetrics = getContext ().getResources ().getDisplayMetrics ();
        int px = Math.round (dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    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 newWidth, int newHeight)
    {
        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 ();

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


            if (onMenu == true)
            {

                if (loadStuffMenu == false)
                {
                    menuScreenBackground = BitmapFactory.decodeResource (getResources (), R.drawable.menuscreen);
                    playGameButton = BitmapFactory.decodeResource (getResources (), R.drawable.menuplaygame);
                    instructionButton = BitmapFactory.decodeResource (getResources (), R.drawable.menuinstruction);

                    menuScreenBackground = getResizedBitmap (menuScreenBackground, canvas.getWidth (), canvas.getHeight ());
                    playGameButton = getResizedBitmap (playGameButton, round (canvas.getWidth () / 1.3), canvas.getHeight () / 8);
                    instructionButton = getResizedBitmap (instructionButton, round (canvas.getWidth () / 1.3), canvas.getHeight () / 8);
                    loadStuffMenu = true;
                }
                canvas.drawARGB (23, 3, 4, 4);

                canvas.drawBitmap (menuScreenBackground, 0, 0, null);

                paint.setTextSize (20);
                paint.setColor (Color.WHITE);
                canvas.drawText ("By: Zunair Syed", round (canvas.getWidth () / 1.5), round (canvas.getHeight () / 1.05), paint);





                if (x > dpToPx (15) && x < dpToPx (305) && y > dpToPx (190) && y < dpToPx (250))
                {
                    onMenu = false;
                    onGame = true;
                }

                else if (x > dpToPx (15) && x < dpToPx (305) && y > dpToPx (270) && y < dpToPx (335))
                {
                    paint.setColor (Color.BLUE);
                    canvas.drawCircle (20, 50, 100, paint);
                }

                else if (x > dpToPx (17) && x < dpToPx (305) && y > dpToPx (355) && y < dpToPx (420))
                {
                    paint.setColor (Color.GREEN);
                    canvas.drawCircle (20, 50, 100, paint);
                }


            }
            else if (onGame == true)
            {
                shipX = round (x) - (round (shipWidth / 2));
                shipY = round (y) - (round (shipHeight / 2));


                if (loadStuffPlayGame == false)
                {
                    shipX = round (canvas.getWidth () / 2);
                    shipY = round (canvas.getHeight () / 2);

                    shipWidth = canvas.getWidth () / 5;
                    shipHeight = canvas.getHeight () / 8;

                    starWidth = canvas.getWidth () / 10;
                    starHeight = canvas.getHeight () / 20;

                    for (int i = 0 ; i < numStars ; i++)
                    {
                        starY [i] = -random.nextInt ((canvas.getHeight () / 4));
                        starX [i] = random.nextInt (canvas.getWidth () - (starWidth));
                        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.star);

                    spaceship = getResizedBitmap (spaceship, dpToPx (shipWidth), dpToPx (shipHeight));
                    background = getResizedBitmap (background, (canvas.getWidth ()), (canvas.getHeight ()) * 2);
                    starPic = getResizedBitmap (starPic, dpToPx (starWidth), dpToPx (starHeight));

                    backgroundY = -(canvas.getHeight ());

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




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

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

                    if (shipX + shipWidth > starX [i] && shipX < starX [i] + starWidth && shipY + shipHeight > starY [i] && shipY < starY [i] + starHeight)
                    {
                        starY [i] = -random.nextInt ((canvas.getHeight () / 4));
                        starX [i] = random.nextInt (canvas.getWidth () - starWidth);
                        starSpeed [i] = 1 + random.nextInt (10);
                        score++;
                    }
                }

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

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

                }

                /*      canvas.drawText("SCORE : "+ score  + "DENSITY :"+ canvas.getDensity() +" screenWidth :"+scrWidth,0, 100, paint);
                        canvas.drawText("ScreenHight:" + scrHeight +" scrRes" + scrRes + "20 pixels ="+dpToPx(20) ,0, 150, paint);
                 */
                canvas.drawText ("SCORE :" + score, canvas.getWidth () / 2 - (canvas.getWidth () / 7), canvas.getHeight () / 80 + canvas.getHeight () / 30, paint);

                canvas.drawBitmap (spaceship, shipX, shipY, null); //1/3 of screen




            }
            else if (onInstruction == true)
            {

            }
            //72

            ourHolder.unlockCanvasAndPost (canvas);

        }
    }

}

}

推荐答案

我看不出有任何构造函数被调用的循环,所以我觉得你的问候GC都OK了。

I don't see any constructors being called in loops, so I think you are ok in regards to GC.

看起来你是在渲染CPU的所有对象。您可以通过使用OpenGL做渲染,而不是获得一些速度。

It looks like you are rendering all the objects on the cpu. You could gain some speed by using OpenGL to do the rendering instead.

有一些在 Android的指南<基础知识/ A>

There are some of the basics of using OpenGL within Android in the Android guide.

这篇关于ANDROID:如何消除滞后和Android中画布SurfaceView提高FPS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆