在 Android 中使用 Canvas.DrawBitmap 进行 Sprite 旋转.我很接近,我做错了什么? [英] Sprite Rotation in Android using Canvas.DrawBitmap. I am close, what am I doing wrong?

查看:65
本文介绍了在 Android 中使用 Canvas.DrawBitmap 进行 Sprite 旋转.我很接近,我做错了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个精灵旋转算法(它的名字很糟糕,只是用于测试).它是如此接近,用它绘制的精灵会旋转.每一帧我都可以添加 +5 度并看到我漂亮的小精灵旋转.问题是,画布上的其他东西现在闪烁了.如果我不进行旋转,则常规绘制的精灵效果很好.我想我很接近,但我只是不知道我错过了什么.下面是我的两个Draw_Sprite"方法,一个只是将先前加载的资源位图绘制到传入的画布上.另一个,做一些旋转,我知道如何将精灵旋转这么多度......然后绘制它.如果我有一个很好的游戏循环来绘制多个对象,那么一种类型是旋转类型.然后未旋转的精灵闪烁,但旋转的精灵从不闪烁.虽然如果我先绘制未旋转的精灵,一切都很好,但是 Z-Ordering 可能会搞砸(UI 元素上的精灵等)......方法定义:

I have this sprite rotating algorithm (its poorly named and just used for testing). It is so close, sprites drawn with it do rotate. Everyframe I can add +5 degrees to it and see my nice little sprite rotate around. The problem is, the other stuff drawn to the canvas now flickers. If I don't do the rotation the regular drawn sprites work great. I think I am close but I just don't know what piece I am missing. Below is my two "Draw_Sprite" methods, one just draws the previously resource loaded bitmap to the canvas passed in. The other one, does some rotation the best I know how to rotate the sprite by so x many degrees..and then draw it. If I have a nice game loop that draws several objects, one type is the rotated kind. Then the non-rotated sprites flicker and yet the rotated sprite never does. Though if I draw the non-rotated sprites first, all is well, but then the Z-Ordering could be messed up (sprites on top of UI elements etc)... The method definitions:

    /*************************************************
 * 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 或闪烁问题的建议?

So it does do it, things after a call to a rotational draw are drawn correctly. But the problem is it flickrs. Now One could say I should just do all my non rotational stuff and save that last, but the zordering would be off.... suggestions as to how to tackle this issue of zordering or the flickering?

推荐答案

尝试旋转前使用canvas.save(),操作完成后使用canvas.restore().

Try using canvas.save() before the rotation and canvas.restore() after manipulation is complete.

在画布上执行操作以更改对象的绘制方式时,您必须记住操作设置画布如何处理原点等...因此,如果您平移或旋转画布,将为那幅画布的生命周期.为了避免这种情况,您首先调用 save,在操作之前保存画布矩阵的快照,然后运行所有更改,然后调用 restore 将画布恢复到最后保存的点.否则,您的所有更改都会累积起来,您会得到意想不到的结果.

When performing manipulations on the canvas in order to change the way an object is drawn you have to remember the manipulations set how the canvas handles origins etc... So if you translate or rotate the canvas, that will be set for the lifetime of that canvas. In order to avoid this you first call save, which saves a snapshot of the canvas matrix before you manipulate it, then you run all your changes, then call restore which will restore the canvas back to the last saved point. Otherwise all your changes build up and you get unintended results.

这篇关于在 Android 中使用 Canvas.DrawBitmap 进行 Sprite 旋转.我很接近,我做错了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆