Asteroids – Del 4

Inledning

Denna artikel är en direkt fortsättning på Asteroids - Del 3 . Denna gång gäller det att få rymdskeppet att skjuta. För att hålla koll på hur många skott som flyger på skärmen så ska vi lära oss skriva ut text med hjälp av klassen SpriteFont.

Nya variabler

Okej, vi kommer att behöva en rad nya variabler. Vi behöver grafik till skottet, en font för att rita ut text. Vi kommer också att behöva variabler för att mäta tiden från det att ett skott avlossats till dess att nästa skott kan avlossas. Varje skott behöver en aktuell position och en hastighet för att vi ska kunna rita ut och flytta dem. Till detta använder vi List av typen Vector2.

Ladda hem grafiken till skottet nedan.

Deklarera följande variabler i början av programmet.

Deklarering

        //Skott
        Texture2D gfx_shot;
        SpriteFont font;
        List<Vector2> shot_pos = new List<Vector2>();
        List<Vector2> shot_speed = new List<Vector2>();
        const int shot_delay = 200;
        int shot_time;

SpriteFont

För att kunna skriva ut något på skärmen så behövs en SpriteFont. En SpriteFont är liksom en textur en komponent som ska ligga i Content i Solution Explorern. Skillnaden är dock att du kan skapa en ny SpriteFont direkt från Visual Studio genom att högerklicka på Content i Solution Explorern och välja "Add -> New Item...".

bild

Välj alternativet "Sprite Font" och döp filen till myFont.spritefont.

bild

En SpriteFont är egentligen ett XML-dokument som talar om vilket storlek, stil och typsnitt som ska användas när SpriteFont'en ska skapas. Detta betyder bland annat att vi måste göra några ändringar i filen myFont.spritefont. Dubbelklicka på filen i Solution Explorer'n och gör ändringar enligt bilden nedan. Ändra FontName till Verdana och Size till 16.

bild

En SpriteFont-variabel har vi redan deklarerat vid namn font. Inladding sker precis som med texturer i metoden LoadContent(). Vi passar på att ladda grafiken för skottet samtidigt. Placera följande kod där:

Komplettering till LoadContent

	gfx_shot = Content.Load<Texture2D>("shot");
	font = Content.Load<SpriteFont>("myFont");

Kvar är nu bara uppritning. Count i klassen List (shot_pos) ger oss det aktuella antalet skott som vi har på skärmen. Vi använder oss av metoden DrawString(). Uppritning sker som vanligt i metoden Draw() i vårt projekt. Placera följande kod där:

Komplettering till Draw

spriteBatch.DrawString(font, "Shots: " + shot_pos.Count, new Vector2(10, 10), Color.White);

Testa nu ditt projekt! Shots kommer alltid att vara 0 då vi ännu inte avfyrar något.

Skapa skott

I Update() måste vi lägga till en koll för knappen SPACE på tangentbordet. Om det har gått tillräckligt lång tid från föregående skott så ska vi lägga till ett skott i listan shot_pos samt med rätt hastighet i listan shot_speed.

Komplettering till Update

shot_time -= gameTime.ElapsedGameTime.Milliseconds;
if (shot_time < 0)
{
	shot_time = 0;
}

if (ks.IsKeyDown(Keys.Space) && shot_time == 0)
{
	shot_time = shot_delay;
	shot_pos.Add(new Vector2(position.X, position.Y));
	shot_speed.Add(new Vector2(5 * (float)Math.Cos(angle), 5 * (float)Math.Sin(angle)));
}

Variabeln shot_time används för att mäta tiden mellan skotten. Varje gång Update()-metoden körs så räknas variabeln ned med den tid i millisekunder som har gått sedan föregående Update(). Variabeln gameTime i Update() innehåller all information om tid.

Om vi trycker SPACE och tiden är mogen för ett nytt skott så skapas två Vector2 för att beskriva skottets position och hastighet. Positionen blir samma som rymdskeppets och hastigheten bygger på skeppets vinkel (angle).

Rita ut skotten

I metoden Draw() behöver vi göra en loop för att rita ut alla skott:

Komplettering till Draw

for (int i = 0; i < shot_pos.Count; i++)
{
	spriteBatch.Draw(gfx_shot, shot_pos[i], null, Color.White, 0,
		new Vector2(gfx_shot.Width / 2, gfx_shot.Height / 2), 1.0f, SpriteEffects.None, 0);
}

Testa nu!

Uppdatera skotten

Som du kanske märkte så rör inte skotten på sig. Vi måste gå igenom alla skott i metoden Update() för att förlytta dem precis som vi gjort med rymdskeppet. Samtidigt kan vi också passa på att städa bort de skott som flygit för långt iväg.

Komplettering till Update

for(int i=0; i < shot_pos.Count; i++)
{
	shot_pos[i] += shot_speed[i];
	if (shot_pos[i].X < -100 || shot_pos[i].X > graphics.GraphicsDevice.Viewport.Width + 100
	   || shot_pos[i].Y < -100 || shot_pos[i].Y > graphics.GraphicsDevice.Viewport.Height + 100)
	{
	   shot_pos.RemoveAt(i);
	   shot_speed.RemoveAt(i);
	   continue;
	}
	
}

Det var allt denna gång!

bild

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Scroll to top