我正在开发一个建立Abelian Sandpiles(一种2D细胞自动机)的Android项目。我有一个网格单元格(从小开始,但后来增长),并在网格上绘制正方形(或圆形)以显示每个单元格的状态。在每一步中,我通常更新不到30%的细胞。Android:反复绘制许多小形状,高效且准确
我的基本做法是从这个帖子采取:Android: How to get a custom view to redraw partially?
我画的所有图形到画布上,并将它缓存为位图,然后在每一步我只更新需要更新的细胞,然后缓存结果并重复。当电网相当小(小于50×50)时,这种方法运行得很好,但随着电网尺寸的增加,这种情况变得越来越不令人满意。这些问题是
1)实在是太慢了,当更新的数量变高
2),甚至当它运行平稳,图纸看起来不干净的 - 例如,小矩形的线条看起来相当波涛汹涌,不一致(见图)。
我相信,必须有一个更好的办法来解决这个问题。对于较大的网格(例如,150 x 150),我绘制了宽度为〜2.33的直角或圆形,并且这不是最佳的。有关提高性能和/或图像质量的建议吗? 简图代码是在这里:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (ready) {
if (needsCompleteRedraw) {
this.cachedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
cacheCanvas = new Canvas(this.cachedBitmap);
doInitialDrawing(cacheCanvas);
canvas.drawBitmap(this.cachedBitmap, 0, 0, null);
needsCompleteRedraw = false;
} else {
canvas.drawBitmap(this.cachedBitmap, 0, 0, null);
doPartialRedraws(cacheCanvas);
}
}
}
private void doInitialDrawing(Canvas clean) {
for (int i = 0; i < pile.gridHeight; i++) {
for (int j = 0; j < pile.gridWidth; j++) {
int state = pile.getGridValueAtPoint(new Point(j, i));
clean.drawRect(j * cellSize, i * cellSize, (j + 1)* cellSize, (i + 1) * cellSize, paints[state]);
}
}
}
private void doPartialRedraws(Canvas cached) {
for (Point p : pile.needsUpdateSet) {
int state = pile.getGridValueAtPoint(p);
cached.drawRect(p.x * cellSize, p.y * cellSize, (p.x + 1)* cellSize, (p.y + 1) * cellSize, paints[state]);
}
pile.needsUpdateSet = new HashSet<Point>();
}
和我的油漆对象设置与抗锯齿为真实的,我已经试过样式设置为两个FILL和FILL_AND_STROKE。
任何建议将不胜感激。
屏幕上的细胞越多,越接近编写游戏(在线搜索各种资源)。或者,您可能想看看其他开源游戏生活类型项目如何处理屏幕性能。 –
您也可以参考Android文档(开发 - API指南 - 动画和图形 - 可绘制和可绘制),并使用您使用单独线程绘制的SurfaceView。这非常高效,我相信它可以解决您的问题。 – Zelig63