【发布时间】:2012-06-02 16:32:43
【问题描述】:
我得到了 invalidate(Rect) 的奇怪效果。
我在画布上使用 onDraw 方法。在最简单的情况下,我有一个背景和一个精灵。
在第一次通过 onDraw 时,我绘制背景并使用 invalidate(Rect)(一个覆盖整个运动场的矩形),在同一次通过中,我绘制了一个 sprite 并且(因为所有通道的代码都是相同的) 我对精灵所在的 Rect 做了一个 invalidate(Rect)。
第一次传球后,比赛场地是正确的。整个背景就位,精灵叠加。
在下一次和后续通过 onDraw 时,我绘制精灵所在背景的“脏”位,并在其上执行 invalidate(Rect) 以及精灵及其新的“脏”矩形,然后sprite 的另一个 invalidate(Rect)。
在这遍和所有后续遍之后,我只看到了精灵。就好像画布被清除了一样。
不允许一次做多个invalidate(Rect)吗?这是问题吗?我遇到了一些异步问题吗?
这里是 onDraw() 代码。如果我在 onDraw() 结束时执行全屏 invalidate() 代替,它可以正常工作,但速度很慢。 它还缩放所有图像。所有图像和屏幕位置均基于 640x480 的运动场, 并缩放到当前 android 设备的大小。在我尝试优化屏幕之前,一切正常 使用 invalidate(Rect) 绘图。
@Override
protected void onDraw(Canvas canvas)
{
int ii;
// Draw the background scene
// Restore all the bits of the backcloth that got
// trampled on by any sprites or the cursor
// On the first pass the whole playfield dirty rectangle is in place in mask
paint.reset();
mask.collapse();
ArrayList <Rect> usedSet = mask.getUsedRectSet();
for (ii = 0; ii < usedSet.size(); ii++)
{
Rect src = rescaleRect(usedSet.get(ii));
Rect dst = displaceRect(src);
canvas.drawBitmap(backcloth, src, dst, paint);
invalidate(dst);
}
// Leave used Rect set clear for next set of sprites
mask.ClearUsedRectSet();
//
// draw Sprites
// screen scaling and
// displacement is done here.
//
ArrayList <Sprite> slist = jadedata.getCurrentSprites();
//Sort sprites into ascending order of priority
// This is a sinking sort. On first pass, the highest
// priority sprite arrives at the bottom. On second,
// the next highest arrives at second bottom, etc.
// Sprites of the same priority remain in their
// original sequence with respect to each other.
for (ii = 0; ii< slist.size()-1; ii++)
{
int sw=0;
for (int jj = 0; jj < (slist.size()-ii-1); jj++)
{
Sprite spare1 = slist.get(jj);
Sprite spare2 = slist.get(jj+1);
if (spare1.getPriority() > spare2.getPriority())
{
slist.set(jj+1, spare1);
slist.set(jj, spare2);
sw=1;
}
}
if (sw==0) break; // exit if slist is already in sequence
}
for (ii = 0; ii< slist.size(); ii++)
{
Point p = new Point();
Point e = new Point();
Rect o = new Rect();
Sprite sprite = (Sprite)slist.get(ii);
// Zero-priority sprites do not get drawn
if (sprite.getPriority() == 0) continue;
p = sprite.getPosition();
e = sprite.getExtent();
// make a rect for usedRects
Rect r = new Rect(0, 0, e.x-1, e.y-1);
Rect src = new Rect(r);
// move it to the model playfield position
r.offset(p.x-e.x/2, p.y-e.y/2);
// make an overlap rect so we can apply it to the source image
o = overlapRect(r, 0, 0, iWidth, iHeight);
// trim r for the used rectangles
r = trimRect(r, 0, 0, iWidth, iHeight);
// add it to used Rectangles
mask.addNewRect(r);
// draw the sprite image
Rect d = rescaleRect(usedSet.get(ii));
Rect dst = displaceRect(d);
Bitmap spriteim = sprite.getCurrentImage();
src.top += o.top;
src.left += o.left;
src.bottom -= o.bottom;
src.right -= o.right;
canvas.drawBitmap(spriteim, src, dst, paint);
invalidate(dst);
}
【问题讨论】: