▼XNA Game Studioメモ▼
ゲームの作成


前方から接近する隕石を避け続けた時間を競うゲーム「SpaceChace」を作成する。




方向キー 戦闘機の移動
Enterキー ゲーム開始
Spaceキー 視点変更


リソースの追加
  1. 戦闘機と隕石の3DモデルをソリューションエクスプローラのContentにドラッグ&ドロップ。
  2. はじめてのXNAアプリの作成」で作成したフォントプロセッサ「DefaultFont.spritefont」をソリューションエクスプローラのContentに追加する。
ソースコードの編集
  1. モデルの移動で利用したCameraクラスとFigureクラスを追加。
  2. 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 {
        //定数
        public readonly int S_PLAY    =0;//プレイ
        public readonly int S_GAMEOVER=1;//ゲームオーバー

        //システム
        private GraphicsDeviceManager graphics;   //グラフィックス
        private SpriteBatch           spriteBatch;//スプライトバッチ
        private SpriteFont            font;       //フォント

        //フィギュア
        private Camera   camera; //カメラ
        private Figure   fighter;//戦闘機
        private Figure[] rock;   //岩
                
        //ゲーム
        private int  init;        //初期化
        private int  scene;       //シーン
        private int  score;       //スコア
        private int  cameraMode;  //カメラモード
        private bool spaceKeyDown;//スペースキーダウン

        //コンストラクタ
        public Game() {
            graphics=new GraphicsDeviceManager(this);
            Content.RootDirectory="Content";
        }

        //初期化
        protected override void Initialize() {
            //描画間隔の指定
            IsFixedTimeStep=true;
            TargetElapsedTime=new TimeSpan(200000);
            
            //ベースの初期化
            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);
            camera.PositionZ=20;
            camera.PositionZ=10;
            camera.PositionY=-10;
            camera.Pitch=(float)Math.PI/4;
            cameraMode=1;
            spaceKeyDown=false;
            
            //戦闘機の生成
            fighter=new Figure(Content.Load<Model>("fighter")); 
            fighter.RotateX=MathHelper.ToRadians(-90.0f);
            fighter.RotateY=MathHelper.ToRadians(180.0f);
            fighter.PositionY=-4.0f;

            //岩の生成
            Model model=Content.Load<Model>("rock");
            rock=new Figure[30];
            for (int i=0;i<rock.Length;i++) {
                rock[i]=new Figure(model); 
                rock[i].Scale=new Vector3(0.5f,0.5f,0.5f);
            }

            //初期化
            init=S_PLAY;
        }

        //グラフィクスコンテントの解放
        protected override void UnloadContent() {
        }

        //更新
        protected override void Update(GameTime gameTime) {
            //キー状態
            KeyboardState keyState=Keyboard.GetState();

            //初期化
            if (init>=0) {
                if (init==S_PLAY) {
                    fighter.PositionX=0.0f;
                    fighter.PositionY=-4.0f;
                    for (int i=0;i<rock.Length;i++) {
                        rock[i].PositionX=(Rand(140)/10.0f)-7.0f;
                        rock[i].PositionY=10.0f+Rand(500)/10.0f;
                    }
                }
                scene=init;
                init=-1;
            }

            //プレイ
            if (scene==S_PLAY) {
                //スコアの加算
                score++;
                                
                for (int i=0;i<rock.Length;i++) {
                    //岩の移動
                    rock[i].PositionY-=0.3f;
                    if (rock[i].PositionY<-20.0f) {
                        rock[i].PositionX=(Rand(160)/10.0f)-8.0f;
                        rock[i].PositionY=10.0f+Rand(500)/10.0f;
                    }

                    //ゲームオーバー判定
                    if (IsHit(fighter.PositionX,fighter.PositionY,
                        rock[i].PositionX,rock[i].PositionY)) {
                        init=S_GAMEOVER;
                    }
                }
                
                //キー操作
                if (keyState.IsKeyDown(Keys.Left)) {
                    if (fighter.PositionX>-7.0f) fighter.PositionX-=0.2f;
                } else if (keyState.IsKeyDown(Keys.Right)) {
                    if (fighter.PositionX< 7.0f) fighter.PositionX+=0.2f;
                } else if (keyState.IsKeyDown(Keys.Up)) {
                    if (fighter.PositionY<10.0f) fighter.PositionY+=0.2f;
                } else if (keyState.IsKeyDown(Keys.Down)) {
                    if (fighter.PositionY>-8.0f) fighter.PositionY-=0.2f;
                }
            }
            //ゲームオーバー
            else if (scene==S_GAMEOVER) {
                //キー操作
                if (keyState.IsKeyDown(Keys.Enter)) {
                    init=S_PLAY;
                }
            }
            //カメラモード
            if (keyState.IsKeyDown(Keys.Space) && !spaceKeyDown) {
                if (cameraMode==0) {
                    camera.PositionZ=10;
                    camera.PositionY=-10;
                    camera.Pitch=(float)Math.PI/4;
                    cameraMode=1;
                } else {
                    camera.PositionZ=20;
                    camera.PositionY=0;
                    camera.Pitch=0;
                    cameraMode=0;
                }
            }
            spaceKeyDown=keyState.IsKeyDown(Keys.Space);
            
            //ベースの更新
            base.Update(gameTime);
        }

        //岩の衝突判定
        private bool IsHit(float x0,float y0,float x1,float y1) {
            return (x0-x1)*(x0-x1)+(y0-y1)*(y0-y1)<1.0f;
        }

        //描画
        protected override void Draw(GameTime gameTime) {
            //背景色
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            //フィギュアの描画
            fighter.Draw(camera);
            for (int i=0;i<rock.Length;i++) {
                rock[i].Draw(camera);
            }

            //2D描画
            spriteBatch.Begin();
            DrawString("SCORE "+score,0,0);
            if (scene==S_GAMEOVER) {
                DrawString("G A M E  O V E R",
                    (int)(800.0f-font.MeasureString(
                    "G A M E  O V E R").X)/2,140);
            }
            spriteBatch.End();

            //ベースの描画
            base.Draw(gameTime);
        }

        //文字列の描画
        private void DrawString(String str,int x,int y) {
            spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
        }

        //乱数の取得
        private Random random=new Random();
        private int Rand(int num) {
            return random.Next(num);
        }     
    }
}



−戻る−