2015年12月14日
ProcessingのAndroidModeでマルチタッチを実現する
ProcessingのAndroidModeでマルチタッチを実現する方法を紹介します。Processingに限らずAndroidなどのスマートフォンでアプリを開発するときにマルチタッチを実現するというのは重要なポイントだと思いますが調べてパッと出てきてパッとわかる情報がなかったのでメモしておこうと思います。使用しているのはProcessing3です。
具体的には以下のスクリーンショットのようにタッチした各点の座標をとれる状態を目指します。
スマートフォンでマルチタッチを実現したときのスクリーンショット
実現方法とプログラムです。
import android.view.MotionEvent; //MotionEventを使うのでインポート
MotionEventを使用するのでインポートしておきます。詳しく知りたい方は公式リファレンスのこちらをどうぞ→MotionEvent
英語ですがそれほど難しくはないと思います。だいぶ参考にしました。
ArrayList points; //取得した各点の座標を格納しておく配列を宣言
PVector point; //表示する点の情報を一時的に格納しておくための変数
それぞれコメントで記したとおりの役割をします。
void setup(){
size(displayWidth,displayHeight); //画面のサイズに合わせたスケッチを作成
points = new ArrayList(); //配列を作成//中身は空
}
スケッチのサイズは使用するAndroid端末の画面に合わせます。
public boolean surfaceTouchEvent(MotionEvent event){
points.clear(); //配列を空にする
for(int i = 0; i < event.getPointerCount(); i++){
points.add(new PVector(event.getX(i),event.getY(i))); //タッチされている点それぞれの座標を取得し配列に追加する
}
if(event.getActionMasked() == MotionEvent.ACTION_UP){
points.clear(); //画面から反応がなくなれば配列を空にする
}
return super.surfaceTouchEvent(event); //superクラス
}
surfaceTouchEventは画面がタッチされているときに呼び出されます(間違ってたらすみません)。MotionEventのデータはデバイスに依存しますがタッチ操作やマウスの操作、トラックボールなどの操作の座標やタッチの状態など様々な情報が格納されています。ここから必要なメソッドを使用して情報を取り出していきます。
まず最初にタッチしている各点の情報を格納している配列を空にします。これがないとタッチした点の情報が配列に次々に格納されていきメモリを圧迫して動作を重くするとともに画面がカオスなことになります。以下の写真はpoints.clear(); をコメントアウトして実行し、ドラッグしてみた時のスクリーンショットです。
ドラッグすることで追加された新たなタッチしている座標の情報が次々に配列に格納され、それらがすべて表示された状態です。複数の指でドラッグ続けるとやがて動作が重くなるのがわかると思います。
次のfor文でタッチしている点の座標を取得して配列に格納しています。event.getPointerCount()で画面をタッチしている点の数を取得しています。そして添え字0からevent.getPointerCount()-1までの点の座標をgetX(i)とgetY(i)で取得し、PVectorとして配列に格納していってます。
その次のif文のevent.getActionMasked()ではタッチしている点の状態を取得しています。MotionEvent.ACTION_UPはすべての指が離れた時の値です。つまりここではすべての指が画面から離れたかどうかを確認しています。そしてすべての指が画面から離れたことが確認できたらpoints.clear();で配列を空にしています。この部分がないと画面をタッチすることをやめても最後に指を離した点の座標が配列に残るため、最初のスクリーンショットの例では最後に指を離した点のところだけタッチしていないにもかかわらず円と座標が表示され続けることになります。
void draw(){
background(0); //画面を黒でリセットしています
//points.size()で配列に格納されている点の数を取得しています
//添え字0からpoints.size()-1までの座標を取得します
for(int i = 0; i < points.size(); i++){
point = (PVector)points.get(i); //配列から添え字の情報を取り出しPVectorにキャストして一時変数に格納しています
stroke(0,255,0); //色を緑にしています
noFill(); //円の内部を塗りつぶさないようにします
ellipse(point.x,point.y,100,100); //円を描いています//point.xとpoint.yで一時変数に格納した点の座標を取り出しています
textSize(32); //表示する点の座標の文字の大きさです
text("x:"+point.x+" y:"+point.y,point.x,point.y); //座標を表示しています
}
}
draw()関数の説明です。ここでは上で書いた部分を使ってタッチされている点に円と座標を表示しているだけです。画面をリセットしタッチしている各点を表示しています。for文の points.size()でタッチされている点の数を取得しています。たとえば4点がタッチされていればこの値は4となり、添え字0から3までの点の座標を取得します。それぞれの添え字の座標を一時変数のpointに格納しellipseで円を描画しています。そしてtextで座標を表示しています。
以上がProcessingのAndroidModeでマルチタッチを実現する方法です。必要なことはすべて書いたのであとはいくらでも応用できると思います。
具体的には以下のスクリーンショットのようにタッチした各点の座標をとれる状態を目指します。
スマートフォンでマルチタッチを実現したときのスクリーンショット
実現方法とプログラムです。
import android.view.MotionEvent; //MotionEventを使うのでインポート
MotionEventを使用するのでインポートしておきます。詳しく知りたい方は公式リファレンスのこちらをどうぞ→MotionEvent
英語ですがそれほど難しくはないと思います。だいぶ参考にしました。
ArrayList points; //取得した各点の座標を格納しておく配列を宣言
PVector point; //表示する点の情報を一時的に格納しておくための変数
それぞれコメントで記したとおりの役割をします。
void setup(){
size(displayWidth,displayHeight); //画面のサイズに合わせたスケッチを作成
points = new ArrayList(); //配列を作成//中身は空
}
スケッチのサイズは使用するAndroid端末の画面に合わせます。
public boolean surfaceTouchEvent(MotionEvent event){
points.clear(); //配列を空にする
for(int i = 0; i < event.getPointerCount(); i++){
points.add(new PVector(event.getX(i),event.getY(i))); //タッチされている点それぞれの座標を取得し配列に追加する
}
if(event.getActionMasked() == MotionEvent.ACTION_UP){
points.clear(); //画面から反応がなくなれば配列を空にする
}
return super.surfaceTouchEvent(event); //superクラス
}
surfaceTouchEventは画面がタッチされているときに呼び出されます(間違ってたらすみません)。MotionEventのデータはデバイスに依存しますがタッチ操作やマウスの操作、トラックボールなどの操作の座標やタッチの状態など様々な情報が格納されています。ここから必要なメソッドを使用して情報を取り出していきます。
まず最初にタッチしている各点の情報を格納している配列を空にします。これがないとタッチした点の情報が配列に次々に格納されていきメモリを圧迫して動作を重くするとともに画面がカオスなことになります。以下の写真はpoints.clear(); をコメントアウトして実行し、ドラッグしてみた時のスクリーンショットです。
ドラッグすることで追加された新たなタッチしている座標の情報が次々に配列に格納され、それらがすべて表示された状態です。複数の指でドラッグ続けるとやがて動作が重くなるのがわかると思います。
次のfor文でタッチしている点の座標を取得して配列に格納しています。event.getPointerCount()で画面をタッチしている点の数を取得しています。そして添え字0からevent.getPointerCount()-1までの点の座標をgetX(i)とgetY(i)で取得し、PVectorとして配列に格納していってます。
その次のif文のevent.getActionMasked()ではタッチしている点の状態を取得しています。MotionEvent.ACTION_UPはすべての指が離れた時の値です。つまりここではすべての指が画面から離れたかどうかを確認しています。そしてすべての指が画面から離れたことが確認できたらpoints.clear();で配列を空にしています。この部分がないと画面をタッチすることをやめても最後に指を離した点の座標が配列に残るため、最初のスクリーンショットの例では最後に指を離した点のところだけタッチしていないにもかかわらず円と座標が表示され続けることになります。
void draw(){
background(0); //画面を黒でリセットしています
//points.size()で配列に格納されている点の数を取得しています
//添え字0からpoints.size()-1までの座標を取得します
for(int i = 0; i < points.size(); i++){
point = (PVector)points.get(i); //配列から添え字の情報を取り出しPVectorにキャストして一時変数に格納しています
stroke(0,255,0); //色を緑にしています
noFill(); //円の内部を塗りつぶさないようにします
ellipse(point.x,point.y,100,100); //円を描いています//point.xとpoint.yで一時変数に格納した点の座標を取り出しています
textSize(32); //表示する点の座標の文字の大きさです
text("x:"+point.x+" y:"+point.y,point.x,point.y); //座標を表示しています
}
}
draw()関数の説明です。ここでは上で書いた部分を使ってタッチされている点に円と座標を表示しているだけです。画面をリセットしタッチしている各点を表示しています。for文の points.size()でタッチされている点の数を取得しています。たとえば4点がタッチされていればこの値は4となり、添え字0から3までの点の座標を取得します。それぞれの添え字の座標を一時変数のpointに格納しellipseで円を描画しています。そしてtextで座標を表示しています。
以上がProcessingのAndroidModeでマルチタッチを実現する方法です。必要なことはすべて書いたのであとはいくらでも応用できると思います。
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/4521329
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック