開発環境 Microsoft Visual C# 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Windows Game (4.0)
プロジェクト名 XnaWheel



Game1.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
 
namespace XnaWheel
{
    class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch sprite;
        SpriteFont font;
        BasicEffect effect;
        VertexBuffer vbSide;
        IndexBuffer ibSide;
        VertexBuffer vbTread;
        IndexBuffer ibTread;
        Texture2D texture;
 
        // fps
        int fpsSec = -1;
        int fpsDraw = 0;
        int fpsCount = 0;
 
        // カメラ
        int camLat = 0;
        int camLon = 90;
        float camDist = 3;
 
        float speed = 0;
        float angle = 0;
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }
 
        protected override void LoadContent()
        {
            sprite = new SpriteBatch(GraphicsDevice);
            font = Content.Load<SpriteFont>("SpriteFont1");
            texture = Content.Load<Texture2D>("Wheel");
 
            effect = new BasicEffect(GraphicsDevice);
            effect.Texture = texture;
            effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 0.1f, 10);
 
            GenerateSide();
            GenerateTread(32);
 
            base.LoadContent();
        }
 
        private void GenerateSide()
        {
            // 頂点
            VertexPositionTexture[] vertices = new VertexPositionTexture[8];
            vertices[0] = new VertexPositionTexture(new Vector3(-0.5f, 0.5f, 0.25f), new Vector2(0, 0));
            vertices[1] = new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0.25f), new Vector2(1, 0));
            vertices[2] = new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0.25f), new Vector2(0, 1));
            vertices[3] = new VertexPositionTexture(new Vector3(0.5f, -0.5f, 0.25f), new Vector2(1, 1));
 
            vertices[4] = new VertexPositionTexture(new Vector3(0.5f, 0.5f, -0.25f), new Vector2(0, 0));
            vertices[5] = new VertexPositionTexture(new Vector3(-0.5f, 0.5f, -0.25f), new Vector2(1, 0));
            vertices[6] = new VertexPositionTexture(new Vector3(0.5f, -0.5f, -0.25f), new Vector2(0, 1));
            vertices[7] = new VertexPositionTexture(new Vector3(-0.5f, -0.5f, -0.25f), new Vector2(1, 1));
 
            vbSide = new VertexBuffer(GraphicsDevice,
                typeof(VertexPositionTexture), vertices.Length, BufferUsage.WriteOnly);
            vbSide.SetData(vertices);
 
            // 索引
            short[] indices = new short[12];
            indices[0] = 0; indices[1] = 1; indices[2] = 2;
            indices[3] = 3; indices[4] = 2; indices[5] = 1;
            indices[6] = 4; indices[7] = 5; indices[8] = 6;
            indices[9] = 7; indices[10] = 6; indices[11] = 5;
 
            ibSide = new IndexBuffer(GraphicsDevice,
                typeof(short), indices.Length, BufferUsage.WriteOnly);
            ibSide.SetData(indices);
        }
 
        private void GenerateTread(int slices)
        {
            // 頂点
            VertexPositionColor[] vertices = new VertexPositionColor[slices * 2];
            int i = 0;
            for (int n = 0; n < slices; n++)
            {
                float rad = (float)n / slices * MathHelper.TwoPi;
                float y = (float)(Math.Cos(rad) * 0.5);
                float x = (float)(Math.Sin(rad) * 0.5);
                vertices[i++] = new VertexPositionColor(new Vector3(x, y, 0.25f), Color.Black);
                vertices[i++] = new VertexPositionColor(new Vector3(x, y, -0.25f), Color.Black);
            }
 
            vbTread = new VertexBuffer(GraphicsDevice,
                typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly);
            vbTread.SetData(vertices);
 
            // 索引
            short[] indices = new short[slices * 6];
            i = 0;
            for (int n = 0; n < slices; n++)
            {
                for (int m = 0; m < 6; m++)
                {
                    indices[i++] = (short)((n * 2 + ((m < 3) ? m : 6 - m)) % (slices * 2));
                }
            }
 
            ibTread = new IndexBuffer(GraphicsDevice,
                typeof(short), indices.Length, BufferUsage.WriteOnly);
            ibTread.SetData(indices);
        }
 
        protected override void Update(GameTime gameTime)
        {
            KeyboardState kState = Keyboard.GetState();
            if (kState.IsKeyDown(Keys.Escape)) Exit();
            if (kState.IsKeyDown(Keys.Up)) camLat = Math.Min(camLat + 1, 89);
            if (kState.IsKeyDown(Keys.Down)) camLat = Math.Max(camLat - 1, -89);
            if (kState.IsKeyDown(Keys.Left)) camLon = (camLon + 1) % 360;
            if (kState.IsKeyDown(Keys.Right)) camLon = (camLon + 359) % 360;
            if (kState.IsKeyDown(Keys.PageUp)) camDist = Math.Max(camDist - 0.1f, 0.1f);
            if (kState.IsKeyDown(Keys.PageDown)) camDist = Math.Min(camDist + 0.1f, 5);
            if (kState.IsKeyDown(Keys.X)) speed += 0.25f;
            if (kState.IsKeyDown(Keys.Z)) speed = Math.Max(speed - 0.5f, 0);
 
            angle += speed;
 
            base.Update(gameTime);
        }
 
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            // カメラ位置
            float rad = MathHelper.ToRadians(camLat);
            float y = (float)Math.Sin(rad) * camDist;
            float r = (float)Math.Cos(rad) * camDist;
            rad = MathHelper.ToRadians(camLon);
            float x = (float)Math.Cos(rad) * r;
            float z = (float)Math.Sin(rad) * r;
            effect.View = Matrix.CreateLookAt(new Vector3(x, y, z), Vector3.Zero, Vector3.Up);
 
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                // 側面
                effect.World = Matrix.CreateRotationZ(MathHelper.ToRadians(angle));
                effect.TextureEnabled = true;
                effect.VertexColorEnabled = false;
                pass.Apply();
                GraphicsDevice.SetVertexBuffer(vbSide);
                GraphicsDevice.Indices = ibSide;
                GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                    0, 0, vbSide.VertexCount, 0, ibSide.IndexCount / 3);
 
                // 接地面
                effect.World = Matrix.Identity;
                effect.TextureEnabled = false;
                effect.VertexColorEnabled = true;
                pass.Apply();
                GraphicsDevice.SetVertexBuffer(vbTread);
                GraphicsDevice.Indices = ibTread;
                GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                    0, 0, vbTread.VertexCount, 0, ibTread.IndexCount / 3);
            }
 
            // fps
            fpsDraw++;
            if (gameTime.TotalGameTime.Seconds != fpsSec)
            {
                fpsCount = fpsDraw;
                fpsDraw = 0;
                fpsSec = gameTime.TotalGameTime.Seconds;
            }
 
            // 2D描画
            sprite.Begin();
            string text = string.Format("fps={0} lat={1} lon={2} dist={3:f1}",
                fpsCount, camLat, camLon, camDist);
            sprite.DrawString(font, text, new Vector2(0, 0), Color.White);
            text = string.Format("speed={0:f1}", speed);
            sprite.DrawString(font, text, new Vector2(0, 20), Color.White);
            sprite.End();
 
            base.Draw(gameTime);
        }
    }
}
 
最終更新:2013年01月14日 16:23
添付ファイル