Asteroids – Del 3

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.

bild

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.

Deklarering

        Texture2D gfx;
        Vector2 position;
        float angle = 0;
        bool accelerate;
        Texture2D gfx_acc;

Se til att vi även laddar in den nya grafiken i LoadContent().

Komplettering till 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.

Komplettering till Update

            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.

Komplettering till Draw

            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!

bild

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.

Deklarering: Fysik

        //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).

Exempel: Fysik

        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.

Komplettering till Update

            //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.

Lämna ett svar

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

Scroll to top