▼XNA Game Studioメモ▼
モデルの移動


モデルの平行移動を行うプログラムを作成する。方向キーで上下左右への移動を行う。



リソースの追加
  1. 戦闘機の3DモデルをソリューションエクスプローラのContentにドラッグ&ドロップ。
Cameraクラスの作成
視点ごとに保持する情報をまとめたCameraクラスを作成。
保持する情報は次の通り。 Camera.csを次のように編集。
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を次のように編集。
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);
        }
    }
}



−戻る−