事件和位图中的预分配

发布于 2024-11-18 15:51:12 字数 3147 浏览 2 评论 0 原文

我正在为 Android 编写一个游戏,当 GC 运行时,每隔几秒就会出现明显的暂停。我已将分配减少到最低限度,唯一剩余的分配(根据分配跟踪器)是由 Bitmap.createBitmap(..)onTouchEventonTouchEvent 生成的。代码>onKeyEvent。 Bitmap.createBitmap(..) 每帧调用两次,并且无法删除。

现在回答我的问题:是否有另一种方法来读取事件和另一种方法来创建位图?或者一种预先分配操作所需内存的方法以及告诉他们使用该内存的方法?

InputHandler 类(包含监听器):

public class InputHandler {

private ISwarmInput mGame;

// Declare input types
public static final int USE_TOUCH = 0;
public static final int USE_MOTION = 1;
public static final int USE_KEY = 2;
public static final int USE_TOUCH_AND_KEY = 3;

private int mInputType;
public OrientationEventListener mOrientationListener;
public OnTouchListener mTouchListener;
public OnKeyListener mKeyListener;

public InputHandler(Context context, ISwarmInput game) {
    mGame = game;
    mTouchListener = createTouchListener();
    mKeyListener = createKeyListener();
}

public OrientationEventListener createTiltListener(Context context) {
    return new OrientationEventListener(context) {
        @Override
        public void onOrientationChanged(int orientation) {
            if (mInputType == USE_MOTION) {
                mGame.setAngle(orientation);
            }
        }
    };
}

public OnTouchListener createTouchListener() {
    return new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event){
            if (mInputType == USE_TOUCH || mInputType == USE_TOUCH_AND_KEY) {
                if (readPointIn(event.getX(), event.getY())) {
                    mGame.addNewPoint((int) event.getX(),
                            (int) event.getY());
                }
            }
            return true;
        }
    };
}

public OnKeyListener createKeyListener() {
    return new OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (mInputType == USE_KEY || mInputType == USE_TOUCH_AND_KEY) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_UP:
                    mGame.setAngle(-90);
                    break;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    mGame.setAngle(180);
                    break;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    mGame.setAngle(90);
                    break;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    mGame.setAngle(0);
                    break;
                }
            }
            return false;
        }
    };
}
}

位图创建部分

public void drawHead(Canvas canv) {
    mat.reset();
    nextFrame();

    setRotationAndFlip(mat);

    this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame * BIG_W[mUseBird], 0,
            BIG_W[mUseBird], BIG_H[mUseBird], mat, true);
    super.drawPlaceable(canv);

    mat.preScale((float)0.6, (float)0.6);
    this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame * BIG_W[mUseBird], 0,
            BIG_W[mUseBird], BIG_H[mUseBird], mat, true);
}

这个游戏类似于蛇,你是一只鸟,每吃掉一条虫子,你就会得到一只更小的鸟在休养。你。第二个位图是针对下面的较小的鸟的。

I'm writing a game for Android and I'm having noticeable pauses every few seconds when the GC runs. I've reduced the allocations to a minimum and the only remaining allocations (according to Allocation Tracker) are produced by Bitmap.createBitmap(..), an onTouchEvent and an onKeyEvent. Bitmap.createBitmap(..) is called twice per Frame, and cannot be removed.

Now to my question: Is there an alternative way to read the events and another way to create bitmaps? Or a way to pre-allocate the memory needed for the operations and a way of telling them to use that?

InputHandler class (contains listeners):

public class InputHandler {

private ISwarmInput mGame;

// Declare input types
public static final int USE_TOUCH = 0;
public static final int USE_MOTION = 1;
public static final int USE_KEY = 2;
public static final int USE_TOUCH_AND_KEY = 3;

private int mInputType;
public OrientationEventListener mOrientationListener;
public OnTouchListener mTouchListener;
public OnKeyListener mKeyListener;

public InputHandler(Context context, ISwarmInput game) {
    mGame = game;
    mTouchListener = createTouchListener();
    mKeyListener = createKeyListener();
}

public OrientationEventListener createTiltListener(Context context) {
    return new OrientationEventListener(context) {
        @Override
        public void onOrientationChanged(int orientation) {
            if (mInputType == USE_MOTION) {
                mGame.setAngle(orientation);
            }
        }
    };
}

public OnTouchListener createTouchListener() {
    return new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event){
            if (mInputType == USE_TOUCH || mInputType == USE_TOUCH_AND_KEY) {
                if (readPointIn(event.getX(), event.getY())) {
                    mGame.addNewPoint((int) event.getX(),
                            (int) event.getY());
                }
            }
            return true;
        }
    };
}

public OnKeyListener createKeyListener() {
    return new OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (mInputType == USE_KEY || mInputType == USE_TOUCH_AND_KEY) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_UP:
                    mGame.setAngle(-90);
                    break;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    mGame.setAngle(180);
                    break;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    mGame.setAngle(90);
                    break;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    mGame.setAngle(0);
                    break;
                }
            }
            return false;
        }
    };
}
}

Bitmap-creating part

public void drawHead(Canvas canv) {
    mat.reset();
    nextFrame();

    setRotationAndFlip(mat);

    this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame * BIG_W[mUseBird], 0,
            BIG_W[mUseBird], BIG_H[mUseBird], mat, true);
    super.drawPlaceable(canv);

    mat.preScale((float)0.6, (float)0.6);
    this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame * BIG_W[mUseBird], 0,
            BIG_W[mUseBird], BIG_H[mUseBird], mat, true);
}

The game is something similar to snake, you're a bird and for each worm you eat you get a smaller bird fallowing you. The second bitmap is for the following, smaller bird.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦断已成空 2024-11-25 15:51:12

对于可重用的输入事件,您可能需要查看此实现:http://code.google.com/p/libgdx/source/browse/trunk/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidInput.java< /a>

关于位图...也许您应该使一些精灵大小相同,以便可以重复使用您的位图。

For reusable input events you might want to take a look at this implementation: http://code.google.com/p/libgdx/source/browse/trunk/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidInput.java

Regarding bitmaps... maybe you should make some sprites the same size so you can reuse your bitmap.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文