Inledning
Denna artikel kommer att handla om hur du får animerad grafik till 2D sprites i XNA. Tekniken kan används inom enklare spel. Vi ska skapa en explosion utifrån en 2D textur. Vi börjar med grafiken.
Du kan ladda hem grafiken nedan i ett bättre format (BMP).
Börja med att skapa ett nytt XNA projekt av typen PC Game.
Tekniken
Som du ser ovan så är grafiken för explosionen i en o samma fil. Detta underlättar både programmeringen och eventuell redigering. Varje bildruta är av samma storlek. Detta är viktigt så jag upprepar: grafiken måste vara ordnad så att varje tänkt bild är lika stor!
Det är 4x4 bilder ordnade på rad från vänster till höger, uppifrån och ned. Varje bild är exakt 64x64 pixlar. Bilden är totalt 256x256 pixlar.
Vi ska införa en variabel som mäter tiden för animationen. Vi inför även en variabel som håller reda på vilken aktuell bild vi ska visa. Med bilder menas numera en av de 16 bilder som finns i texturen. Vi kan även ha en variabel som kontrollerar animationshastigheten.
//Animationer
Texture2D gfx_explosion;
Vector2 position;
int tid, bild;
const int animationsHastighet = 50;
Tiden kommer att mätas i millisekunder (1s = 1000 ms). Efter 50ms så kommer vi att byta bild i animationen. Variabeln bild kommer att ha värden från 0 till 15 (16 olika värden). När bild passerar värdet 15 så nollställer vi och spelar på så sätt animationen om och om igen.
Update
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
tid += gameTime.ElapsedGameTime.Milliseconds;
if (tid >= animationsHastighet)
{
tid = 0;
bild++;
if (bild > 15)
{
bild = 0;
}
}
base.Update(gameTime);
}
För att avläsa tiden som har passerat sedan föregående Update används gameTime.ElapsedGameTime.Milliseconds. Det ger oss tiden i millisekunder från det att förra uppritningen av spelet skedde.
Har det gått för lång tid så byter vi bild och nollställer tid. Har bild passerat 15 så nollställer vi även den variabeln.
Draw
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
Rectangle tmp = new Rectangle((bild % 4) * 64, (bild / 4) * 64, 64, 64);
spriteBatch.Draw(gfx_explosion, position, tmp, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
Här beräknar vi en temporärRectangle, tmp, baserat på värdet på variabeln bild. Nu gäller det att minnas vilka parametrar Rectangle tar. Först är det X-koordinat sedan Y-koordinat, därefter bredd och sist höjd.
(bild % 4) * 64
%-tecknet anger resten vid en heltalsdivision, ofta kallad modulo. Vi tar en titt på vilka värden uttrycket kommer att få beroende på bild i tabellen nedan:
bild | bild % 4 | (bild % 4) * 64 |
---|---|---|
0 | 0 | 0 |
1 | 1 | 64 |
2 | 2 | 128 |
3 | 3 | 192 |
4 | 0 | 0 |
5 | 1 | 64 |
6 | 2 | 128 |
7 | 3 | 192 |
8 | 0 | 0 |
9 | 1 | 64 |
10 | 2 | 128 |
11 | 3 | 192 |
12 | 0 | 0 |
13 | 1 | 64 |
14 | 2 | 128 |
15 | 3 | 192 |
(bild / 4) * 64
Division mellan två heltal kommer att resultera i ett heltal. Detta blir användbart i uttrycket som reglerar Y-positionen för rektangeln tmp. Värden på bild resulterar i:
bild | bild / 4 | (bild / 4) * 64 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 0 |
2 | 0 | 0 |
3 | 0 | 0 |
4 | 1 | 64 |
5 | 1 | 64 |
6 | 1 | 64 |
7 | 1 | 64 |
8 | 2 | 128 |
9 | 2 | 128 |
10 | 2 | 128 |
11 | 2 | 128 |
12 | 3 | 192 |
13 | 3 | 192 |
14 | 3 | 192 |
15 | 3 | 192 |
Uppritningen blir nu lätt då vi hela tiden kan beräkna rätt bild som ska användas för för animationen.