2010-08-27 14 views
7

Tengo este algoritmo de rotación de sprites (su nombre es malo y acaba de usarse para probar). Está tan cerca, los sprites dibujados con él giran. Cada cuadro puedo agregar +5 grados a él y ver girar mi pequeño sprite. El problema es que las otras cosas atraídas por el lienzo ahora parpadean. Si no hago la rotación, los sprites dibujados regularmente funcionan bien. Creo que estoy cerca, pero no sé qué pieza me falta. A continuación están mis dos métodos "Draw_Sprite", uno simplemente dibuja el mapa de bits previamente cargado al lienzo pasado. El otro, rota un poco, lo mejor que sé es cómo rotar el sprite por tantos x grados ... y luego dibujarlo . Si tengo un buen bucle de juego que dibuja varios objetos, un tipo es el tipo girado. Luego, los sprites no girados parpadean y, sin embargo, el sprite girado nunca lo hace. Aunque si dibujo los sprites no rotados en primer lugar, todo está bien, pero entonces el orden Z podría ser mal estado (sprites en la parte superior de los elementos de la interfaz, etc ...) Las definiciones de método:Sprite Rotation en Android usando Canvas.DrawBitmap. Estoy cerca, ¿qué estoy haciendo mal?

/************************************************* 
* 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; 
} 

Y ahora el uso:

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 

} 

Así que lo hace, las cosas después de una llamada a un sorteo rotacional se dibujan correctamente. Pero el problema es flickrs. Ahora uno podría decir que debería hacer todas mis cosas no rotativas y guardar eso último, pero el zordering estaría apagado ... ¿sugerencias sobre cómo abordar este problema de zordering o el parpadeo?

Respuesta

8

Pruebe usar canvas.save() antes de la rotación y canvas.restore() después de completar la manipulación.

Al realizar manipulaciones en el lienzo para cambiar la forma en que se dibuja un objeto, debe recordar las manipulaciones que establecen cómo maneja el lienzo los orígenes, etc. ... Así que si traduce o rota el lienzo, eso se configurará para la vida de ese lienzo. Para evitar esto, primero debe llamar a save, que guarda una instantánea de la matriz canvas antes de manipularla, luego ejecuta todos los cambios y luego ejecuta la restauración que restaurará el lienzo hasta el último punto guardado. De lo contrario, todos sus cambios se acumulan y obtiene resultados no deseados.

+0

que hizo que ... wow totalmente – Codejoy

+0

acabo de encontrar con esto ayer. Tenía una suposición completamente errónea de cómo el lienzo maneja las manipulaciones. Me alegro de haber aprendido de la manera correcta! :) – methodin

15

Solo para el siguiente tipo que pueda leer esto. Esto se puede hacer con sólo unas pocas líneas de código:

canvas.save(); 
canvas.rotate(rotation_angle, x + (widthofimage/2), y + (heightofimage/2)); 
canvas.drawBitmap(bitmap, x, y, null); 
canvas.restore(); 
Cuestiones relacionadas