第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 sprites 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 sprites 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();
}
}
}
}