Windows Phone XNA遊戲提供的重力傳感器可以利用量測重力的原理判手機移動的方向,允許使用者利用搖動或甩動手機的方式控制遊戲的執行,其原理和汽車的安全氣囊相同,在偵測到汽車快速減速的時候立刻充氣以保護駕駛人與乘客不會受傷。要使用重力傳感器當做遊戲程式的輸入,以 XNA 為基礎的遊戲程式可以利用 Accelerometer 類别提供的功能啟用/停用重力加速器,取得重力加速器的狀态,以及處理重力加速器引發的事件。
Accelerometer 類别常用的屬性
屬性名稱
說明
State
管理重力加速器狀态的屬性,其型态為 SensorState 列舉型态。有關 SensorState 列舉型态合法的内容值可以參考表4 的說明。
Accelerometer 類别常用的方法
方法名稱
Start
開始從重力加速器讀取資料。
Stop
結束從重力加速器讀取資料。
Accelerometer 類别常用的事件
事件名稱
ReadingChanged
當重力加速器讀取到資料時會引發的事件。
處理 ReadingChanged 事件的事件處理程式的第二個參數的型态為 AccelerometerReadingEventArgs 類别,其 X、Y、與 X 屬性的内容值代表智能型手機在 X 軸、Y 軸、和 Z 軸的加速方向,而不是三度空間的坐标,其機關為重力機關,也就是 G 力 (1G = 9.81 m/s2)。除了 X、Y、與 Z 三個屬性以外,還有一個名稱為 Timestamp 的屬性,負責記錄重力加速器讀取資料的時間點。
請注意當手機放在平坦的桌面上,而且正面朝上的時候,AccelerometerReadingEventArgs 類别的 Z 字段的内容值會是 -1.0,表示 Z 軸承受 -1G 的重力,而當手機放在平坦的桌面上,而且正面朝下的時候,AccelerometerReadingEventArgs 類别的 Z 字段的内容值就會是 +1.0,表示 Z 軸承受 1G 的重力。
[說明]
透過 Accelerometer 類别的 State 屬性取得的重力加速器狀态是 SensorState 列舉型态的資料,其合法的内容值請參考表 的說明:
内容值名稱
NotSupported
未支援重力加速器。
Ready
重力加速器處于可以處理資料的狀态。
Initializing
重力加速器正在初始化。
NoData
NoPermissions
呼叫者沒有權限取用重力加速器接收到的資料。
Disabled
重力加速器處于禁用的狀态。
要使用重力加速器判斷智能型手機加速的方向,首先您必須使用滑鼠的右鍵點中 [Solution Explorer] 視窗中的項目名稱,從出現的菜單選擇 [Add Reference] 功能,然後于出現的視窗中選擇名稱為 Microsoft.Devices.Sensors 的元件,添加引用上去。
下面看一個例子:
using System;
using System.Windows;
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.Input.Touch;
using Microsoft.Xna.Framework.Media;
using Microsoft.Devices.Sensors;
namespace AccelerometerSample
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont readingsFont;//字型資源
Accelerometer accelerometer;//重力加速器
double X;
double Y;
double Z;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
}
/// <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
//初始化重力加速器
accelerometer = new Accelerometer();
//讀取重力改變事件
accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(AccelerometerReadingChanged);
//開始其中重力加速器
accelerometer.Start();
base.Initialize();
/// LoadContent will be called once per game and is the place to load
/// all of your content.
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
//加載字型資源
readingsFont = Content.Load<SpriteFont>("readings");
/// UnloadContent will be called once per game and is the place to unload
/// all content.
protected override void UnloadContent()
// TODO: Unload any non ContentManager content here
accelerometer.Stop();
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// <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);
/// This is called when the game should draw itself.
protected override void Draw(GameTime gameTime)
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
//繪制文字
spriteBatch.DrawString(readingsFont, "X: " + X.ToString("0.00"), new Vector2(50, 50), Color.White);
spriteBatch.DrawString(readingsFont, "Y: " + Y.ToString("0.00"), new Vector2(50, 75), Color.White);
spriteBatch.DrawString(readingsFont, "Z: " + Z.ToString("0.00"), new Vector2(50, 100), Color.White);
spriteBatch.End();
base.Draw(gameTime);
void AccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs e)
//觸發UI更新
Deployment.Current.Dispatcher.BeginInvoke(() => NewReading(e));
//指派XYZ的值
void NewReading(AccelerometerReadingEventArgs e)
X = e.X;
Y = e.Y;
Z = e.Z;
}
}
<a href="http://blog.51cto.com/attachment/201212/162325162.jpg" target="_blank"></a>
本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1078392