【问题标题】:2D Game, Performance Improvements?2D 游戏,性能改进?
【发布时间】:2013-08-28 21:50:00
【问题描述】:

我正在开发的游戏在进步,添加的元素越来越多,但我当然也面临着新的问题,其中之一就是性能。

目前,我有 3 个线程,其中两个执行计算,另一个更新画布。这三个线程与 CyclicBarrier 同步,以便在开始绘制画布时完成所有计算。

我使用了几个不同大小的位图。在绘图方法中,位图正在被旋转(通过使用 drawBitmap-matrix 组合并将缩放/平移/旋转添加到矩阵中以进行“本机”(我猜)管理)并且当然是绘制的。我面临的问题是,每当屏幕上有太多“移动和旋转”元素时,它就会变得不稳定。

Matrix matrix = new Matrix();
matrix.setTranslate(view.getX(), view.getY());
matrix.preScale((1.0f * view.getWidth() / view.getCurrentBitmap().getWidth()), (1.0f * view.getHeight() / view.getCurrentBitmap().getHeight()));
matrix.postRotate(view.getRotation(), view.getX() + view.getWidth()/2f, view.getY()  + view.getHeight()/2f);
mCanvas.drawBitmap(view.getCurrentBitmap(), matrix, mBasicPaint);

例如,这是根据旋转和位置绘制玩家对象的方式:

private void drawPlayer(final Canvas mCanvas) {
    final Bitmap playerBitmap = mPlayer.getCurrentBitmap();
    mPlayer.nextFrame();
    if(playerBitmap != null) {
        if(mPlayer.getRotation() != 0) {
            Matrix matrix = new Matrix();
            matrix.setTranslate(-mPlayer.getCurrentBitmap().getWidth()/2f, -mPlayer.getCurrentBitmap().getHeight()/2f);
            matrix.postRotate(mPlayer.getRotation());
            matrix.postTranslate(mPlayer.getX() +  + mPlayer.getCurrentBitmap().getWidth()/2f, mPlayer.getY()  + mPlayer.getCurrentBitmap().getHeight()/2f);
            matrix.postScale((1.0f * mPlayer.getWidth() / mPlayer.getCurrentBitmap().getWidth()), (1.0f * mPlayer.getHeight() / mPlayer.getCurrentBitmap().getHeight()), mPlayer.getX(), mPlayer.getY());
            mCanvas.drawBitmap(mPlayer.getCurrentBitmap(), matrix, mBasicPaint);
        } else {
            Matrix matrix = new Matrix();
            matrix.setScale((1.0f * mPlayer.getWidth() / mPlayer.getCurrentBitmap().getWidth()), (1.0f * mPlayer.getHeight() / mPlayer.getCurrentBitmap().getHeight()));
            matrix.postTranslate(mPlayer.getX(), mPlayer.getY());
            mCanvas.drawBitmap(mPlayer.getCurrentBitmap(), matrix, mBasicPaint);
        }
    } else log("bitmap = null!");
}

(这是一种已弃用的版本,.getCurrentBitmap() 调用在当前版本中减少为一个。)

如何提高性能?我是否应该创建某种“正在加载...”屏幕,在其中预加载每个位图(以最大尺寸)和每个位图的预旋转版本? (这将导致,如果我采用 2-4 度的步长,每个位图有 90-180 个版本,这看起来有点……很多?)或者这是否会在存储旋转位图的情况下过多记忆?我对 OpenGL 等一无所知,这就是我使用 SurfaceView 而没有其他游戏引擎的原因,而且我确信它也必须像这样工作 - 不知何故。

【问题讨论】:

  • 如果你画到一个离屏画布然后翻转它们以渲染它怎么样。拥有两个画布(canvasii?)是否会为您的应用程序占用太多内存?
  • 但这不会让事情变得更糟吗?绘图做得很好,只是旋转很多,速度变慢了。将其绘制到另一个画布上,然后复制画布只需要更多的 CPU 时间,不是吗?

标签: android bitmap android-canvas


【解决方案1】:

每次调用drawPlayer 方法时,您都会创建一个Matrix(矩阵)和Bitmap(playerBitmap)对象。据我了解,您将在每一帧调用此方法。因此,每一帧,您都在创建 2 个大型对象,当您退出该方法时需要进行垃圾收集,这会降低您的帧速率。您只能创建 2 个对象 matrixplayerBitmap 作为类级变量,并在每次调用 drawPlayer 时刷新它们,从而减少 GC 调用次数。

【讨论】:

  • getCurrentBitmap 执行以下操作: public Bitmap gettCurrentBitmap() { return mResourceBitmaps[mFrame]; },在 mResourceBitmaps(对于每个 ViewObject 实例)中,每个帧的位图在第一次初始化对象时加载,所以这不应该是创建位图,而是更有可能返回引用?还是“最终位图位图;”总是创建一个全新的位图,即使它只是参考?
  • 从drawPlayer()的作用域开始,每次调用都会创建一个新的Bitmap Object(在这个作用域内),当这个对象超出作用域时(drawPlayer()退出),这个对象不再被引用并且被垃圾收集(对于 Matrix 对象相同)
猜你喜欢
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2011-04-02
  • 2016-05-23
  • 1970-01-01
  • 2011-11-05
相关资源
最近更新 更多