输入检测模块是一个挺让我头大的模块,虽然写得有些奇特,但是自己用起来还是感觉良好的。
作为一个小菜(鸟),肯定有说错了或者不恰当的话,希望细心的读者可以指正,thx~
Input部分分为上下两篇,上篇提出问题和构想,下篇则是本人的解决方案,希望阅读了上篇的朋友可以实现更好的解决方案~
首先,我的输入模块奇特在如下两处:
1.手势处理:
平时在XNA中简单读取手势我们的代码大致如此:
protected override void Update(GameTime gameTime)
{
while (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
switch (gesture.GestureType)
{
case GestureType.Tap:
......
case GestureType.Hold:
......
......
}
}
......
base.Update(gameTime);
}
这样的代码看似效率蛮高,但是用起来总觉得不够...可不可以这样做呢:
我们在创建每个页面的时候都注册要用到的手势,当系统检测到相应的手势后,触发相应的响应事件(方法)
忽略系统的细节,我们先看看调用的方式大致是这个样子的:
protected override void LoadContent()
{
// 创建新的 SpriteBatch,可将其用于绘制纹理。
spriteBatch = new SpriteBatch(GraphicsDevice);
//......
SetupInput();
}
private void SetupInput()
{
SAInput.EnableGesture(GestureType.Tap, OnTap);
SAInput.EnableGesture(GestureType.DragComplete, OnTap);
SAInput.EnableGesture(GestureType.HorizontalDrag, OnDrag);
SAInput.EnableBackButton(OnBackButton);
}
private void OnTap(GestureSample gestureSample)
{
//......
}
private void OnDrag(GestureSample gestureSample)
{
// ......
}
private void OnBackButton()
{
this.Exit();
}
protected override void Update(GameTime gameTime)
{
SAInput.UpdateInput();
// ......
base.Update(gameTime);
}
纳尼,似乎代码变长了~,不过,当我们完成自定义的页面后,真正对Input的使用会变得相当简单易读,大概会是这个样子:
private override void SetupInput()
{
SAInput.EnableGesture(GestureType.Tap, OnTap);
SAInput.EnableGesture(GestureType.DragComplete, OnTap);
SAInput.EnableGesture(GestureType.HorizontalDrag, OnDrag);
SAInput.EnableBackButton(OnBackButton);
}
private void OnTap(GestureSample gestureSample)
{
//......
}
private void OnDrag(GestureSample gestureSample)
{
// ......
}
private void OnBackButton()
{
this.Exit();
}
有没有稍微觉得这个样子清爽了一些?
细心的读者应该已经发现了,连同平时用的BackButton的检测也已经整合了进来。
2.加速度计:
平时的使用:
protected override void Initialize()
{
gSensor = new Accelerometer(); //建立 Accelerometer 類別的物件
gSensor.ReadingChanged += new
EventHandler<AccelerometerReadingEventArgs>(
gSensor_ReadingChanged); //處理 Accelerometer 類別的物件的 ReadingChanged 事件
gSensor.Start(); //開始接收重力加速器輸入的資料
base.Initialize();
}
void gSensor_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
//取用 e.X, e.Y, e.Z
}
改进后的样子:
protected override void Initialize()
{
//......
SAAccelerometer.StartAccelerometer();
base.Initialize();
}
protected override void Update(GameTime gameTime)
{
//......
float tempX = SAAccelerometer.X;
float tempY = SAAccelerometer.Y;
float tempZ = SAAccelerometer.Z;
base.Update(gameTime);
}
直接使用SAAccelerometer的全局变量即可,通过X,Y,Z的值我们可以了解并使用加速计的状态。
Inputs部分有两个曾经比较令我烦心的地方:
1.如何整合自定义的控件,
2.如何整合手势以及较为底层的TouchCollection(在处理多点非手势的触摸上,对TouchCollection的处理很重要)。
上篇差不多就是这么多了~