Sprite Rotation в Android с использованием Canvas.DrawBitmap.Я рядом, что я делаю не так? - PullRequest
7 голосов
/ 27 августа 2010

У меня есть этот алгоритм вращения спрайтов (он плохо назван и используется только для тестирования). Это так близко, спрайты, нарисованные им, вращаются. К каждому кадру я могу добавить +5 градусов и увидеть, как мой милый маленький спрайт вращается вокруг. Проблема в том, что другой материал, нарисованный на холсте, теперь мигает. Если я не делаю вращение, то обычные нарисованные спрайты работают отлично. Я думаю, что я близко, но я просто не знаю, что мне не хватает. Ниже приведены два моих метода «Draw_Sprite», один из которых просто рисует ранее загруженное растровое изображение на переданный холст. Другой, делает какое-то вращение лучше, чем я знаю, как повернуть спрайт на столько х градусов ... а затем нарисовать его , Если у меня есть хороший игровой цикл, который рисует несколько объектов, то один тип будет повернутым. Тогда не повернутые спрайты мерцают, а вращающийся спрайт никогда не срабатывает. Хотя, если я сначала рисую не повернутые спрайты, все будет хорошо, но тогда Z-упорядоченность может быть испорчена (спрайты поверх элементов пользовательского интерфейса и т. Д.) ... Определения метода:

    /*************************************************
 * rotated sprite, ignore the whatever, its for ease of use and testing to have this argument list
 * @param c canvas to draw on.
 * @param whatever ignore 
 * @param rot degrees to rotate
 * @return
 */
public int Draw_Sprite(Canvas c, int whatever, int rot) {   
    //rotating sprite
    Rect src = new Rect(0, 0, width, height);
    Rect dst = new Rect(x, y, x + width, y + height);
    Matrix orig = c.getMatrix();        
    mMatrix = orig;
    orig.setTranslate(0, 0);
    orig.postRotate(rot, x+width/2, y+height/2); 
    c.setMatrix(orig);
    c.drawBitmap(images[curr_frame], src, dst, null);
    c.setMatrix(mMatrix); //set it back so all things afterwards are displayed correctly.

    isScaled=false;
    return 1;

}

/********************************************************
 * draw a regular sprite to canvas c
 * @param c
 * @return
 */
public int Draw_Sprite(Canvas c) {  

    Rect src = new Rect(0, 0, width, height);
    Rect dst = new Rect(x, y, x + width, y + height);       
    c.drawBitmap(images[curr_frame], src, dst, null);

    isScaled=false;
    return 1;
}

А теперь использование:

void onDraw(Canvas c)
{
    canvas.drawRect( bgRect, bgPaint); //draw the background

    //draw all game objects
      // draw the normal items
    for (GameEntity graphic : _graphics) { 
        graphic.toScreenCoords((int)player_x, (int)player_y);
        if(graphic.getType().equals("planet")) //draw planets
            graphic.Draw_Sprite(canvas); //before the rotation call draws fine
        else
        {
            //rotate all space ships every frame so i see them spinning        
            //test rotation
            mRot +=5;
            if(mRot>=360)
                mRot=0;
            graphic.Draw_Sprite(canvas, 0, mRot); //yes function name will be better in future.  this rotates spins draws fine


        }                           
       }

       thePlayer.Draw_Sprite(canvas); //FLICKERS
       drawUI(canvas);//all things here flickr

}  

Так оно и есть, вещи после вызова ротационного розыгрыша отрисовываются правильно. Но проблема в том, что это мерцает. Теперь можно было бы сказать, что я должен просто сделать все свои вещи, не связанные с вращением, и сохранить этот последний, но zordering будет отключен .... предложения относительно того, как решить эту проблему zordering или мерцания?

Ответы [ 2 ]

15 голосов
/ 30 декабря 2011

Только для следующего парня, который может прочитать это. Вы можете сделать это всего несколькими строками кода:

canvas.save();
canvas.rotate(rotation_angle, x + (widthofimage / 2), y + (heightofimage / 2));
canvas.drawBitmap(bitmap, x, y, null);
canvas.restore();
8 голосов
/ 08 октября 2010

Попробуйте использовать canvas.save () до вращения и canvas.restore () после завершения манипуляции.

При выполнении манипуляций на холсте для изменения способа рисования объекта вы должны помнитьманипуляции устанавливают, как холст обрабатывает происхождение и т. д. Итак, если вы переведите или поверните холст, это будет установлено на весь срок службы холста.Чтобы избежать этого, вы сначала вызываете функцию save, которая сохраняет снимок матрицы холста, прежде чем манипулировать ею, затем вы запускаете все свои изменения и затем вызываете restore, которая восстанавливает холст обратно до последней сохраненной точки.В противном случае все ваши изменения накапливаются, и вы получаете непредвиденные результаты.

...