▼XNA Game Studioメモ▼
モデルの移動
モデルの平行移動を行うプログラムを作成する。方向キーで上下左右への移動を行う。
リソースの追加Cameraクラスの作成
- 戦闘機の3DモデルをソリューションエクスプローラのContentにドラッグ&ドロップ。
視点ごとに保持する情報をまとめたCameraクラスを作成。
保持する情報は次の通り。Camera.csを次のように編集。
- ビュー変換行列
- カメラ位置
- 参照点
- UPベクトル
- 射影変換行列
- 視野角
- アスペクト比
- ニアクリップ面の距離
- ファークリップ面の距離
Camera.cs using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; //カメラ public class Camera { //ビュー変換行列 private Matrix view; public Matrix View { get { return view; } } //射影変換行列 private Matrix projection; public Matrix Projection { get { return projection; } } //カメラ位置 private Vector3 position; public Vector3 Position { set { position=value; Update(); } get { return position; } } public float PositionX { set { position.X=value; Update(); } get { return position.X; } } public float PositionY { set { position.Y=value; Update(); } get { return position.Y; } } public float PositionZ { set { position.Z=value; Update(); } get { return position.Z; } } //参照点 private Vector3 look; public Vector3 Look { set { look=value; LookAt(position,look,Vector3.Up); } get { return look; } } //方向 public Vector3 Direction { get { Vector3 direction=look-position; direction.Normalize(); return direction; } } //横位置 private float yaw; public float Yaw { set { yaw=value; Update(); } get { return yaw; } } //高さ位置 private float pitch; public float Pitch { set { pitch=value; Update(); } get { return pitch; } } //傾き位置 private float roll; public float Roll { set { roll=value; Update(); } get { return roll; } } //コンストラクタ public Camera(float aspectRatio) { //ビュー変換行列 yaw =0.0f; pitch=0.0f; roll =0.0f; position=new Vector3(0.0f,0.0f,3.0f); Update(); //射影変換行列 PerspectiveFieldOfView( MathHelper.ToRadians(45.0f), aspectRatio, 0.005f, 1000.0f ); } //ビュー変換行列の更新 private void Update() { Vector3 vec=new Vector3(0,0,-1); Matrix trans=Matrix.CreateFromYawPitchRoll(yaw,pitch,roll); Vector3 look=Vector3.Transform(vec,trans)+position; LookAt(position,look,Vector3.Up); } //ビュー変換行列の設定 public void LookAt(Vector3 position,Vector3 look,Vector3 up) { this.position=position; this.look=look; view=Matrix.CreateLookAt(position,look,up); } //射影変換行列の設定 public void PerspectiveFieldOfView(float fieldOfView, float aspectRatio,float near,float far) { projection=Matrix.CreatePerspectiveFieldOfView( fieldOfView,aspectRatio,near,far); } }
Figureクラスの作成
モデルごとに保持する情報をまとめたFigureクラスを作成。描画を行うDraw()メソッドも持つ。
保持する情報は次の通り。Figure.csを次のように編集。
- 形状情報
- 位置情報
- X座標
- Y座標
- Z座標
- 回転情報
- X軸回転
- Y軸回転
- Z軸回転
- スケール情報
- X軸スケール
- Y軸スケール
- Z軸スケール
Figure.cs using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; //形状データ public class Figure { //モデル private Model model; //位置 private Vector3 position; public Vector3 Position { get { return position; } set { position=value; } } public float PositionX { get { return position.X; } set { position.X=value; } } public float PositionY { get { return position.Y; } set { position.Y=value; } } public float PositionZ { get { return position.Z; } set { position.Z=value; } } //X軸回転 private float rotateX; public float RotateX { get { return rotateX; } set { rotateX=value; } } //Y軸回転 private float rotateY; public float RotateY { get { return rotateY; } set { rotateY=value; } } //Z軸回転 private float rotateZ; public float RotateZ { get { return rotateZ; } set { rotateZ=value; } } //スケール private Vector3 scale; public Vector3 Scale { get { return scale; } set { scale=value; } } public float ScaleX { get { return scale.X; } set { scale.X=value; } } public float ScaleY { get { return scale.Y; } set { scale.Y=value; } } public float ScaleZ { get { return scale.Z; } set { scale.Z=value; } } //コンストラクタ public Figure(Model model) { this.model=model; position=new Vector3(0.0f,0.0f,0.0f); rotateX=0.0f; rotateY=0.0f; rotateZ=0.0f; scale=new Vector3(1.0f,1.0f,1.0f); } //描画 public void Draw(Camera camera) { //モデルの設定 Matrix world= Matrix.CreateRotationX(rotateX)* Matrix.CreateRotationY(rotateY)* Matrix.CreateRotationZ(rotateZ)* Matrix.CreateScale(scale)* Matrix.CreateTranslation(position); foreach (ModelMesh mesh in model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World=world; effect.View=camera.View; effect.Projection=camera.Projection; } } //モデルの描画 foreach (ModelMesh mesh in model.Meshes) { mesh.Draw(); } } }
ソースコードの作成
Game.csを次のように編集。
Game.cs using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage; namespace SpaceChace { public class Game : Microsoft.Xna.Framework.Game { //システム private GraphicsDeviceManager graphics; //グラフィックス private SpriteBatch spriteBatch;//スプライトバッチ private SpriteFont font; //フォント //フィギュア private Camera camera; //カメラ private Figure fighter;//戦闘機 //コンストラクタ public Game() { graphics=new GraphicsDeviceManager(this); Content.RootDirectory="Content"; } //初期化 protected override void Initialize() { //描画間隔の指定 IsFixedTimeStep=true; TargetElapsedTime=new TimeSpan(200000); Window.Title="PositionEx"; //ベースの初期化 base.Initialize(); } //グラフィクスコンテントの読み込み protected override void LoadContent() { //フォントの生成 spriteBatch=new SpriteBatch(GraphicsDevice); font=Content.Load<SpriteFont>("DefaultFont"); //カメラの生成 camera=new Camera( (float)GraphicsDevice.Viewport.Width/ (float)GraphicsDevice.Viewport.Height); //戦闘機の生成 fighter=new Figure(Content.Load<Model>("fighter")); } //グラフィクスコンテントの解放 protected override void UnloadContent() { } //更新 protected override void Update(GameTime gameTime) { //キー状態 KeyboardState keyState=Keyboard.GetState(); //キー操作 if (keyState.IsKeyDown(Keys.Left)) { fighter.PositionX-=0.2f; } else if (keyState.IsKeyDown(Keys.Right)) { fighter.PositionX+=0.2f; } else if (keyState.IsKeyDown(Keys.Up)) { fighter.PositionY+=0.2f; } else if (keyState.IsKeyDown(Keys.Down)) { fighter.PositionY-=0.2f; } //ベースの更新 base.Update(gameTime); } //描画 protected override void Draw(GameTime gameTime) { //背景色 graphics.GraphicsDevice.Clear(Color.CornflowerBlue); //フィギュアの描画 fighter.Draw(camera); //ベースの描画 base.Draw(gameTime); } } }