编写第一个XNA游戏

本文将引导你使用XNA Game Studio Express一步一步地创建一个简单的游戏 

第1步: 安装软件 
第2步: 创建新项目 
第3步: 查看代码 
第4步: 加入一个精灵 
第5步: 使精灵可以移动和弹跳 
第6步: 继续尝试! 
完整的实例 

第1步: 安装软件
在动手之前,先确定你已经安装了所需的软件,其中包括August 2006 DirectX SDK.参见所需软件 中的软件列表. 

第2步:创建新项目
从开始菜单中启动Microsoft Visual C# 2005 Express Edition. 
在Microsoft Visual C# 2005 Express Edition 起始页面出现后,点击文件(File)菜单, 然后选择新项目( New Project). 
当出现对话框的时候, 选择Windows Game (XNA) 类型的项目,输入工程名称,点击OK. 
创建新项目以后,你会看到设计器视图和它的组件.至此,你的游戏中只有一个被标记为graphics的GraphicsComponent组件.

点击文件菜单(File )-保存全部(Save All). 
输入保存工程的路径,这个路径也是你向游戏中加入图象及其他资源的时候的路径.保存完毕将返回设计视图. 
第3步:查看代码
一些复杂的工作已经为你做好.如果你现在编译并运行你的游戏, GraphicsComponent组件将为你处理设置屏幕大小,渲染出一个空白屏幕的这些工作. 你的游戏会自动的运行和更新. 你得加入自己的代码来使游戏更有趣一些. 要查看代码,只要在灰色的设计面板中的任意地方双击就可以了,或者在解决方案浏览器中右键点击"Game1.cs",选择查看代码(View Code)

你将会看到已经为你写好的代码: 一个简单的Update循环和一个简单的 Draw循环; 你可以在任一个循环中加入你的代码. 

Update 循环是你对游戏逻辑进行更新的最佳场所:移动对象,接收玩家输入,决定对象之间碰撞的结果,等等... 
Draw 循环是你渲染对象和屏幕背景的一个最佳的场所. 
第4步:加入一个精灵
下一步就是给屏幕上加入一个可见的图象,使用一个小的图象文件,比如.bmp或者.jpg,你也可以自己制作图形,这样就更具有创造性了.

你甚至可以制作不规则图象-比如让边缘和拐角的地方不要显示,这样看起来效果会更好,可以参见例子:怎样制作带有遮掩的纹理图..

当你有了图形文件以后,你可以按照下面的步骤把它拷贝到你的项目的文件夹里面:

右键单击解决方案资源管理器, 点击添加(Add), 再点击已有项(Existing Item).查找你的图象文件并且选中它.解决方案资源管理器中将为这个图象文件增加一项. 
点击该项.在解决方案资源管理器下面的属性(Properties)面板中找到"拷贝到输出目录"(Copy To Output Directory)项,把它的值设置为"总是拷贝"(Copy always).这将保证图象文件对你编译生成的游戏程序来说总是可用的. 
现在,你必须编写加载精灵,以及在屏幕上显示精灵的代码.你可以使用 怎样绘制一个精灵中给出的代码或者按照这里所讲的方式来写. 

回到代码查看视图,找到你的Game1类,在构造函数的后面加入如下的这些代码.

C#  
//this is a texture we can render
Texture2D myTexture;
//coordinates to draw the sprite at
int spriteX = 0;
int spriteY = 0;
//this is the object that will draw the sprites
SpriteBatch spriteBatch;

protected override void OnStarting()
{
    base.OnStarting();
    graphics.GraphicsDevice.DeviceReset += new EventHandler(GraphicsDevice_DeviceReset);
    LoadResources();
    
}

void GraphicsDevice_DeviceReset(object sender, EventArgs e)
{
    LoadResources();
}

void LoadResources()
{
    myTexture = Texture2D.FromFile(graphics.GraphicsDevice, "mytexture.bmp");
    spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
}
 

请确保在调用Texture2D.FromFile 的时候使用了你刚加入的精灵.以上这些代码加载你的图象,做好画图前的准备,并且将会在图象设备被重新复位的时候重新加载进来(比如,当游戏窗口大小改变的时候)

现在,给Draw 循环中加入代码,使它看起来像这样: 
C#  
protected override void Draw()
{
    if (!graphics.EnsureDevice())
    {
        return;
    }

    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    graphics.GraphicsDevice.BeginScene();
    
    // TODO: Add your drawing code here

    spriteBatch.Begin();
    spriteBatch.Draw(myTexture, new Rectangle(spriteX, spriteY, myTexture.Width, myTexture.Height), Color.White);
    spriteBatch.End();

    // Let the GameComponents draw
    DrawComponents();

    graphics.GraphicsDevice.EndScene();
    graphics.GraphicsDevice.Present();
}
 

这些代码在每帧显示的时候在屏幕上绘制精灵.

编译并运行你的游戏,精灵显示出来了.现在,是时候该让它动起来了. 
第5步: 使精灵可以移动和弹跳
修改你的Update 函数,让它看起来像下面这样:

C#  
//store some info about the sprite's motion
int m_dSpriteHorizSpeed = 1;
int m_dSpriteVertSpeed = 1;

protected override void Update()
{
    // The time since Update was called last
    float elapsed = (float)ElapsedTime.TotalSeconds;

    // TODO: Add your game logic here
    //move the sprite around
    UpdateSprite();

    // Let the GameComponents update
    UpdateComponents();
}

void UpdateSprite()
{
    //move the sprite by speed
    spriteX += m_dSpriteHorizSpeed;
    spriteY += m_dSpriteVertSpeed;

    int MaxX = Window.ClientWidth - myTexture.Width;
    int MinX = 0;
    int MaxY = Window.ClientHeight - myTexture.Height;
    int MinY = 0;

    //check for bounce
    if (spriteX > MaxX)
    {
        m_dSpriteHorizSpeed *= -1;
        spriteX = MaxX;
    }
    else if(spriteX < MinX)
    {
        m_dSpriteHorizSpeed *= -1;
        spriteX = MinX;
    }

    if (spriteY > MaxY)
    {
        m_dSpriteVertSpeed *= -1;
        spriteY = MaxY;
    }
    else if (spriteY < MinY)
    {
        m_dSpriteVertSpeed *= -1;
        spriteY = MinY;
    }
}
 

这给程序中加入了一点可以让精灵每帧都移动的逻辑,还能让精灵在碰到游戏窗口边缘的时候改变方向.

第6步:继续尝试!
到此为止,你可以做任何想做的尝试了,比如像这里给出的这些点子:

加入第2个精灵,使用BoundingBox对象来使得精灵之间可以相互碰撞. (请参阅 如何检测两个对象是否碰撞) 
使得精灵可以根据 键盘, 鼠标, 或者 游戏手柄 的输入来移动. (请参阅输入概述) 
创建一些声音事件,使得精灵移动的时候发声(请参阅如何给把声音文件加入到游戏以及怎样播放声音) 

使用简单的3D模型来取代精灵,在3D空间中环游(参见 怎样绘制简单的3D模型) 

完整的实例
C#  
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Components;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

namespace MyFirstXNAGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    partial class Game1 : Microsoft.Xna.Framework.Game
    {
        public Game1()
        {
            InitializeComponent();
        }
        //this is a texture we can render
        Texture2D myTexture;
        //coordinates to draw the sprite at
        int spriteX = 0;
        int spriteY = 0;
        //this is the object that will draw the sprites
        SpriteBatch spriteBatch;

        protected override void OnStarting()
        {
            base.OnStarting();
            graphics.GraphicsDevice.DeviceReset += new EventHandler(GraphicsDevice_DeviceReset);
            LoadResources();
            
        }

        void GraphicsDevice_DeviceReset(object sender, EventArgs e)
        {
            LoadResources();
        }

        void LoadResources()
        {
            myTexture = Texture2D.FromFile(graphics.GraphicsDevice, "mytexture.bmp");
            spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
        }

        //store some info about the sprite's motion
        int m_dSpriteHorizSpeed = 1;
        int m_dSpriteVertSpeed = 1;

        protected override void Update()
        {
            // The time since Update was called last
            float elapsed = (float)ElapsedTime.TotalSeconds;

            // TODO: Add your game logic here
            //move the sprite around
            UpdateSprite();

            // Let the GameComponents update
            UpdateComponents();
        }

        void UpdateSprite()
        {
            //move the sprite by speed
            spriteX += m_dSpriteHorizSpeed;
            spriteY += m_dSpriteVertSpeed;

            int MaxX = Window.ClientWidth - myTexture.Width;
            int MinX = 0;
            int MaxY = Window.ClientHeight - myTexture.Height;
            int MinY = 0;

            //check for bounce
            if (spriteX > MaxX)
            {
                m_dSpriteHorizSpeed *= -1;
                spriteX = MaxX;
            }
            else if(spriteX < MinX)
            {
                m_dSpriteHorizSpeed *= -1;
                spriteX = MinX;
            }

            if (spriteY > MaxY)
            {
                m_dSpriteVertSpeed *= -1;
                spriteY = MaxY;
            }
            else if (spriteY < MinY)
            {
                m_dSpriteVertSpeed *= -1;
                spriteY = MinY;
            }
        }
        protected override void Draw()
        {
            if (!graphics.EnsureDevice())
            {
                return;
            }

            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
            graphics.GraphicsDevice.BeginScene();
            
            // TODO: Add your drawing code here

            spriteBatch.Begin();
            spriteBatch.Draw(myTexture, new Rectangle(spriteX, spriteY, myTexture.Width, myTexture.Height), Color.White);
            spriteBatch.End();

            // Let the GameComponents draw
            DrawComponents();

            graphics.GraphicsDevice.EndScene();
            graphics.GraphicsDevice.Present();
        }
    }
}
using System;

namespace MyFirstXNAGame
{
    partial class Game1
    {
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.graphics = new Microsoft.Xna.Framework.Components.GraphicsComponent();

            this.GameComponents.Add(this.graphics);

        }

        private Microsoft.Xna.Framework.Components.GraphicsComponent graphics;
    }
}
using System;

namespace MyFirstXNAGame
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            using (Game1 game = new Game1())
            {
                game.Run();
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值