大四入學有三天了,由於企業實習和畢業設計的考慮,我打算把畢業設計方向放在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;
}
}
// 這個代碼不好太理解。。