我正在SurfaceView画布上绘制一组图像。获取surfaceHolder后,doDraw由游戏循环线程调用。当画布上绘制的图像数量很大时,问题是每秒帧数(FPS)非常低。这是因为drawBitmap很慢。
测试设置
cluster arraylist有400个小图片(cluster.Picture)。时差是运行drawBitmap循环的测量参数。为了比较,我将drawBitmap替换为drawRect,并注释掉drawBitmap,使循环空体。 用于测试的设备 https://www.optus.com.au/shop/prepaidmobile/lg/leon
测试结果(毫秒)
上述时间仅测量逻辑部分。总游戏循环将接近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);
}
}
答案 0 :(得分:1)
我能够使用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 );