博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

梦想成真 XNA (1) - Hello XNA

Posted on 2011-06-23 08:45  webabcd  阅读(8623)  评论(9编辑  收藏

[索引页]
[源码下载] 


梦想成真 XNA (1) - Hello XNA



作者:webabcd


介绍
XNA: 从 Hello XNA 开始


示例
1、为了方便在一个 XNA 程序里演示各种知识点,所以写了如下代码,通过键盘按键加载对应的 Demo
Game1.cs

/*
 * 项目上单击右键 -> 属性 -> XNA Game Studio,其中可以选择 HiDef 标准或 Reach 标准
 *     HiDef 标准 - 全集(一般用于 Xbox 360 或 GPU 可支持 DirectX 10 以上的 PC)
 *     Reach 标准 - HiDef 的子集,用于显卡不济时(一般用于 Windows Phone 手机)
 */

using System;
using System.Collections.Generic;
using System.Linq;
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.Media;

using XNA.Component.Sprite;

namespace XNA
{
    // 启动时先 Initialize,再 LoadContent,退出时 UnloadContent
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        // 图形设备(显卡)管理器,XNA 在游戏窗口上做的所有事情都要通过此对象
        GraphicsDeviceManager _graphics;

        // 快捷键及其对应的 Demo 类全名的关系字典
        Dictionary<Keys, string> _demos;

        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            _graphics.PreferredBackBufferWidth = 1280; // 游戏窗口的宽
            _graphics.PreferredBackBufferHeight = 720; // 游戏窗口的高

            // Content.RootDirectory - 编译后,内容资源的保存路径
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            // 显示鼠标指针(默认值为 false)
            // this.IsMouseVisible = true;

            // 每一个 Demo 演示都对应一个按键,按对应的按键即可加载对应的 Demo
            _demos = new Dictionary<Keys, string>();
            _demos.Add(Keys.A, "XNA.Component.Sprite.Hello");
            _demos.Add(Keys.B, "XNA.Component.Sprite.DrawDemo");
            _demos.Add(Keys.C, "XNA.Component.Sprite.DrawString");
            _demos.Add(Keys.D, "XNA.Component.Sprite.SpriteSortModeDemo");
            _demos.Add(Keys.E, "XNA.Component.Sprite.BlendStateDemo");
            _demos.Add(Keys.F, "XNA.Component.Sprite.Animation");
            _demos.Add(Keys.G, "XNA.Component.Sprite.AnimatingSprite");
            _demos.Add(Keys.H, "XNA.Component.Control.KeyboardControl");
            _demos.Add(Keys.I, "XNA.Component.Control.MouseControl");
            _demos.Add(Keys.J, "XNA.Component.Control.GamePadControl");
            _demos.Add(Keys.K, "XNA.Component.Audio.XACT");
            _demos.Add(Keys.L, "XNA.Component.Audio.SoundEffectDemo");
            _demos.Add(Keys.M, "XNA.Component.Audio.SongDemo");
            ...
            ...
            ...
            ...
            ...
            ...
            ...
            ...

            base.Initialize();
        }

        protected override void LoadContent()
        {

        }

        protected override void UnloadContent()
        {

        }

        private Keys _prevKey = Keys.None;
        protected override void Update(GameTime gameTime)
        {
            IGameComponent component;
            // 获取当用户的按键信息
            Keys[] keys = Keyboard.GetState().GetPressedKeys();

            if (keys.Length > 0 && keys[0] != _prevKey)
            {
                // 加载用户按键所对应的 Demo
                if (_demos.ContainsKey(keys[0]))
                {
                    component = (IGameComponent)Activator.CreateInstance(Type.GetType(_demos[keys[0]]), this);
                    Components.Clear();
                    Components.Add(component);
                }

                _prevKey = keys[0];
            }

            // 在 base.Update(gameTime) 中的其中一个逻辑就是调用 Components 集合中的所有 IGameComponent 对象的 Update() 方法
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);
        }
    }
}



2、Hello XNA(按键盘 A 键加载此 Demo)
Component/Sprite/Hello.cs

using System;
using System.Collections.Generic;
using System.Linq;
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.Media;

namespace XNA.Component.Sprite
{
    // 启动时先 Initialize,再 LoadContent,退出时 UnloadContent
    public class Hello : Microsoft.Xna.Framework.DrawableGameComponent
    {
        // 精灵绘制器
        SpriteBatch _spriteBatch;

        // 2D 纹理对象
        Texture2D _texture2D;

        public Hello(Game game)
            : base(game)
        {
            
        }

        /// <summary>
        /// 游戏运行前的一些初始化工作
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// 加载游戏所需用到的资源,如图像和音效等
        /// </summary>
        protected override void LoadContent()
        {
            // 实例化 SpriteBatch
            _spriteBatch = new SpriteBatch(Game.GraphicsDevice);

            /*
             * 解决方案中的 XNAContent 项目为内容管道(Content Pipeline),其用于管理如图像、音乐之类的游戏资源
             * 每一个资源文件的属性中的 Asset Name 字段用于标识其在内容管道中的资源名称(没有文件扩展名,同文件夹内不能同名)
             * 本质上,内容管道会把诸如 .jpg .png .mp3 之类的游戏资源文件在编译时转换成一种 XNA 很容易使用的内部格式
             */

            // 将图片 Image/Son 加载到 Texture2D 对象中
            _texture2D = Game.Content.Load<Texture2D>("Image/Son");
        }

        /// <summary>
        /// 手工释放对象,游戏退出时会自动调用此方法
        /// 注:XNA 会自动进行垃圾回收
        /// </summary>
        protected override void UnloadContent()
        {
            
        }

        /// <summary>
        /// Draw 之前的逻辑计算
        /// </summary>
        /// <param name="gameTime">游戏的当前时间对象</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        /// <summary>
        /// 在游戏窗口上进行绘制
        /// </summary>
        /// <param name="gameTime">游戏的当前时间对象</param>
        public override void Draw(GameTime gameTime)
        {
            // 清除游戏窗口上的所有对象,然后并以 CornflowerBlue 颜色作为背景
            Game.GraphicsDevice.Clear(Color.CornflowerBlue);

            // SpriteBatch.Draw() - 用于绘制图像,其应在 SpriteBatch.Begin() 和 SpriteBatch.End() 之间调用
            _spriteBatch.Begin();
            _spriteBatch.Draw(_texture2D, new Vector2((Game.Window.ClientBounds.Width - _texture2D.Width) / 2, (Game.Window.ClientBounds.Height - _texture2D.Height) / 2), Color.White);
            _spriteBatch.End();

            base.Update(gameTime);
        }
    }
}



OK 
[源码下载]