2D Kamera

Inledning

I många spel behöver man ett enkelt och smidigt sätt att flytta den statiska kameran, dvs i förlängningen betraktarens ögon. Vi ska därför titta på en enkel lösning för att ta hand om de vanligaste transformationer vi kan behöva. Vår kamera kommer att stödja följande.

  • Position
  • Zoom
  • Rotation

Vår lösning använder den inbyggda funktionalitet i SpriteBatch.Begin() som stödjer just detta nämligen strukturen Matrix.


public void Begin (
         SpriteSortMode sortMode,
         BlendState blendState,
         SamplerState samplerState,
         DepthStencilState depthStencilState,
         RasterizerState rasterizerState,
         Effect effect,
         Matrix transformMatrix
)

Allt som renderas mellan denna Begin och dess avslutande End kommer att transformeras om efter den Matris som anges. Vi nöjer oss med att bara använda den här strukturen utan att gå in närmare på hur matriser fungerar.

Camera2D

Camera2D.cs

class Camera2D
{
    protected float zoom; // Camera Zoom
    public Matrix transform; // Matrix Transform
    public Vector2 pos; // Camera Position
    protected float rotation; // Camera Rotation

    public Camera2D()
    {
        zoom = 1.0f;
        rotation = 0.0f;
        pos = Vector2.Zero;
    }

    public float Zoom
    {
        get { return zoom; }
        set { zoom = value; if (zoom <  0.02f) zoom = 0.02f; } // Negative zoom will flip image}
    }

    public float Rotation
    {
        get { return rotation; }
        set { rotation = value; }
    }


    public void Move(Vector2 amount)
    {
        pos += amount;
    }

    public Vector2 Pos
    {
        get { return pos; }
        set { pos = value; }
    }

    public Matrix get_transformation(GraphicsDevice graphicsDevice)
    {
        transform = Matrix.CreateTranslation(new Vector3(-pos.X, -pos.Y, 0)) *
                    Matrix.CreateRotationZ(Rotation) *
                    Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
                    Matrix.CreateTranslation(new Vector3(graphicsDevice.Viewport.Width *
 			0.5f, graphicsDevice.Viewport.Height * 0.5f, 0));
        return transform;
    }
}

Här är vår lilla klass som sköter hela matrisens transformation. Ännu en gång väljer vi att inte gå in närmare på hur transformeringen fungerar, man behöver kunskaper i linjär algebra Just nu får vi acceptera att det är ren magi :-D. I en kommande artikel kan vi går vidare med matrisberäkning och en annan tillämpning vilket är 3D. En sak kan vi dock säga, i vilken ordning man gör transformationen är viktig. Dvs A*B är INTE samma sak som B*A. Det är därför viktigt att göra multiplikationen i ordningen ovan för att det ska bli rätt.

Game

Vår Draw metod ser nu ut så här:

Game1.cs

spriteBatch.Begin(  SpriteSortMode.FrontToBack, 
                                BlendState.AlphaBlend,
                                SamplerState.LinearWrap,
                                DepthStencilState.Default,
                                RasterizerState.CullNone,
                                null,
                                cam.get_transformation(GraphicsDevice));

spriteBatch.Draw(mario, Vector2.Zero, 
	destRect, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
            
spriteBatch.End();

Detta är allt som behövs för att göra ett enkelt test. I vårt exempel så används följande tangenter för styrning av kameran.

  • Piltangenter – Position
  • Home/End – Rotation
  • PageUp/PageDown - Zoom

Demo projekt

Slutligen finns ett demo projekt att ladda hem

Lämna ett svar

Din e-postadress kommer inte publiceras.

Scroll to top