2012年5月28日月曜日

ヴィータの画面(シーン)を、ハードウェアキーから操作する方法

今回の記事は、ヴィータの画面(シーン)を、ハードウェアキーから操作する方法について書かせて頂きたいと思います。

前回の記事では、ヴィータのストップウォッチを作った話をさせて頂きましたが、これがちょうどハードウェアキーからの操作を可能にしたアプリでありましたので、話のベースにしたいと思います。

ヴィータの画面(シーン)っていうのは、基本的にWindowsフォームと同じくイベントドリブン型のプログラミングをします。
たとえば、画面に配置されたボタンを押してプログラム実行!!というお馴染みのスタイルです。
しかし、ボタンを押す等の、ウィジェットに対するタッチ操作であれば良いのですが、ハードウェアキーから同じ機能を実行したいなーと思うと「あれっ、どのイベントにハードウェアキーのプログラム書けばいいの?」って愕然となってしまうと思います。

私が色々やってみた範囲では、シーン(画面)からのイベントドリブンでは対応出来ないです。
と言っても、私のヴィータのプログラミングは、全て自己流の試行錯誤でやってるので、これが「正解(正道)」なのかどうか言い切れないですが・・・

じゃあどうするのかというと、画面(シーン)を、より一段高い位置からコントロールしている「メインクラス」の「メインループ」の方に、ハードウェアキーによるプログラムを組み込みます。
画面(シーン)の方では無いというのが大きなポイントです。

このあたりの、メインループと画面(シーン)の関係については、以前の記事に書かせて頂きましたので、参照して頂けるととても助かります

その記事の内容と一部重複する部分がありますが、プログラムは大雑把に以下のようになります。

//*****************************************
//メインループ部分
//*****************************************
 public static void Main (string[] args)
 {
      try
     {
           Initialize ();    
           //@@@@@@@@@@[LOOP-START]@@@@@@@@@@
           while (bRES) 
           {
                 SystemEvents.CheckEvents ();
                 Update ();  //←ヴィータのハードウェアキー処理はこの中で行います。
                 Render ();
           }
           //@@@@@@@@@@[LOOP-END  ]@@@@@@@@@@
      }
      catch(System.Exception oE)
     {
             MessageDialog.CreateAndShow(MessageDialogStyle.Ok,"ヴィータからのお知らせ",oE.Message);
     }
}

//*****************************************
//Update内部のハードウェアキー処理部分(抜粋)
//*****************************************

//ヴィータ・ストップウォッチ処理部分
if((gamePadData.ButtonsDown & GamePadButtons.R)!=0)
{   //Rキーを押した後の処理(VitaStopWatchCONTROLは自作処理ですが内容については割愛させて頂きます)
     VitaStopWatchCONTROL(VitaStopWatchMode.StartAndStop);
}
else if((gamePadData.ButtonsDown & GamePadButtons.L)!=0)
{   //Lキーを押した後の処理
     VitaStopWatchCONTROL(VitaStopWatchMode.Split);
}
else if((gamePadData.ButtonsDown & GamePadButtons.Cross)!=0)
{   //(X)キーを押した後の処理
    VitaStopWatchCONTROL(VitaStopWatchMode.Clear);
}


ちなみに、gamePadData.ButtonsDown の部分を、gamePadData.Buttonsにすると、押した時の一回限りではなくて、キーを押している間じゅう連続的にキーをキャプチャします。

肝心のキー内容の判定ですが、今回のように(X)ボタンを使う場合は、決してgamePadData.ButtonsDown.Equals(GamePadButtons.Cross)という具合に、Equalsで判定してはいけません

どうしてかというと、LキーやRキーは良いのですが、ヴィータのクロスキー(×ボタン)を押すと、同時にEnterキーが入ってきます。
サークルボタン(○ボタン)は、同時にBackキーが入ってきます。
最初、Equalsで判定していたら、どうしても駄目で「何故だぁ」と焦ってしまいました。
そこで、テストプログラムを組んでチェックしてみたところ、上記の仕様が分かりました。
テストプログラムでチェックした時の様子です。
押したキーの内容を表示していますが、×ボタンを押すとEnterボタンの情報も同時に入ってきているのが分かります。
同じく、○ボタンを押すとBackボタンの情報も同時に入ってきていますね・・・これじゃあ「等しい」を意味するEqualsでの判定はダメダメで当然でした。

EnterもBackもヴィータには無いキーなので、これって、PlayStation Suiteがandroidにも対応している為、そっちとの互換性を考えた仕様なのかな?

ともあれ、ハードウェアキーによる制御が分かってくると、ヴィータのプログラミングがより深く楽しめるて来ますね!!

両面12点同時マルチタッチの最新鋭タッチパネルを備えるヴィータですが、ハードウェアキーも一歩たりとも後退しないのは当たり前で、歴史上最高の操作性という大進化を遂げているわけですから、積極的に使って行けたら良いなぁと思います。