Android Java. Странное поведение с недействительным (Rect)

1

Я получаю эффект astrange с invalidate (Rect).

Я использую метод onDraw на холсте. В простейшем случае у меня есть фон и спрайт.

На первом проходе через onDraw я рисую фон и использую invalidate (Rect) (прямоугольник, который покрывает все игровое поле), и в тот же проход, я рисую спрайт и (потому что код одинаковый для всех проходов), я делаю недействительный (Rect) для Rect, в котором находился спрайт.

После первого прохода игровое поле верное. Весь фон на месте, с наложенным спрайтом.

На следующем и последующем прохождении через onDraw я рисую "грязный" бит фона, на котором был спрайт, и делает недействительным (Rect) на нем вместе со спрайтом и его новым "грязным" прямоугольником и другим недействительным ( Rect) для спрайта.

После этого прохода и всех последующих проходов я вижу только спрайт. Как будто полотно было очищено.

Разве не разрешено делать несколько недействительных (Rect) s за один проход? Это проблема? Я столкнулся с какой-то проблемой с асинхронностью?

Вот код onDraw(). Он работает нормально, но медленно, если я делаю полный экран invalidate() в конце onDraw(). Он также масштабирует все изображения. Все изображения и позиции экрана основаны на игровом поле 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);
    }
Теги:

1 ответ

0

не уверен, что вы делаете, так как вы не предоставили код, поэтому я просто дам общий совет:

для проходов после первого прохода используйте invalidate только на загрязненном прямоугольнике и в методе onDraw нарисуйте все, что нужно нарисовать, но только внутри грязного прямоугольника.

  • 0
    Спасибо за ответ. Я думаю, что я делаю, как вы рекомендуете. 'Rect src = rescaleRect (usedSet.get (ii)); Rect dst = displaceRect (src); canvas.drawBitmap (backcloth, src, dst, paint); недействительным (ДСТ); 'для фона и' canvas.drawBitmap (spriteim, src, dst, paint); недействительным (ДСТ);» для спрайта
  • 0
    так теперь это работает? если это так, пожалуйста, отметьте ответ. если нет, пожалуйста, предоставьте фрагмент вашего кода, чтобы мы могли увидеть, что не так.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню