1

我是一个近乎初学者的 android 程序员,我在 surfaceView 类中制作了一个简单的 2D 飞船游戏,您可以用手指控制飞船,并且可以躲避迎面而来的物体。

但是,现在我使用了很多位图,我的游戏似乎有点滞后。

所以我想知道有没有办法在你使用它们后销毁/垃圾图片,所以它们不会造成太多的延迟。(因为我认为,图片造成了滞后)

请告诉我另一种让我的游戏更流畅而没有延迟的简单方法,并请告诉我一些与画布相关的事情,因为我想继续使用 android 画布,而不是使用引擎或 OpenGL

多谢

下面是我的长代码,如果你想检查一下......

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);

        }
    }

}

}

4

1 回答 1

1

我没有看到在循环中调用任何构造函数,所以我认为你对 GC 没问题。

看起来您正在渲染 cpu 上的所有对象。您可以通过使用 OpenGL 进行渲染来获得一些速度。

Android 指南中有一些在 Android 中使用 OpenGL 的基础知识。

于 2013-08-05T20:26:37.713 回答