学习XNA游戏编程1:初识

     大四入学有三天了,由于企业实习和毕业设计的考虑,我打算把毕业设计方向放在XNA游戏编程上,语言为C#,之前的远期打算在这俩月要稍微改下,本月读完《学习XNA游戏编程》这本从图书馆借的书, 并且确定这个打算和毕业设计的设计思路。

     以下开始XNA学习--初始:

      xna是我这些天才了解到的一个游戏开发平台,是微软为游戏开发者开发XBOX360,window phone7系统手机游戏的软件,当然也可以在pc上开发,这也是我的方向。初步翻了一下书,比Directx简单些。。。开发工具为XNA GAME Studio 4.0,VS2010。

     这里忽略安装,直接跳到XNA4.0上,需要注意的是它的两种配置:Reach和Hidef。Hidef为高端硬件设计,Reach为支持更大范围硬件设备而设计(即对硬件要求相对低),Reach为Hidef的配置子集,会牺牲些较强大的图形API。

          一:建立第一个XNA应用程序

    打开VS2010,新建项目->VIsualC#->XNA Game Studio 4.0->Windows Game(4.0),以下为初始代码:

 

//Game1.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 XNA1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}


    初始代码提供了2个类级变量:1.GraphicDerviceManager(图形设备管理?直译。。),使开发人员能访问PC,XBOX360,Window Phone7设备,它的一个GraphicDevice属性,代表机器上的实际图形设备,在屏幕上做的任何事情都是通过该对象进行。2.SpriteBatch:是用来绘制精灵的核心对象("精灵":能集成到更大场景中的2D或3D图像)。1个Game1构造器:其中包含了主函数。5个其他方法:1.Initialize:用于初始化变量以及与Game1对象相关的其他对象,将图像设备对象实例化。2.LoadContent:加载游戏图形内容中的各种资源(图片,模型,声音等)。3和4:游戏循环中的Update和Draw,Draw方法中只涉及重绘,Update负责其他的所有操作(移动对象,检查碰撞,更新数据和逻辑等等)。5.UnloadContent:退出循环,卸载加载过的内容等。
    XNA4.0中,内容项目名称为XNA1Content(Content)文件,存放所有资源(图片,声音,模型),LoadContent方法中调用它们。
    之后编译运行该项目只会出现一个蓝色背景的窗口.

       二.为项目添加精灵

    第一步在XNA1Content(Content)中新建Images文件夹,右键该文件夹,添加现有项,加载你要加载的图片。出现logo.png(我选的图片名),右键查看属性:Assert Name是以后加载时要加载的资源名称(为logo)。
    第二:现在图片已经被内容管道识别,首先将资源加载到变量中,图片的默认对象为Texture2D:

Texture2D   texture;

    第三:然后加载对象,在LoadContent方法中使用ContentManager类的Load方法:

texture = Content.Load<Texture2D>(@"Images/logo");


    其中@符号造成后续的字符串按照字面意思解释,而不是解释成转义序列。以下两种代码相同:

 

string str1 = @"images\logo"; 
string str2 = "images\\logo";


    第四步绘制到屏幕上,在Deaw方法中添加以下代码:

spriteBatch.Begin();
spriteBatch.Draw(texture,Vector2.Zero,Color.White);
spriteBatch.End();


 通过spriteBatch对象的Begin和End调用,XNA告诉图形设备准备向它发送一个精灵。Draw调用了三个函数:

texture        Texture2D          Texture2D对象容纳想要绘制的图片文件
position       Vector2            图片起始绘制位置(2D座标),总是从图片左上角开始绘制
color          Color              给图片染什么颜色,White表明不染色


    Vector2.Zero代表X和Y座标都为0,等同于new Vector2(X,Y)。
    启动调试后将发现图片出现在屏幕的左上角。
    另外查询Game类的Window.ClientBounds属性,获得窗口信息:

Window.ClientBounds.X\Y             对应窗口游戏的左上角位置
Window.ClientBounds.Width\Height    对应窗口的宽和高


    Texture2D的Width和Height属性,代表图片的宽和高,如下在窗口中心显示图片:

spriteBatch.Draw(texture,new Vector2((Window.ClientBounds.Width/2)-(texture.Width/2),(Window.ClientBounds.Height/2)-(texture.Height/2)),Color.White);
 

    三.透明度

    有两种方法可以透明渲染图片某些部分:1.图片文件本身包含透明背景(- -!);2.图片中希望透明的部分设置成紫红色(即255,0,255),XNA会自动将这种颜色渲染成透明。透明设置可以保存到利用alpha通道的特定文件格式中(如.png),这些格式不仅包含RGB的值,相反,每个像素都有一个额外的alpha通道(RGBA中的A)来决定像素透明度(不太懂。。。)
    SpriteBatch.Draw方法的一个重载版本,参数:

Texture              Texture2D          要绘制的纹理
Position             Vector2            图片起始位置
SourceRectangele     Rectangle          允许只绘制图片一部分,NULL为全绘
Color                Color              图片染什么颜色
Rotation             float              旋转图片。0为不旋转
origin               Vector2            指定旋转参照点
Scale                float              改变图片的比例。1为原大小
Effects              SpriteEffects      使用SpriteEffects枚举来水平后垂直翻转图片。SpriteEffects.None为不变SpriteEffects.FlipHorizontally是图片水平翻转
LayerDepth           float              层深度。范围0-1


       四.层深度


    图片的叠加顺序成为图片的Z次序或者层深度。XNA默认在之前绘制图片的顶部绘制新图片。
    SpriteBatch.Draw的重载版本最后一个参数可以设置层深度,范围0-1.0。要想按照层深度方式叠加图片,需要设置SpriteBatch.Begin的参数,如下:

SpriteSortMode       定义精灵的排序模式,有下面5种:
                     1.Deferred:(延缓)不考虑深度,越早调用Draw的越早绘制。(默认值)
                     2.Immediate:(立即)调用完draw后马上绘制。
                     3.Texture:(材质)与Deferred一样,但是对于相同深度不互相重叠的情况效率更高。
                     4.BackToFront:(从后向前)越晚调用Draw方法的越早绘制,如果有设置深度的话0是前面 1时后面,数字大得先画,深度优先权大于被调用的顺序。
                     5.FrontToBack:(从前向后)与BackToFront正好相反,越早调用Draw的越早绘制。
BlendState           决定精灵颜色如何和背景颜色混合,有四种:
                     1.AlphaBlend:(透明度混合)是将来源的Alpha作为来源混合参数,将1-Alpha作为目标混合参数。
                     2.Additive:(添加混合)是将来源的混合参数和目标的混合参数都设置成1,这样混合白色会没有变化,其他的颜色看上去会更加明亮,黑色会更加明亮				如图1,DNF的魔法阵周遍是完全的黑色所以想过是直接显示了底层的ELLY图片。这要求美工作出的图片必须符合要求。
                     3.NonPremultiplied:使用alpha混合来源和目标数据,同时假设颜色数据不包含alpha信息。
                     4.Opaque:目标数据覆盖来源数据。


如果有透明背景图片,要求绘图时按照较小层深度值对象先绘制的方法。设定为:

spriteBatch.Begin(spriteSortMode.FrontToBack,BlendState.AlphaBlend);


      五.本书附带例子

    一个动态的三星,这里不赘述,源码放后边。

     http://download.csdn.net/detail/asd77882566/4533979

       六.调整帧频

    XNA默认以60fps的帧频绘制,可以再Game1构造器末尾添加以下代码来改变帧速:

TargetElapsedTime = new TimeSpan(0,0,0,0,50);//以50毫秒调用一次Game.Update,即帧频20fps。



    XNA提供了了检测游戏是否存在性能问题的途径。作为Update和Draw方法的参数传递的GameTime对象有一个Boolean类型的IsRuningSlowly属性,如果返回true,则表明XNA无法跟上指定的帧频,此时XNA会跳过一些Draw调用以期保持你希望的速度。

       七.调整动画速度

    调整特定精灵动画速度,在动态三星例子中只是单独对那个精灵进行调整:

int timeSinceLaseFrame = 0;              //跟踪动画帧改变后过了多长时间
int millisecondsPerFrame = 50;            //指定要过多长时间才改变当前帧索引


    update方法中:

timeSinceLaseFrame += gameTime.ElapsedGameTime.Milliseconds;
if(timeSinceLastFrame > millisecondsPerFrame)
{
	timeSinceLastFrame -= millisecondsPerFrame;
        ++currentFrame.X;
        if(currentFrame.X == sheetSize.X)
	{
		currentFrame.X = 0;
                ++currentFrame.Y;
		if(currentFrame.Y == sheetSize.Y)
			currentFrame.Y = 0;
	}
}
 //   这个代码不好太理解。。


 

OVER
发布了25 篇原创文章 · 获赞 41 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章