私はinvalidate(Rect)で奇妙な効果を得ています。
キャンバスで onDraw メソッドを使用します。最も単純なケースでは、背景とスプライトがあります。
onDraw の最初のパスで、背景を描画し、invalidate(Rect) (プレイフィールド全体をカバーする rect) を使用し、同じパスでスプライトを描画します (コードはすべてのパスで同じであるため)。スプライトが入っていた Rect の invalidate(Rect)。
最初のパスの後、プレイフィールドは正しいです。背景全体が配置され、スプライトが重ねられています。
onDraw の次のパスと後続のパスでは、スプライトがあった背景の「汚れた」ビットを描画し、スプライトとその新しい「汚れた」四角形と一緒に、その上で無効化(Rect) を実行し、別の無効化( Rect) スプライト用。
このパスとその後のすべてのパスの後、スプライトのみが表示されます。まるでキャンバスがクリアされたかのようです。
1回のパスで複数の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);
}