Inledning
Denna artikel är en direkt fortsättning på Asteroids - Del 2 . Vi ska här få skeppet att röra på sig inom en begränsad yta samt skapa illusionen av att motorerna tänds.
Tänd raketerna
Det går att skapa en illusion av att motorerna tänds genom att rita ut grafik för detta bakom den grafik som vi ritar som rymdskeppet. Ladda hem texturen nedan och placera den i din Content mapp. Lägg även till den i Solution Explorern.
Deklarera en bool för att hålla reda på om vi accelererar eller ej. Deklarera även en ny Texture2D variabel till vår nya textur.
Texture2D gfx;
Vector2 position;
float angle = 0;
bool accelerate;
Texture2D gfx_acc;
Se til att vi även laddar in den nya grafiken i LoadContent().
gfx_acc = Content.Load<Texture2D>("ship_acc");
Lägg till en extra if-sats i Update() för att kolla om vi trycker på pil upp knappen.
if (ks.IsKeyDown(Keys.Up))
{
accelerate = true;
}
else
{
accelerate = false;
}
Vi avslutar nu med att ändra i Draw()-metoden. Om vi accelererar så ritar vi först ut raketerna, d v s grafiken från gfx_acc.
spriteBatch.Begin();
if (accelerate)
{
spriteBatch.Draw(gfx_acc, position, null, Color.White, angle + (float)Math.PI / 2,
new Vector2(gfx.Width / 2, gfx.Height / 2), 1.0f, SpriteEffects.None, 0);
}
spriteBatch.Draw(gfx, position, null, Color.White, angle + (float)Math.PI / 2,
new Vector2(gfx.Width / 2, gfx.Height / 2), 1.0f, SpriteEffects.None, 0);
spriteBatch.End();
Testa nu!
Rörelser och fysik
Rymdskeppet ska nu få en hastighet som flyttar skeppets position i den riktning hastigheten pekar. En lämlig variabeltyp för detta är Vector2 då vi kan lagra hastighet både i X- och Y-led samtidigt. Vi kallar denna variabel ship_speed.
Vi behöver ett värde på accelerationen för rymdskeppet. Vi kallar denna variabel ship_acc. Vi inför också en maxgräns för hur hög hastighet vårt rymdskepp kan ha, ship_max_speed.
Variablerna deklareras överst i programmet tillsammans med tidigare variabler.
//Fysik
Vector2 ship_speed = new Vector2();
const float ship_acc = 0.1f;
const float ship_max_speed = 4;
Om vi accelererar (trycker pil upp) så ökar vi hastigheten med accelerationen i den riktning (angle) rymdspkeppet pekar. För att beräkna riktningen utifrån angle används Math.Cos() och Math.Sin() (rad 21-22 nedan).
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
KeyboardState ks = Keyboard.GetState();
if (ks.IsKeyDown(Keys.Left))
{
angle -= 0.05f;
}
if (ks.IsKeyDown(Keys.Right))
{
angle += 0.05f;
}
if (ks.IsKeyDown(Keys.Up))
{
accelerate = true;
ship_speed.X += ship_acc * (float)Math.Cos(angle);
ship_speed.Y += ship_acc * (float)Math.Sin(angle);
if (ship_speed.Length() > ship_max_speed)
{
ship_speed.Normalize();
ship_speed *= ship_max_speed;
}
}
else
{
accelerate = false;
}
position += ship_speed;
base.Update(gameTime);
}
På rad 23 görs ett test för att se om hastigheten har överskridit maxhastigheten som vi tidigare angav. Metoden Length() beräknar längden som utgörs av vektorns X- och Y-värde. Det är ett mått på hur långt skeppet flyttas oberoende av riktning.
Om hastigheten är för hög så normaliseras ship_speed. Detta innebär att längden på ship_speed räknas om till 1.0 samtidigt som riktningen behålls. Därefter multipliceras ship_speed med maxhastigheten (rad 26). Hastigheten blir därmed ship_max_speed.
Från exemplet ovan; mosvarigheten till
ship_speed *= ship_max_speed;
Är
ship_speed = ship_speed * ship_max_speed;
Skeppet ska flyttas med hastigheten. På rad 34 så sker detta. += fungerar efter samma princip som *= fast då med addition.
Dags att testa igen!
Begränsad rörelse
Som du kanske märkt så kan du köra skeppet ut i cyberrymden och riskera att aldrig se det igen. Genom att införa extra kontroll på skeppets position i Update() så hindras skeppet från att åka för långt bort.
//Utanför skärmen?
if (position.X < -80)
{
position.X = graphics.GraphicsDevice.Viewport.Width + 80;
}
if (position.X > graphics.GraphicsDevice.Viewport.Width + 80)
{
position.X = -80;
}
if (position.Y < -60)
{
position.Y = graphics.GraphicsDevice.Viewport.Height + 60;
}
if (position.Y > graphics.GraphicsDevice.Viewport.Height + 60)
{
position.Y = -60;
}
Är skeppet för långt till höger så teleporterar vi det tillbaka till vänster sida av skärmen. Är skeppet för långt nedanför, så tillbaka till överdelen av skärmen etc. etc.
Testa nu! Voila! Genast en känsla av Asteroids.