
剛嘗試手勢的時候我差點選擇放棄,現在想想還是自己不好好看SDK,小心使得萬年船啊。
五一不想斷更的,實在是沒辦法,出去的急忘了帶筆記本,隻好斷更。下午才回來,畢竟這種萬年沒休的也習慣這種生活方式了,反而出去溜達感到閑的蛋疼。
廢話不多說,直接貼代碼,這段代碼實作的是在畫圈停止後輸出一個Gesture通知,代碼很順利,結果很粗糙。由于手部肌肉連帶,食指動的時候必然中指也動,加上Leap“超凡的精确度”,導緻動了右手食指,出來四胞胎結果——拇指,食指,中指,無名指。
public override void OnFrame(Controller arg0)
{
Frame frame = arg0.Frame();
GestureList gestures = frame.Gestures();
for (int i = 0; i < gestures.Count; i++)
{
Gesture gesture = gestures[i];
switch (gesture.Type)
{
case Gesture.GestureType.TYPE_CIRCLE:
CircleGesture circle = new CircleGesture(gesture);
// Calculate clock direction using the angle between circle normal and pointable
String clockwiseness;
if (circle.Pointable.Direction.AngleTo(circle.Normal) <= Math.PI / 2)
{
//Clockwise if angle is less than 90 degrees
clockwiseness = "clockwise";
}
else
{
clockwiseness = "counterclockwise";
}
float sweptAngle = 0;
// Calculate angle swept since last frame
if (circle.State != Gesture.GestureState.STATE_START)
{
CircleGesture previousUpdate = new CircleGesture(arg0.Frame(1).Gesture(circle.Id));
sweptAngle = (circle.Progress - previousUpdate.Progress) * 360;
}
if(circle.State==Gesture.GestureState.STATE_STOP)
Console.WriteLine(" Circle id: " + circle.Id
+ ", " + circle.State
+ ", progress: " + circle.Progress
+ ", radius: " + circle.Radius
+ ", angle: " + sweptAngle
+ ", " + clockwiseness);
break;
}
}
}
修改過一個小東西後,手勢明顯變得好用了,就是門檻值。圖上是檢測Key_Tap時候的回報資料,由于設定了min_distance,即最小移動檢測門檻值,回報良好,基本不會出現誤操作的問題。由此可見好好看SDK是多麼重要啊!門檻值參數表如下:
畫圈手勢
Gesture.Circle.MinRadius float5mm
Gesture.Circle.MinArc float1.5 * piradians
按鍵手勢
Gesture.KeyTap.MinDownVelocity float50mm/s
Gesture.KeyTap.HistorySeconds float0.1s
Gesture.KeyTap.MinDistance float3mm
橫掃手勢
Gesture.Swipe.MinLength float150mm
Gesture.Swipe.MinVelocity float1000mm/s
觸摸手勢
Gesture.ScreenTap.MinForwardVelocity float50mm/s
Gesture.ScreenTap.HistorySeconds float0.1s
Gesture.ScreenTap.MinDistance float5mm
第一項為名稱,第二項是資料類型(都是float),第三項是預設門檻值大小,第四項是機關,csdn的表格有點不友善,然而對于一個寫程式剛入門的,還去用dreamwaver編個表格粘到源碼裡,太麻煩,大家就這麼一看,我就這麼一畫吧。修改門檻值的方式也很簡單:這裡用Circle手勢作為參考,修改了最小半徑和最小角速度,然後記得儲存。
controller.Config.SetFloat ("Gesture.Circle.MinRadius", 10.0f);
controller.Config.SetFloat ("Gesture.Circle.MinArc", .5f);
controller.Config.Save ();
那麼問題又來了,手勢是對了,怎麼知道是哪根指頭操作的呢,不能玩第二根半價(權值選擇不讀)的遊戲啊,肯定得想辦法把所有指頭都用上。想了兩個辦法,第一個操作一個Hand循環,采樣手指名稱,比如finger.type等于“TYPE_INDEX”是食指,是需要的的指頭操作,測試發現問題了,因為是foreach fingers,是以隻要手指頭被檢測到,就會被刷出來,第一種方案胎死腹中。第二個方案比較原始,即判斷激發點和手指的位置是不是重合,但是由于Finger中并沒有postion參數,隻好想其他辦法,不過下期一定貼代碼!
另外,細心的朋友發現程式失焦後會不工作,這是Leap的一種保護機制,然而這種保護機制我給零分,明明應該是預設讀取資料,我可以選擇關閉,現在是預設關閉我可以選擇打開,好吧,我服,其實就是加了一句話:
Controller.SetPolicy(Controller.PolicyFlag.POLICY_BACKGROUND_FRAMES);
這樣子程式就可以背景繼續資料了,回來路上我還納悶這個問題呢,心想不應該,實在不行建立個新程序單獨走,然而SDK再一次告訴我想多了,好好看SDK,東西全在裡面,寫不出都是自己的問題。現在節奏快,巴不得什麼東西都不學,一口吃成個大胖子,唉,急不得啊。
如果有朋友有finger和gesture比對的解決方案,記得留言!