我正在SurfaceView画布上绘制一组图像。在获取surfaceHolder之后,游戏循环线程会调用doDraw。问题是当画布上绘制的图像数量很大时,每秒帧数(FPS)确实很低。这是因为drawBitmap较慢。

测试设置

clusters arraylist有400个小图像(cluster.Picture)。时间差是运行drawBitmap循环的测量参数。为了进行比较,我用drawRect替换了drawBitmap,并注释掉了drawBitmap,使循环为空。
用于测试的设备
https://www.optus.com.au/shop/prepaidmobile/lg/leon

测试结果(毫秒)


drawBitmap 400循环-平均:25.5,最小值:14,最大值:37
drawRect 400循环-平均:8.6,最小:5,最大:21
没有400循环-平均值:1.3,最小值:0,最大值:10


上面的时间仅测量逻辑的一部分。整个游戏循环将花费近40毫秒。这意味着FPS确实很低。即使是100次循环,绘制位图也需要18毫秒。

我尝试设置getHolder()。setFormat(PixelFormat.RGBA_8888),setFixedSize(screenSize.x,screenSize.y)和zorder以及将位图配置设置为RGBA_8888。另外,我尝试使用游戏线程的setPriority设置高优先级。

我不确定还能做什么。如何提高游戏循环和FPS的性能。

    public List<PCluster> clusters = new ArrayList<PCluster>();

    public void doDraw(Canvas canvas) {

    try {
        if (canvas == null) {
            return;
        }
        super.draw(canvas);

        canvas.drawColor(backColor);
        if (waitTillLoad) {
            return;
        }

    } catch (Exception ex) {
    }
    final int savedState = canvas.save();
    try {

        minX = (int) (((viewWidth / mScaleFactor) - Gen.screenSizeWidth) / 2) * Utils.VIEW_SIZE;
        minY = (int) (((viewHeight / mScaleFactor) - Gen.screenSizeHeight) / 2) * Utils.VIEW_SIZE;

        if (mPosX > maxX) {
            mPosX = maxX;
        }
        if (mPosX < minX) {
            mPosX = minX;
        }
        if (mPosY > maxY) {
            mPosY = maxY;
        }
        if (mPosY < minY) {
            mPosY = minY;
        }


        canvas.scale(mScaleFactor, mScaleFactor);
        canvas.translate(mPosX, mPosY);

        long startTime = System.currentTimeMillis();
        if (!showBackground) {

            for (PCluster cluster : clusters) {
                if (cluster.isVisible) {
                    canvas.drawBitmap(cluster.Picture, cluster.BoardLocation.left,
                            cluster.BoardLocation.top, null);
                }
            }
            Log.d("myApp", "   " + (System.currentTimeMillis() - startTime));
        }

    } catch (Exception ex) {
    } finally {
        canvas.restoreToCount(savedState);
    }
}

最佳答案

我可以使用PorterDuff SRC_OVER绘画对象来提高性能。这可能是因为透明图像相互叠加绘制时计算量较少。另外,请确保在涂料中添加抖动和抗锯齿功能。

canvasPaint = new Paint();
canvasPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER ));

canvas.drawBitmap(cluster.Picture, cluster.BoardLocation.left,
                            cluster.BoardLocation.top, canvasPaint );

关于android - 在SurfaceView游戏线程上的drawBitmap性能低下(android),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42950810/

10-09 00:08