7体感游戏设计.docx
《7体感游戏设计.docx》由会员分享,可在线阅读,更多相关《7体感游戏设计.docx(16页珍藏版)》请在冰豆网上搜索。
![7体感游戏设计.docx](https://file1.bdocx.com/fileroot1/2023-4/21/a557aedf-07b0-4a68-86f4-7a79ff4de74e/a557aedf-07b0-4a68-86f4-7a79ff4de74e1.gif)
7体感游戏设计
7体感游戏设计
摘要
WindowsPhone7智能型手机支持完整的传感器(Sensor)功能,包括:
重力传感器(G-Sensor)、数字罗盘、趋近传感器、以及环境光线传感器,这些传感器可以视为另外一种型态的输入,可以用来控制游戏程序的进行。
在这一篇文章,我们将会利用WindowsPhone7智能型手机的重力传感器,让使用者能够利用传感器代替输入设备,达到控制游戏执行的目的。
认识传感器
传感器可以视为一种特殊的输入设备,使用者可以不需要特别执行任何输入的动作,程序就可以依据传感器输入的数据做出反应。
例如程序可以利用数字电子罗盘得到方向相关的数据,协助定位相关的功能进行定位;利用光线传感器感应外界光线的强弱,自动调节智能型手机屏幕的亮度;利用接近传感器判断智能型手机是否贴近使用者的脸部欲进行通话的动作,而锁定屏幕,避免误触智能型手机的功能而影响通话的进行;利用重力传感器感应智能型手机运动的方向,并据以调整智能型手机的屏幕显示方向,或是改变程序显示的内容。
例如类似弹珠台的游戏程序就可以善用重力传感器模拟使用者摇晃弹珠台,以改变弹珠的滚动方向的动作,达到逼真的游戏操作体验。
除此之外,重力传感器在支持GPS(全球定位系统)功能方面,能够在智能型手机接收不到卫星讯号时利用智能型手机运动的方法推断用户的位置。
传感器在游戏程序的应用
传感器在游戏程序的应用很广泛,例如使用者挥动手臂的动作可以模拟使用球棒挥击棒球的动作,模拟掷出保龄球的动作,拍击网球、羽毛球、或乒乓球的动作,模拟丢掷骰子,甚至可以模拟游戏者身体移动的方向,跳跃的高度与距离,让使用者融入游戏的场景,达到与游戏真实互动的感觉,而不是像传统的游戏,游戏的使用者感觉较像局外人。
Microsoft、任天堂、与Sony等游戏大厂在体感游戏开发方面都有丰富的成果,而且也都得到游戏玩家正面的反应。
WindowsPhone7智能型手机支持了完整的传感器功能,让程序设计师能够很方便开发出利用传感器控制的俄罗斯方块,在不靠键盘输入的状况下利用倾斜智能型手机的方式控制方块掉落的位置。
WindowsPhone7体感游戏设计支持
了解传感器的用途以及传感器在游戏程序上的应用之后,接下来我们就要利用WindowsPhone7智能型手机提供的重力传感器开发能够利用传感器控制游戏显示的内容的游戏。
WindowsPhone7智能型手机提供的重力传感器可以利用量测重力的原理判断智能型手机移动的方向,允许使用者利用摇动或甩动智能型手机的方式控制游戏的执行,其原理和汽车的安全气囊相同,在侦测到汽车快速减速的时候立刻充气以保护驾驶人与乘客不会受伤。
要使用重力传感器当做游戏程序的输入,以XNA为基础的游戏程序可以利用Accelerometer类别提供的功能启用/停用重力加速器,取得重力加速器的状态,以及处理重力加速器引发的事件。
有关Accelerometer类别常用的属性可以参考表1的说明:
表1:
Accelerometer类别常用的属性
属性名称
说明
State
管理重力加速器状态的属性,其型态为SensorState列举型态。
有关SensorState列举型态合法的内容值可以参考表4的说明。
Accelerometer类别常用的方法可以参考表2的说明:
表2:
Accelerometer类别常用的方法
方法名称
说明
Start
开始从重力加速器读取数据。
Stop
结束从重力加速器读取数据。
Accelerometer类别常用的事件可以参考表3的说明:
表3:
Accelerometer类别常用的事件
事件名称
说明
ReadingChanged
当重力加速器读取到数据时会引发的事件。
处理ReadingChanged事件的事件处理程序的第二个参数的型态为AccelerometerReadingEventArgs类别,其X、Y、与X属性的内容值代表智能型手机在X轴、Y轴、和Z轴的加速方向,而不是三度空间的坐标,其单位为重力单位,也就是G力(1G=9.81m/s2)。
除了X、Y、与Z三个属性以外,还有一个名称为Timestamp的属性,负责记录重力加速器读取数据的时间点。
有关X轴、Y轴、和Z轴的加速方向可以参考图1的说明:
图1:
X轴、Y轴、和Z轴的加速方向
请注意当智能型手机放在平坦的桌面上,而且正面朝上的时候,AccelerometerReadingEventArgs类别的Z字段的内容值会是-1.0,表示Z轴承受-1G的重力,而当智能型手机放在平坦的桌面上,而且正面朝下的时候,AccelerometerReadingEventArgs类别的Z字段的内容值就会是+1.0,表示Z轴承受1G的重力。
[说明]
透过Accelerometer类别的State属性取得的重力加速器状态是SensorState列举型态的数据,其合法的内容值请参考表4的说明:
表4:
SensorState列举型态合法的内容值
内容值名称
说明
NotSupported
未支持重力加速器。
Ready
重力加速器处于可以处理数据的状态。
Initializing
重力加速器正在初始化。
NoData
未支持重力加速器。
NoPermissions
呼叫者没有权限取用重力加速器接收到的数据。
Disabled
重力加速器处于禁用的状态。
要使用重力加速器判断智能型手机加速的方向,首先您必须使用鼠标的右键点中[SolutionExplorer]窗口中的项目名称,从出现的菜单选择[AddReference]功能,然后于出现的窗口中选择名称为Microsoft.Devices.Sensors的组件,如图2所示:
图2:
参考名称为Microsoft.Devices.Sensors的组件的画面
做好之后请按下[OK]键完成参考组件的动作。
接下来请于Game1类别中加入以下的变量宣告,负责管理重力加速器装置:
AccelerometergSensor;//管理重力加速器的變數
然后于Initialize方法执行建立Accelerometer类别的对象的动作,为Accelerometer类别的对象的ReadingChanged事件制作事件处理程序,并呼叫Accelerometer类别的Start方法,开始接收从重力加速器输入的数据,如下:
protectedoverridevoidInitialize()
{
gSensor=newAccelerometer();//建立Accelerometer類別的物件
gSensor.ReadingChanged+=new
EventHandler(
gSensor_ReadingChanged);//處理Accelerometer類別的物件的ReadingChanged事件
gSensor.Start();//開始接收重力加速器輸入的資料
base.Initialize();
}
应用程序只要于Accelerometer类别的对象的ReadingChanged事件的事件处理程序中利用型态为AccelerometerReadingEventArgs类别,名称为e的参数,就可以得知WindowsPhone7装置加速的方向,如下:
voidgSensor_ReadingChanged(objectsender,AccelerometerReadingEventArgse)
{
//取用e.X,e.Y,e.Z
}
利用传感器移动XNA游戏显示的物体
了解WindowsPhone7对体感游戏设计的支持之后,接下来我们就要设计一个能够支持体感控制的XNA游戏,让使用者能够以倾斜WindowsPhone7智能型手机的方式移动物体。
首先请启动VisualStudio2010ExpressforWindowsPhone,建立一个[WindowsPhoneGame(4.0)]型态的项目,然后加入游戏程序欲显示的图片到ContentPipeline项目中。
做好之后请为Game1类别加入以下的变量宣告,负责管理欲显示的图片和图片的显示位置,以及管理重力加速器和记载加速度方向的变量:
Texture2DLogo;//管理欲顯示的圖片的變數
Vector2LogoPosition;//管理圖片顯示位置的變數
AccelerometergSensor;//管理重力加速器的變數
Vector2LogoVelocity;//管理加速度方向的變數
宣告妥游戏程序欲使用的变量之后请编辑Game1类别的建构函式,执行设定游戏窗口的高度与宽度的工作,设定好游戏窗口高度与宽度的Game1类别建构函式如下:
publicGame1()
{
graphics=newGraphicsDeviceManager(this);
Content.RootDirectory="Content";
graphics.PreferredBackBufferWidth=480;//設定遊戲視窗的寬度
graphics.PreferredBackBufferHeight=800;//設定遊戲視窗的高度
TargetElapsedTime=TimeSpan.FromTicks(333333);
}
因为我们想让游戏的使用者能够利用传感器控制游戏显示的对象,所以我们必须在Game1类别的Initialize方法中启用重力加速器,做好的Initialize方法如下:
protectedoverridevoidInitialize()
{
gSensor=newAccelerometer();//建立Accelerometer類別的物件
gSensor.ReadingChanged+=newEventHandler(
gSensor_ReadingChanged);//為建立Accelerometer類別的物件指定
//ReadingChanged事件的事件處理程序
gSensor.Start();//啟動重力加速器
base.Initialize();
}
上述的程序代码需要用到名称为gSensor_ReadingChanged的事件处理程序,所以我们必须在Game1类别中加入以下的方法,负责处理Accelerometer类别的对象(即重力加速器)引发的ReadingChanged事件:
voidgSensor_ReadingChanged(objectsender,AccelerometerReadingEventArgse)
{
LogoVelocity.X+=(float)e.X;//取得X軸的加速度
LogoVelocity.Y+=-(float)e.Y;//取得Y軸的加速度
LogoPosition+=LogoVelocity;//將加速度的內容值加入到圖片的位置
}
建立妥管理Accelerometer类别的对象,启动重力加速器之后,并制作好处理重力加速器引发的ReadingChanged事件的事件处理程序之后,请编辑Game1类别的LoadContent方法,加载游戏程序欲显示的图片,顺便设定图片默认的显示位置,做好的LoadContent方法如下:
protectedoverridevoidLoadContent()
{
spriteBatch=newSpriteBatch(GraphicsDevice);
Logo=Content.Load("xna");//載入遊戲程式欲顯示的圖片
Viewportviewport=graphics.GraphicsDevice.Viewport;//取得遊戲視窗的視界
LogoPosition=newVector2((viewport.Width-Logo.Width)/2,(viewport.Height–
Logo.Height)/2);//設定圖片預設顯示的位置在遊戲視窗的正中央
}
因为我们在初始化的阶段启用了重力加速器传感器,所以我们需要在游戏程序结束之前关闭重力加速器。
您可以编辑Game1类别的UnloadContent方法,于UnloadContent方法中呼叫Accelerometer类别的对象的Stop方法,将重力加速器关闭,编辑好的UnloadContent方法如下:
protectedoverridevoidUnloadContent()
{
gSensor.Stop();
}
因为我们开发的游戏程序允许用户以倾斜的方式让用户移动游戏程序显示的对象,所以我们必须在Game1类别的Update方法中改变物体显示的位置,当游戏程序显示的物体碰撞到游戏窗口的四个边界的时候,停止移动物体的动作。
所以我们要将Game1类别的Update方法编辑成以下的样子,在物体碰撞到游戏窗口的四个边界时,设定对象显示的位置,并将重力加速度的内容值设定为0:
protectedoverridevoidUpdate(GameTimegameTime)
{
if(GamePad.GetState(PlayerIndex.One).Buttons.Back==ButtonState.Pressed)
this.Exit();
Viewportviewport=graphics.GraphicsDevice.Viewport;//取得遊戲視窗的視界
if(LogoPosition.X<0)//如果所顯示的圖片已經超出遊戲視窗的左邊界
{
LogoPosition.X=0;//將所顯示的圖片的位置靠齊在遊戲視窗的左邊界
LogoVelocity.X=0;//設定X軸方向的加速度為0
}
elseif(LogoPosition.X>viewport.Width–
Logo.Width)//如果所顯示的圖片已經超出遊戲視窗的右邊界
{
LogoPosition.X=viewport.Width–
Logo.Width;//將所顯示的圖片的位置靠齊在遊戲視窗的右邊界
LogoVelocity.X=0;//設定X軸方向的加速度為0
}
if(LogoPosition.Y<0)//如果所顯示的圖片已經超出遊戲視窗的上邊界
{
LogoPosition.Y=0;//將所顯示的圖片的位置靠齊在遊戲視窗的上邊界
LogoVelocity.Y=0;//設定Y軸方向的加速度為0
}
elseif(LogoPosition.Y>viewport.Height–
Logo.Height)//如果所顯示的圖片已經超出遊戲視窗的下邊界
{
LogoPosition.Y=viewport.Height–
Logo.Height;//將所顯示的圖片的位置靠齊在遊戲視窗的下邊界
LogoVelocity.Y=0;//設定Y軸方向的加速度為0
}
base.Update(gameTime);
}
[提示]
上述的程序代码会在游戏程序显示的物体碰撞到游戏窗口的四个边界的时候将物体停放在窗口的边界,如果要让对象碰撞到游戏窗口的边界时产生反弹的效果,可以将对象加速度的方向设定为负值,再依据模拟的摩擦系数进行递减,详细的做法可以参考[设计支持手势操作的XNA游戏]一文的说明,让游戏程序显示的物体能够像实际世界的物体一样呈现自然的反弹效果。
最后我们要编辑Game1类别的Draw方法,将游戏程序显示的物体显示在游戏程序的窗口中,编辑好的Draw方法如下:
protectedoverridevoidDraw(GameTimegameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();//宣告繪製的動作開始
spriteBatch.Draw(Logo,LogoPosition,Color.White);//繪製事先載入的圖片資源
spriteBatch.End();//宣告繪製的動作結束
base.Draw(gameTime);
}
做好之后请执行建置项目的动作,完成使用传感器的游戏程序的制作。
因为我们制作的游戏程序需要使用到WindowsPhone7智能型手机上的重力加速器,让游戏程序利用传感器输入的数据来控制游戏程序的进行,所以制作好的程序必须部署到实际的WindowsPhone7智能型手机上执行,无法部署到WindowsPhone7的仿真器上执行,因为WindowsPhone7仿真器并未提供传感器的功能,就算WindowsPhone7仿真器提供重力加速器传感器,用户也很难摇动或是倾斜计算机的屏幕以产生重力加速的效果,以试验游戏程序设计读取传感器输入的数据的功能是否正确。
有关如何将开发好的游戏程序部署到实际的WindowsPhone7智能型手机的做法可以参考[设计支持手势操作的XNA游戏]一文的说明。
请将开发好的游戏程序部署到实际的WindowsPhone7智能型手机执行,您将会看到如图3的执行画面:
图3:
使用重力加速器功能的游戏程序执行的情形
您可以将智能型手机往任意的方向倾斜,游戏程序显示的物体就会往屏幕倾斜的方向移动,这是因为智能型手机往任意的方向倾斜之后产生的重力加速度会被用来当做移动游戏程序移动物体的速度的关系。
[提示]
有些游戏程序会在用户将智能型手机的屏幕转向之后,切换屏幕显示的内容,例如将原本垂直显示的窗口内容改变成水平显示的内容,或是将原本水平显示的窗口内容改变成垂直显示的内容,这种功能并不需要利用Accelerometer类别提供的功能才能够达成。
要在使用者旋转智能型手机方向的时候自动旋转游戏程序窗口的显示方向,以XNA为基础的游戏程序只要设定GraphicsDeviceManager类别的对象的SupportedOrientations属性的内容值,就可以在使用者旋转智能型手机的方向的时候自动旋转游戏程序窗口的显示方向。
GraphicsDeviceManager类别的对象的SupportedOrientations属性的型态为DisplayOrientation结构,其合法的内容值请参考表5的说明:
表5:
DisplayOrientation结构合法的内容值
合法的内容值
说明
Default
默认的窗口显示方向。
LandscapeLeft
将窗口的显示方向逆时钟旋转90度,变成水平显示的方向,此时屏幕的宽度将会大于窗口的高度。
LandscapeRight
将窗口的显示方向顺时钟旋转90度,变成水平显示的方向,此时窗口的宽度将会大于窗口的高度。
Portrait
以垂直的方向显示窗口的内容,此时窗口的高度将会大于窗口的宽度。
您只要在Game1类别的建构函式中将GraphicsDeviceManager类别的对象的SupportedOrientations属性的内容值设定成适当的内容值,就可以在使用者旋转智能型手机的方向的时候自动旋转游戏程序窗口的显示方向,做法如下:
publicGame1()
{
graphics=newGraphicsDeviceManager(this);
Content.RootDirectory="Content";
graphics.SupportedOrientations=
DisplayOrientation.Portrait|
DisplayOrientation.LandscapeLeft|
DisplayOrientation.LandscapeRight;//表示視窗能夠自動切換成垂直顯//示,逆時鐘旋轉90度顯示,以及順//時鐘旋轉90度顯示
graphics.PreferredBackBufferWidth=480;
graphics.PreferredBackBufferHeight=800;
TargetElapsedTime=TimeSpan.FromTicks(333333);
}
做好之后请将应用程序部署到实际的WindowsPhone7智能型手机执行,然后旋转执行程序的WindowsPhone7智能型手机屏幕的方向,您就会发现应用程序也会自动调整窗口显示的方向,使其和屏幕的方向一致,如图4所示:
图4:
可以依据屏幕的方向自动调整窗口显示方向的游戏程序
范例下载:
AccelerometerEnabledGame.zip
audioEngine=newAudioEngine("Content\\MyAudio.xgs");//建立AudioEngine類別的物件
waveBank=newWaveBank(audioEngine,
"Content\\WaveBank.xwb");//建立WaveBank類別的物件
soundBank=newSoundBank(audioEngine,
"Content\\SoundBank.xsb");//建立SoundBank類別的物件
请注意建立AudioEngine类别对象时指定的是XACT3的项目名称,其扩展名为.xgs,建立WaveBank类别的对象时指定的是WaveBank的名称,其扩展名为.xwb,而建立SoundBank类别的对象时指定的是SoundBank的名称,其扩展名为.xsb。
建立好必要的对象之后,请于Game1类别的Update方法加入以下的程序代码,准备欲播放的音效内容,并呼叫AudioEngine类别对象的PlayCue方法执行播放音效的动作:
audioEngine.Update();
soundBank.PlayCue("RingOut");
请注意呼叫AudioEngine类别对象的PlayCue方法所传入的是CueName,意即要播放CueName所代表的声音文件。
做好之后只要执行程序就可以听到程序播放XACT3工具管理的音效。