XNA 互動式遊戲設計

摘要

上一回我們為大家介紹了 XNA Framework 支援遊戲程式製作的重要類別,做為開發遊戲程式的基礎知識。除此之外,我們也利用所介紹的類別實作一個簡單的遊戲程式,並令其具有能夠不斷捲動的背景圖案。這一回我們將會介紹更多 XNA Framework 支援遊戲開發的類別,包括支援輸入控制,音效播放,以及背景音樂播放控制的類別等等,讓讀者能夠為所製作的遊戲程式加入更豐富的遊戲效果。

 輸入控制

遊戲程式難免需要和使用者互動,讓使用者可以藉由輸入裝置,例如鍵盤、觸控面板、滑鼠、或是遊戲控制器進行遊戲控制,與遊戲程式達到互動的效果。要讓使用者控制遊戲程式的進行,可以利用 Keyboard 類別搭配 KeyboardState 結構,利用 TouchPanel 類別搭配 TouchCollection 結構,利用 Mouse 類別搭配 MouseState 結構,或是利用 GamePad 類別搭配 GamePadState 結構,對所操作的遊戲程式進行控制。

Keyboard 類別的功能很簡單,只提供名稱為 GetState 的方法以取得使用者操作鍵盤的按鍵狀態。遊戲程式可以呼叫 Keyboard 類別的 GetState 方法取得鍵盤的狀態 (型態為 KeyboardState 結構的傳回值),以判斷使用者按了那一個鍵。KeyboardState 結構的常用屬性請參考表1 的說明:

表1:KeyboardState 結構的常用屬性
屬性名稱 說明
Item 代表鍵盤的某個按鍵的按鍵狀態

 

KeyboardState 結構的常用方法請參考表2 的說明:

表2:KeyboardState 結構的常用方法
方法名稱 說明
GetPressedKeys 取得目前所有被按下的按鍵
IsKeyDown 判斷指定的按鍵是否已被按下
IsKeyUp 判斷指定的按鍵是否已被放開

 

要判斷使用者操作滑鼠的做法和判斷使用者操作鍵盤的操作類別,遊戲程式可以先呼叫 Mouse 類別的 GetState 方法取得滑鼠的狀態 (型態為 MouseState 結構的傳回值),再透過滑鼠的狀態判斷使用者的操作動作。有關 Mouse 類別常用的方法可以參考表3 的說明:

表3:Mouse 類別常用的方法
方法名稱 說明
GetState 取得包括滑鼠座標在內的滑鼠按鍵狀態
SetPosition 設定滑鼠游標相對於遊戲視窗左上角的位置

 

MouseState 結構常用的屬性請參考表4 的說明:

表4:MouseState 結構常用的屬性
方法名稱 說明
LeftButton 滑鼠左鍵的按鍵狀態
MiddleButton 滑鼠中間鍵的按鍵狀態
RightButton 滑鼠右鍵的按鍵狀態
ScrollWheelValue 記錄從遊戲開始執行迄今,滑鼠滾輪累計的捲動距離
X 滑鼠游標的 X 座標位置
Y 滑鼠游標的 Y 座標位置

 

雖然 Windows Phone 7 智慧型手機並未配備滑鼠,但是遊戲程式還是仍然能夠使用 Mouse 類別與 MouseState 結構判斷使用者操作滑鼠的動作,其效果相當於使用者對智慧型手機進行觸控操作。GamePad 類別和 GamePadState 結構也一樣,雖然 Windows Phone 7 智慧型手機未配備遊戲控制器,但是遊戲程式仍然能夠使用 GamePad 類別和 GamePadState 結構判斷使用者操作遊戲控制器的動作,當使用者按下 Windows Phone 7 智慧型手機下緣的硬體按鍵,其效果相當於透過遊戲控制器和遊戲程式溝通。例如在使用 Visual Studio 2010 Express for Windows Phone 建立的 Windows Phone Game (4.0) 的專案中,Game1 類別的 Update 方法便會利用以下的程式碼判斷使用者是否按下智慧型手機下緣回到上一個畫面的按鍵,如果是的話,則結束遊戲程式的執行:

XML
if (GamePad.GetState(PlayerIndex.One).Buttons.Back 
== ButtonState.Pressed)		//判斷使用者是否按下回到上一個畫面的按鍵
    this.Exit();												//結束遊戲
 

GamePad 類別常用的方法可以參考表 5 的說明:

表5:GamePad 類別常用的方法
方法名稱 說明
GetCapabilities 查詢遊戲控制器支援的功能的方法
GetState 取得遊戲控制器的狀態
SetVibration 設定遊戲控制器震動馬達的速度

 

GamePadState 結構常用的屬性可以參考表6 的說明:

表6:GamePadState 結構常用的屬性
屬性名稱 說明
Buttons 取得遊戲控制器所有按鍵的狀態
DPad 取得方向指引器指引的方向
IsConnected 判斷遊戲控制器是否已連接到遊戲裝置
ThumbSticks 取得遊戲控制器的搖捍的位置
Triggers 取得遊戲控制器的觸控鈕的位置

 

GamePadState 結構常用的方法可以參考表7 的說明:

表7:GamePadState 結構常用的方法
方法名稱 說明
IsButtonDown 判斷指定的遊戲控制器按鈕是否被按下
IsButtonUp 判斷指定的遊戲控制器按鈕是否已放開

 

Windows Phone 7 是一隻支援多點觸控智慧型手機,程式設計師可以利用 TouchPanel 類別搭配 TouchCollection 結構判斷使用者的觸控操作。TouchPanel 類別常用的屬性可以參考表8 的說明:

表8:TouchPanel 類別常用的屬性
屬性名稱 說明
DisplayHeight 代表觸控螢幕高度的屬性
DisplayOrientation 代表觸控螢幕方向的屬性
DisplayWidth 代表觸控螢幕寬度的屬性
EnabledGestures 代表手勢操作是否啟用的屬性
IsGestureAvailable 代表是否支援手勢操作的屬性

 

TouchPanel 類別常用的方法可以參考表9 的說明:

表9:TouchPanel 類別常用的方法
方法名稱 說明
GetCapabilities 查詢觸控面板支援的功能的方法
GetState 取得觸控面板目前的狀態的方法
ReadGesture 讀取使用者手勢操作的相關資訊的方法

 

使用者對 Windows Phone 7 智慧型手機進行觸控及手勢操作的觸控資訊會存放在 TouchCollection 結構型態的變數中,程式設計師可以利用 TouchCollection 結構提供的屬性和方法取得使用者的觸控和手勢操作的相關資訊。TouchCollection 結構常的屬性可以參考表10 的說明:

表10:TouchCollection結構常用的屬性
屬性名稱 說明
Count 取得觸控螢幕被使用者觸碰的位置的數目
IsConnected 判斷觸控螢幕是否作用中
IsReadOnly 判斷存放觸控螢幕被使用者觸碰的位置的集合是否唯讀
Item 取得觸控螢幕被使用者觸碰的位置的相關資訊

 

TouchCollection 結構常的方法可以參考表11 的說明:

表11:TouchCollection 結構常用的方法
方法名稱 說明
Add 新增一個觸碰點到存放觸碰位置的集合中
Clear 清除存放觸碰點的集合的所有內容
Contains 清除存放觸碰點的集合的所有內容
FindById 依據 ID 搜尋觸碰點
IndexOf 判斷指定的的觸碰點位於存放觸碰點的集合的編號
Insert 插入觸碰點到存放觸碰點的集合的指定位置
Remove 自存放觸碰點的集合移除指定的觸碰點
RemoveAt 依據編號自存放觸碰點的集合移除指定的觸碰點

 

了解以 XNA 為基礎的遊戲的輸入控制技巧之後,接下來我們就要製作一個能夠允許使用者利用觸控的方式移動圖形的程式。

首先請啟動 Visual Studio 2010 Express for Windows Phone,建立一個 [Window Phone Game (4.0) 型態的專案],並於 Content Pipeline 專案加入一個圖形檔案 (例如內容為圓形的圖形檔案),做為使用者利用觸控面板移動的主體。做好之後請於 Game1 類別中宣告以下的變數,負責管理 2 維圖形,以及記錄 2 維圖形的位置:

 

 

XML
Texture2D Ball;											//管理 2 維圖形的變數
Vector2 BallPosition;									//記錄 2 維圖形的位置
 

宣告好變數之後請修改 Game1 類別的建構函式,加入設定遊戲視窗大小的程式碼,編輯好的 Game1 類別建構函式如下:

XML
public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
    graphics.PreferredBackBufferHeight = 800;				//設定遊戲視窗的高度為 800
    graphics.PreferredBackBufferWidth = 480;				//設定遊戲視窗的寛度為 480
    // Frame rate is 30 fps by default for Windows Phone.
    TargetElapsedTime = TimeSpan.FromTicks(333333);
}
 

設定好遊戲視窗的大小之後請修改 Game1 類別的 LoadContent 方法,負責載入 Content Pipeline 專案中事先準備好的圖形,並設定圖形要顯示在遊戲視窗的正中央:

XML
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
    Ball = Content.Load<Texture2D>("Ball"); 				//載入名稱為 Ball 的圖形資源
    BallPosition = new Vector2((Window.ClientBounds.Width - Ball.Width) 
(Window.ClientBounds.Height-Ball.Height)/2); //設定圖形顯示的位置在視窗正中央
}
 

[提示]

上述的程式碼利用 Game1 類別的 Window 屬性取得遊戲視窗,再利用遊戲視窗的 ClientBounds 屬性的 Width 成員和 Height 成員取得遊戲視窗的大小,做為計算圖形顯示位置的依據。

[注意]

讀者必須依據準備在 Content Pipeline 專案中的圖形資源名稱進行載入圖形資源的動作。

XML
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
    TouchCollection tc=TouchPanel.GetState();	   		//取得使用者操作觸控面板的狀態
    if (tc.Count > 0)							//如果使用者有觸控螢幕的動作
    {
        BallPosition = tc[0].Position;	//將使用者第一個觸碰點當做顯示圖形的左上角點
    }
    base.Update(gameTime);
}
 

接下來請編輯 Game1 類別的 Draw 方法,將遊戲載入的圖形資源顯示在使用者觸碰的螢幕座標點,做好的 Draw 方法如下:

XML
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);
    // TODO: Add your drawing code here
    spriteBatch.Begin();									//開始繪製遊戲內容
    spriteBatch.Draw(Ball, BallPosition, 
Color.White);		//將載入的圖形資源顯示在 BallPosition 變數指定的座標位置
    spriteBatch.End();									//結束繪製遊戲內容
    base.Draw(gameTime);
}
 

做好之後請按下 CTRL+F5 組合鍵執行遊戲程式,當遊戲程式開始執行的時候會將所載入的圖形顯示在遊戲視窗的正中央,當您觸碰 Windows Phone 7 智慧型手機的觸控螢幕的時候,遊戲程式顯示的圖形資源就會改變顯示位置到觸控螢幕被觸碰的座標點,如圖1 所示:

圖1:依據使用者觸碰觸控螢幕的座標點顯示圖形資源的遊戲程式執行的情形

 音效與音樂

以 XNA 為基礎的遊戲程式可以利用 SoundEffect 類別或 SoundEffectInstance 類別播放音效,或是利用 Song 類別和 MediaPlayer 類別執行播放音樂的動作,讓遊戲程式可以播放悅耳的背景音樂。

在支援音效播放方面,SoundEffectInstance 類別提供更多的音效播放控制方法,而 SoundEffect 類別只能提供單純的音效播放功能。表12 所列為 SoundEffect 類別常用的屬性:

表12:SoundEffect 類別常用的屬性
屬性名稱 說明
DistanceScale 距離比例。當音源遠離使用者時,如果聲音衰減太快,則須遞增 DistanceScale 屬性的內容值,反之則須遞減 DistanceScale 屬性的內容值
DopplerScale Doppler 比例。當音源接近使用者時,如果頻率升高太快,則須遞減 DopplerScale 屬性的內容值,反之則須遞增 DopplerScale 屬性的內容值
Duration 控制音效播放時間長短的屬性
MasterVolume 代表音量大小的屬性。內容值為 0.0f 代表不發出聲音 (靜音),內容值為 1.0f 代表最大音量
SpeedOfSound 代表音速的屬性,內容值為每秒 343.5 公尺

 

表13 所列為 SoundEffect 類別常用的方法:

表13:SoundEffect 類別常用的方法
方法名稱 說明
CreateInstance 能夠利用 SoundEffect 類別的物件建立 SoundEffectInstance 類別的物件的方法
FromStream 能夠利用資料流建立 SoundEffect 類別的物件
Play 負責播放音效的方法

 

SoundEffect 類別支援控制音效播放的功能較少,例如只支援播放音效的 Play 方法而未支援停止音效播放 Stop 方法,而且也未提供重覆播放音效的功能,如果遊戲程式需要對所播放的音效執行進階控制,就可以利用 SoundEffect 類別提供的 CreateInstance 方法建立 SoundEffectInstance 類別的物件,以便對所播放的音效執行更進階的控制。

表14 所示即為 SoundEffectInstance 類別常用的屬性:

表14:SoundEffectInstance 類別常用的屬性
屬性名稱 說明
IsLooped 控制音效是否需要重覆播放的屬性
Pan 控制音效平移的屬性
Pitch 控制音效的音調高低的屬性
State 代表音效播放狀態的屬性。其內容值為 Paused、Playing、Stopped 三種狀態之一
Volume 控制音效播放音量的屬性

 

有關 SoundEffectInstance 類別常用的方法可以參考表15 的說明:

表15:SoundEffectInstance 類別常用的方法
方法名稱 說明
Apply3D 播放 3D 音效
Pause 暫停音效播放
Play 播放音效
Resume 恢復音效播放
Stop 停止音效播放

 

如果遊戲程式欲播放的是音樂,例如副檔名為 mp3 的音樂或歌曲當做遊戲的背景音樂,就必須用到 Song 類別和 MediaPlayer 類別。Song 類別負責管理遊戲程式欲播放的音樂或歌曲,其常用的屬性請參考表16 的說明:

表16:Song 類別常用的屬性
屬性名稱 說明
Duration 代表歌曲長度的屬性
IsProtected 代表音樂是否為數位版權管理 (DRM) 的內容

 

Song 類別常用的方法可以參考表17 的說明:

表17:Song 類別常用的方法
方法名稱 說明
FromUri 利用 Uri 指向的音樂建立 Song 類別的物件

 

建立好負責管理音樂或歌曲的 Song 類別的物件之後,就可以利用 MediaPlayer 類別進行播放與控制。MediaPlayer 類別常用的屬性可以參考表18 的說明:

表18:MediaPlayer 類別常用的屬性
屬性名稱 說明
IsMuted 控制是否要調整成靜音模式的屬性
IsRepeating 控制是否要重覆播放音樂的屬性
PlayPosition 取得目前播放位置的屬性
State 代表目前播放狀態的屬性。其內容值為 Paused、Playing、Stopped 三種狀態之一
Volume 控制播放音量的屬性

 

MediaPlayer 類別常用的方法可以參考表19 的說明:

表19:MediaPlayer 類別常用的方法
方法名稱 說明
Pause 暫停音樂播放
Play 播放音樂
Resume 恢復音樂播放
Stop 停止音樂播放

 

 為遊戲程式加入音效和背景音樂

了解以 XNA 為基礎的遊戲程式支援播放音效與音樂的基本功能之後,接下來我們就要為所開發的遊戲程式加入背景音樂。

首先請為 [Windows Phone Game (4.0)] 專案中的 Content Pipeline 專案加入當做背景音樂與音效的資源檔案,例如您可以為專案加入副檔名為 .wma 的檔案當做遊戲程式的音效資源,為專案加入副檔名為 .mp3 或 .wma 的檔案當做遊戲的背景音樂。有關 Content Pipeline 專案支援的音效與音樂資源格式可以參考 [認識 XNA Game Studio 4.0] 一文的說明。

加入妥音效資源和背景音樂資源之後,請於 Game1 類別加入以下的變數宣告,負責管理音效資源,播放音效的 SoundEffectInstance 類別的物件,以及管理背景音樂的 Song 類別的物件:

XML
SoundEffect HitWall;						//管理球體碰撞到遊戲視窗邊界的音效的變數
SoundEffectInstance HitWallEffect;							//控制音效播放的變數
Song BackgroundSong;									//管理遊戲背景音效的變數
 

接下來請編輯 Game1 類別的 LoadContent 方法,加入以下的程式碼,執行載入音效和音樂資源的動作:

XML
HitWall = Content.Load<SoundEffect>("HitWall");		//載入名稱為 HitWall 的音效資源
HitWallEffect = HitWall.CreateInstance(); //建立播放音效資源的 SoundEffectInstance 物件
HitWallEffect.Apply3D(new AudioListener(), 
new AudioEmitter());	  //呼叫 SoundEffectInstance 物件的 Apply3D 方法,播放 3D 音效

BackgroundSong = Content.Load<Song>("SuperMario");//載入名稱為 SuperMario 的背景音樂資源
MediaPlayer.IsRepeating = 
true;	//將MediaPlayer類別的IsRepeating屬性設定成true,表示要不中斷地重覆播放背景音樂
MediaPlayer.Play(
BackgroundSong);					//呼叫 MediaPlayer 類別的 Play 方法播放名稱為
//BackgroundSong的物件管理的背景音樂
 

最後請編輯 Game1 類別的 Update 方法,加入以下的程式碼,以便在使用者利用觸碰觸控螢幕移動遊戲程式顯示的圖形時,判斷所移動的圖形是否碰撞到遊戲視窗的邊界,以決定是否要播放碰撞的音效:

XML
if (BallPosition.X == 0 || BallPosition.X > Window.ClientBounds.Width - Ball.Width || 
BallPosition.Y==0 || 
BallPosition.Y > 
Window.ClientBounds.Height-Ball.Height)	//判斷圖形是否碰撞到遊戲視窗的四個邊界
{
    HitWallEffect.Play();									//播放碰撞的音效
}
 

[說明]

控制播放音效與背景音樂的動作屬於控制遊戲程式狀態的範疇,和顯示遊戲程式內容無關,所以不需要修改 Game1 類別的 Draw 方法。

做好之後請按下 CTRL+F5 組合鍵執行專案,待遊戲程式啟動之後,讀者就可以聽到不斷重覆播放的背景音樂。當您觸碰遊戲程式的視窗以移動戲程顯示的圖形時,只要圖形碰觸到遊戲視窗的邊界,就會聽到遊戲程式發出的碰撞音效。

範例下載:TouchMoveBall.zip

[結語]

這一回我們為大家介紹了更多的 XNA Framework 支援遊戲開發的類別,包括支援輸入控制,音效播放,以及背景音樂播放控制的類別等等,讓讀者能夠為所製作的遊戲程式加入更豐富的遊戲效果。下一回我們將要為大家介紹進階的輸入控制,例如手勢觸控輸入,進階音效控制技巧,碰撞偵測,以及輔助 XNA 遊戲設計的好用類別。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值