Bu yazıda en basit kamera sınıfı olan hedef kamerası oluşturacağız. Hedef kamerasının temel iki bileşeni vardır – kamera konumu ve hedef konumu. Bu kamera sadece bulunduğu konumdan hedefe bakar. Bu verileri modeli çizdirirken kullandığımız Matrix sınıfının CreateLookAt() methoduna parametre olarak girmek durumundayız.
Hedef kamerası oluştururken temel kamera sınıfından miras alarak oluşturmak projeksiyon ve diğer matrislerin bizim için hesaplanmasını sağlayacaktır.
public class TargetCamera : Camera { public Vector3 Position { get; set; } public Vector3 Target { get; set; } public TargetCamera(Vector3 Position, Vector3 Target, GraphicsDevice graphicsDevice) : base(graphicsDevice) { this.Position = Position; this.Target = Target; } public override void Update() { Vector3 forward = Target - Position; Vector3 side = Vector3.Cross(Vector3.Up, forward); Vector3 up = Vector3.Cross(forward, side); this.View = Matrix.CreateLookAt(Position, Target, up); } }
Dikkat edilirse public olarak tanımlanan Position (kamera konumu) ve Target (hedef konumu) değerleri kamera oluşturulurken veya Update() methodu içerisinde gerektiği gibi güncellenebilir. Bu kamerayı kullanabilmek için Game1 sınıfında da çeşitli değişiklikler yapmamız gerekiyor. Öncelikle model listesini tuttuğumuz kodun altına bir adet kamera tanımlayarak başlayabiliriz.
List<CModel> models = new List<CModel>(); Camera camera;
Daha sonra kamerayı LoadContent() methodu içerisinde yüklememiz gerekiyor.
camera = new TargetCamera(new Vector3(100, 150, -500), Vector3.Zero, GraphicsDevice);
Ayrıca kameranın güncellenmesi için Update() methodu içerisinde aşağıdaki kodu eklememiz gerekir.
protected override void Update(GameTime gameTime) { camera.Update(); base.Update(gameTime); }
Son olarak ise görünüm ve projeksiyon matrislerini kameranın özellikleri arasından çekip modelin çizilmesi için kullanabiliriz.
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); foreach (CModel model in models) model.Draw(camera.View, camera.Projection); base.Draw(gameTime); }
Bütün kodlar eklendikten sonraki Game1 sınıfı şöyledir.
public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; List<CModel> models = new List<CModel>(); Camera camera; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.PreferredBackBufferWidth = 1280; graphics.PreferredBackBufferHeight = 800; } protected override void Initialize() { base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); camera = new TargetCamera(new Vector3(100, 150, -500), Vector3.Zero, GraphicsDevice); models.Add(new CModel(Content.Load<Model>("Skyline"), Vector3.Zero, Vector3.Zero, new Vector3(1f), GraphicsDevice)); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { // ESC'ye veya Joystick'den Geri tuşuna basarak oyundan çıkmak için if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape)) this.Exit(); camera.Update(); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); foreach (CModel model in models) model.Draw(camera.View, camera.Projection); base.Draw(gameTime); } }