摘要:我的第一個xna程式!
我們先從簡單的2D遊戲開始學起,首先就先來研究如何在畫面上貼圖。
下面是產生新專案後所生出的程式碼,若我們直接按F5編譯程式的話,會跑出一個藍色背景的視窗。
02
03 public class Game1 : Microsoft.Xna.Framework.Game {
04 GraphicsDeviceManager graphics;
05 SpriteBatch spriteBatch;
06
07 public Game1() {
08 graphics = new GraphicsDeviceManager(this);
09 Content.RootDirectory = "Content";
10 }
11
12 protected override void Initialize() {
13 // TODO: Add your initialization logic here
14
15 base.Initialize();
16 }
17
18 protected override void LoadContent() {
19 // Create a new SpriteBatch, which can be used to draw textures.
20 spriteBatch = new SpriteBatch(GraphicsDevice);
21
22 // TODO: use this.Content to load your game content here
23 }
24
25
26 protected override void UnloadContent() {
27 // TODO: Unload any non ContentManager content here
28 }
29
30
31 protected override void Update(GameTime gameTime) {
32 // Allows the game to exit
33 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
34 this.Exit();
35
36 // TODO: Add your update logic here
37
38 base.Update(gameTime);
39 }
40
41
42 protected override void Draw(GameTime gameTime) {
43 GraphicsDevice.Clear(Color.CornflowerBlue);
44
45 // TODO: Add your drawing code here
46
47 base.Draw(gameTime);
48 }
49 }
50 }
第7行是建構子,他首先取得繪圖裝置,以後要畫圖的話就是透過此裝置,而xna已經將比較底層的工作都幫你做好了,所以不像以前直接用DX9那樣還要自己註冊。另外第9行是設定Content的目錄位置,原則上我們會把遊戲需要用到的圖形、模型、聲音等資源放在Content目錄內,因此幾乎用不著改他。
接著第12行是遊戲的初始化,非圖形的物件或資料通常在這裡載入,而呼叫base.Initialize()函式會呼叫component的初始化函式,關於component這裡還用不到,以後再說!
第18行就是用來載入圖形或模型等資料的地方,而第26行就是把這些載入的資源釋放掉。
31行和42行可以說是遊戲最重要的兩的函式,Update用來作邏輯處理,像是物體的移動、碰撞、改變狀態、輸入控制等事情都在這裡做,而Draw函式就是負責把圖畫出來。
預設的xna專案會是60FPS的,也就是一秒鐘畫面更新60次,電腦會固定在1/60秒呼叫一次draw和update,若是draw在1/60秒無法處理完成,會優先再度叫用update,讓時間趕上之後再呼叫draw,
這樣畫面會出現延遲,但是不會變成慢動作,一秒鐘該走的距離還是一樣,xna也有可能會自動將fps降到30。但若是update來不及,那就很慘了,雖然不會都不呼叫draw,但是你應該會玩不下去。
介紹完這五個主要的函式後,讓我們是著在畫面貼上我們的圖,首先在Content目錄加入我們想要顯示的圖(如下圖)
這裡我加入一個圖形名稱為msd_a01.jpg,基本上我們常用的圖檔格式xna都支援像是jpg、bmp、png。加好圖形後,我們在圖形上按右鍵選擇Properties,會出現下面的屬性選單
第一個選項表示xna會把這張圖編碼成xnb檔,第二個表示不會將jpg圖複製到專案編譯後的目錄內,第三、四個是圖檔的名稱及路徑。
Asset Name是個重點,他表示xna將圖編譯成xnb檔之後的名稱,在LoadContent載入此圖時就要用這個名稱,此名稱在整個專案中不能重複。最後兩個就是編譯的方式,目前不要改他。
將圖案加入專案後,讓我們來看看程式要怎麼寫
02
03 protected override void LoadContent() {
04 spriteBatch = new SpriteBatch(GraphicsDevice);
05 myImage = Content.Load<Texture2D>("msn_a01");
06 }
07
08 protected override void UnloadContent() {
09 myImage.Dispose(); //釋放物件
10 }
11
12 protected override void Draw(GameTime gameTime) {
13 GraphicsDevice.Clear(Color.CornflowerBlue);
14
15 spriteBatch.Begin();
16 spriteBatch.Draw(myImage, Vector2.Zero, Color.White);
17 spriteBatch.End();
18
19 base.Draw(gameTime);
20 }
在原本的專案中加入第一行的物件,此Texture2D物件是2d的圖形物件,這裡用來存放我們將要載入的圖片。
而在LoadContent 內,第四行是用繪圖裝置產生一個SpriteBatch,這個物件負責一些畫圖的設定、畫法等功能,加入第五行程式碼,Content物件是用來載入我們放在Content目錄下的東西,其Load是一個泛型函式,角括號是要載入的物件型態,我們的圖片是2D的圖,所以用Texture2D。載入後的圖將會設定給myImage。
最後我們在Draw函式中將此圖畫出來,第13行是將繪圖裝置用一種顏色清空,目前的繪圖裝置當然就是只螢幕囉,所以一開始執行專案時,螢幕才會是藍色。
我們要真正繪圖時,必須將SpriteBatch.Draw函式用SpriteBatch.Begin和SpriteBatch.End包起來,他有幾種多載,這裡先用最簡單的,之後在中間的Draw函式將此圖畫出來,第一個參數是要畫的圖,第二個是顯示的位置,是一個二維座標,最後是顏色遮照,不想讓他變色的話就用白的!
下面是執行程式後的畫面
在電腦螢幕的座標系和一般我們數學教的座標方向有點不一樣,螢幕的座標左上角是(0,0),x軸往右為正,y軸往下為正,一般而言原點都是左上角,我們第二個參數是呼叫Vector2.Zero,他是產生一個(0,0)的向量,所以此圖形會長在畫面的左上角。
你可以改變此向量,例如改成new Vector2(150,100),他就會將圖形畫在距離視窗左上角右邊150像素、往下100像素的地方。
既然如此,我們就知道要如何讓圖形移動了,先在Game1內加上一Vector2 position ,接著在update函式內加上移動的方式
然後將draw函式的位置參數改成position,程式如下:
02 int stepX = 1;
03
04 protected override void Update(GameTime gameTime) {
05
06 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
07 this.Exit();
08 if (position.X + myImage.Width > Window.ClientBounds.Width || position.X < 0) {
09 stepX *= -1;
10 }
11 position.X += stepX;
12
13 base.Update(gameTime);
14 }
15
16 protected override void Draw(GameTime gameTime) {
17 GraphicsDevice.Clear(Color.CornflowerBlue);
18 spriteBatch.Begin();
19 spriteBatch.Draw(myImage, position, Color.White);
20 spriteBatch.End();
21
22 base.Draw(gameTime);
23 }
此範例會移動圖片,到畫面右邊之後會反彈。
最後是此demo的專案檔!WindowsGame1.rar