Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 22 di 53
  • livello principiante
Indice lezioni

Matrici di Trasformazione

Ottenere e mixare le trasformazioni sfruttando le matrici e un pizzico di algebra
Ottenere e mixare le trasformazioni sfruttando le matrici e un pizzico di algebra
Link copiato negli appunti

Come ultimo esempio di uso dello SpriteBatch utilizziamo una matrice di trasformazione, da applicare per modificare le coordinate della posizione di ciascun vertice risultante da ogni chiamata di Draw.

Una matrice di trasformazione è un oggetto molto potente, in quanto ci consente di specificare una serie di trasformazioni da applicare in sequenza una dopo l'altra. Il bello di una matrice è che in effetti consente una rappresentazione compatta (16 valori floating point) di tantissime informazioni.

In effetti basta considerare che se abbiamo una matrice di rotazione, una di scala e una di traslazione, semplicemente moltiplicandole tra loro otterremo una unica matrice in grado di effettuare una rotazione, una scala e una traslazione.

Ad esempio, per ruotare una serie di oggetti contamporaneamente intorno al centro dello schermo, dovremmo:

  1. traslare gli oggetti in modo che l'origine sia il centro dello schermo
  2. ruotare gli oggetti della rotazione desiderata
  3. traslare gli oggetti in modo da ripristinare l'origine all'angolo superiore sinistro dello schermo

Per avere questo effetto, creiamo una matrice che rappresenti questa trasformazione (adatta ad uno schermo a risoluzione 800×480):

Matrix.CreateTranslation(-400, -240, 0) *
Matrix.CreateRotationZ((float)gameTime.TotalGameTime.TotalMinutes) *
Matrix.CreateTranslation(400, 240, 0)

e la passiamo come ultimo parametro dell'overload più lungo del metodo SpriteBatch.Begin:

sprite_batch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, null, null, null,
  Matrix.CreateTranslation(-400, -240, 0) *
  Matrix.CreateRotationZ((float)gameTime.TotalGameTime.TotalMinutes) *
  Matrix.CreateTranslation(400, 240, 0));

a questo punto possiamo disegnare una serie di asteroidi, ma questa volta li disegniamo singolarmente (e non secondo una griglia piena):

var width = 800 / 10;
var height = 480 / 7;
for (int i = 0; i < 10; i++)
{
  for (int j = 0; j < 7; j++)
  {
    if((i + j) % 2 == 0)
      sprite_batch.Draw(asteroid, new Rectangle(i * width, j * height, width, height), Color.White);
  }
}

Il risultato è:

Figura 36. La trasformazione applicata agli asteroidi
Applicare la trasformazione agli asteroidi

Possiamo anche ruotare ciascun asteroide in direzione contraria a quella della rotazione globale, in modo che gli asteroidi restino tutti allineati ai lati della finestra; siccome la rotazione intorno al centro è pari al numero di minuti da cui l'applicazione è stata avviata, allora ruotiamo ciascun asteroide del numero di minuti dall'avvio della applicazione negato:

sprite_batch.Draw(asteroid, new Rectangle(i * width, j * height, width, height), null, Color.White,
  -(float)gameTime.TotalGameTime.TotalMinutes, new Vector2(asteroid.Width, asteroid.Height) * 0.5f,
  SpriteEffects.None, 0.0f);

Il risultato è:

Figura 37. Controrotazione dei singoli asteroidi
Controrotazione dei singoli asteroidi

Ti consigliamo anche