◆PROCESSING 逆引きリファレンス
カテゴリー:スマホ(AndroidMode)
マウスイベントの扱いについて(AndroidMode編)
【概要】
PROCESSINGにAndroidMode を導入する事で、PROCESSINGで開発したプログラムをAndroid端末上で動かす事ができるようになります。
AndroidModeの導入については「PROCESSINGをAndroid端末で動かすには(4.0版)」記事を参照してください。
PCでは、マウスでの操作が主流です。一方スマホでは、(一部の特殊な機種を除き)ほとんどの機種で、タッチでの操作が主流となっています。
それでは、AndroidModeでマウスイベントの扱いは、どのようになっているのでしょうか?。
結論から言うと、AndroidModeでは基本的にマウスイベントは利用できなくなっています。スマホらしく、マウスイベントではなくタッチイベントを拾って、人間の操作を処理する必要があるという事ですね。
しかし一部のマウスイベントについては、(JavaModeとの互換性のためか)残されており、タッチイベントの限定的な動作を検知できます。
またマウスに関するグローバル変数(mouseX、mouseY、mousePressed)も利用可能ですが、その挙動はJavaModeとはかなり異なっています。
AndroidModeでは、以下のマウスイベントが利用可能です。
mousePressed、mouseDragged、mouseReleased は限定的なサポートとなっています。イベントに渡される MouseEvent クラスも、動作が大きく異なるので注意して下さい。
mouseClickedからmouseMoved まではコーディングしてもコンパイルエラーにはなりませんが、まったく動作しないため意味を成しません(汗)。
JavaModeで利用できた mouseWheel は未サポートとなっており、コーディングするとコンパイルエラーとなります。
【詳細】
タッチ開始
void mousePressed ( ) ;
mousePressed メソッドで、タッチ開始動作を拾うことが可能です。スクリーンにタッチされた瞬間、このメソッドが反応します。
メソッドに渡される MouseEvent クラスがもつ getX( )、getY( ) メソッドを利用するか、mouseX、mouseY 変数を利用する事で、タッチされた座標を知ることが可能です。
例えば、以下のような感じです。
1 2 3 4 5 6 |
public void mousePressed( MouseEvent mouseEvent ) { //getX()、getY()でタッチされた座標が得られる //mouseX、mouseY を利用してもよい Log.d( TAG, "mousePressed "+mouseEvent.getX()+","+mouseEvent.getY()); Log.d( TAG, "mousePressed "+mouseX + "," + mouseY ); } |
ただし、mousePressed メソッドはマルチタッチには対応していません。
複数の指でスクリーンをタッチしても、イベントは最初の指が触れた瞬間の1回分しか上がってきません。
mouseX、mouseY に記録される座標も、最初の指が置かれた座標のみです。2本め以降の指が置かれた座標ではない事に注意してください。
なおエミュレータ(仮想端末)で実行した場合は、マウスの右ボタン押下には反応しません。
スワイプ
void mouseDragged ( MouseEvent mouseEvent ) ;
void mouseDragged ( ) ;
mouseDragged メソッドで、スワイプ動作を拾うことが可能です。スクリーン上で指を動かしている間、このメソッドが反応します。
メソッドに渡される MouseEvent クラスがもつ getX( )、getY( ) メソッドを利用するか、mouseX、mouseY 変数を利用する事で、スワイプ中の座標を知ることが可能です。
mouseDragged メソッドもマルチタッチには対応していません。
複数の指でスクリーンをドラッグしても、イベントは最初の指が移動している間しか上がってきません。
mouseX、mouseY に記録される座標も、最初の指が置かれている座標のみです。2本め以降の指が置かれている座標ではない事に注意してください。
エミュレータで実行した場合は、マウスのドラッグ操作に反応します。
タッチ終了
void mouseReleased ( MouseEvent mouseEvent ) ;
void mouseReleased ( ) ;
mouseReleased メソッドで、タッチ終了動作を拾うことが可能です。スクリーン上から指を離した瞬間、このメソッドが反応します。
メソッドに渡される MouseEvent クラスがもつ getX( )、getY( ) メソッドを利用するか、mouseX、mouseY 変数を利用する事で、指が離された座標を知ることが可能です。
mouseReleased メソッドもマルチタッチには対応していません。
mouseX、mouseY に記録される座標は、最初の指が離された座標のみです。2本め以降の指が離された座標ではない事に注意してください。
また、これはAndroidModeのバグかもしれませんが、mouseReleased メソッドはマルチタッチ状態で指を離した場合、イベントを拾わないことがあります。
mousePressed メソッドと対になるような動作をさせる目的で mouseReleased メソッドを利用すると、思わぬ不具合を引き起こす可能性があります。
例えば、mousePressed メソッドで、なにかの変数( touchCount など )を加算し、mouseReleased メソッドで減算するような処理は、全ての指がスクリーンから離れても touchCount 変数が 0 にならない事があります。
エミュレータで実行した場合は、マウスの右ボタンリリースには反応しません。
イベントの発生ルール
JavaModeではMouseEventを引数にとるメソッドと、引数なしのメソッドを両方定義すると、引数なしのメソッドは呼び出されませんでした。
たとえば、
1 2 3 4 5 6 7 |
void mousePressed(){ println( "hoge" ); //<=JavaModeでは動作しない } void mousePressed(MouseEvent ev){ println( "fuga" ); } |
のようなコーディングをすると、マウスボタンを押下しても hoge は表示されません。
AndroidModeの場合は、両方共呼び出されます。上記例であれば、hoge も fuga も表示されることになります。
JavaMode時に比べて、動作に違いがあるので注意して下さい。
グローバル変数の更新タイミング
JavaModeでは、実行結果ウィンドウの上でマウスカーソルを動かすと、マウスボタンを押下するか否かにかかわらず mouseX、mouseY 変数にマウスカーソルの座標が記録されました。
しかしAndroidModeでは、タッチ開始、スワイプ、タッチ終了の各イベントが発生した場合のみ、これらの変数が更新されます。
mouseX、mouseY 変数は便利なので、多用していた人もいるかと思いますが、JavaMode時とは変数の更新タイミングが異なるので、注意が必要です。
また、JavaModeでマウスボタンが押下された時に True となった mousePressed 変数は、タッチ開始時に True となり、タッチ終了時に Falseとなります。
これらのグローバル変数は、いずれもマルチタッチには対応していません。
特に mousePressed 変数は、mouseReleased メソッドと同様の問題を抱えているので、注意してください。
つまりマルチタッチ状態から指を離すと、全部の指が離れているにもかかわらず、mousePressed 変数が True のままとなる事があります(泣)。
MouseEventクラス
イベントに渡されてくる MouseEvent クラスは、各メソッドの動作が、JavaMode時とは大きく異なります。
getX( )、getY( ) メソッドは、同じように利用できます。
getAction( ) には、 MouseEvent.PRESS、MouseEvent.DRAG、MouseEvent.RELEASE のいずれかが戻されます。
getButton( ) には常に 0が、getClickCount( ) は常に 1 が戻されます。特にgetClickCount( )については、マルチタッチしていても1が戻されますので、注意して下さい。
キーボードに依存しているMouseEvent クラスの isShiftDown( ) や isControlDown( ) メソッドは、常に False を戻します。
【関連記事】
サンプルプログラム
各イベントを検出する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import android.util.Log; /** * AndroidMode MouseEvent Test * @author MSLABO */ final String TAG = "MouseEventTest"; ArrayList<PVector> touchP; void setup(){ fullScreen(); touchP = new ArrayList<PVector>(); } void draw(){ background(255); //タッチまたはスワイプ中の位置に青丸を描く for( PVector point: touchP ){ //青丸を描く fill( color( 100,100,255 ) ); ellipse( point.x, point.y, 50, 50 ); } } void mousePressed(){ //タッチされた座標を覚える touchP.add( new PVector( mouseX, mouseY )); Log.d( TAG, "touch" ); } void mouseDragged (){ //スワイプ中の座標を覚える touchP.add( new PVector( mouseX, mouseY )); Log.d( TAG, "swipe" ); } void mouseReleased(){ //指が離れたら座標記録を初期化する touchP.clear(); Log.d( TAG, "release" ); } |
タッチまたはスワイプされた座標を記録し、その位置に青丸を描きます。
詳細で解説したように、マルチタッチには対応していません。注意してください。
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。