AndEngineでロングタップを実装する

 現在作成中のスライドパズルは、前々回に貼り付けたスクリーンショットのとおり、画面いっぱいに画像を表示しています。
 なので、ロングタップでメニュー画面を表示させたいと考えたのですね。
 もちろん、普通のタップ時はパネルがスライドしなくてはなりません。
 どうしたら良いの?
 
 こんなことは、作り始める前に考えておきましょう。
 
 グーグル先生に尋ねたところ、幸いにも AndEngine GLES2-AnchorCenter にはロングタップを取得するクラスがあるようです。
 実装してみました。
 はまりました。
 
 最終的には、こちらのコード。AndEngine の Scene を継承したサブクラスでの処理が前提ね。

import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.input.touch.TouchEvent;
import org.andengine.input.touch.detector.ContinuousHoldDetector;
import org.andengine.input.touch.detector.HoldDetector;
import org.andengine.input.touch.detector.HoldDetector.IHoldDetectorListener;

public class GameScene extends Scene implements IOnSceneTouchListener, IHoldDetectorListener{
	private ContinuousHoldDetector continuousHoldDetector;
	private boolean isHold = false;
	private boolean isTouchOK = true;
	private long holdTime = 200;
	
	GameScene(){
		setOnSceneTouchListener(this);
		setTouchAreaBindingOnActionDownEnabled(true);
		continuousHoldDetector = new ContinuousHoldDetector(this);
		registerUpdateHandler(continuousHoldDetector);
	}
	
	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent){
		if(isTouchOK){
			// ロングタップ処理後は isHold を放置してここでリセット処理する
			if(isHold){
				isHold = false;
				continuousHoldDetector.reset(); // リセットしないとホールドタイムが累積されてしまう
			}
			continuousHoldDetector.onTouchEvent(pSceneTouchEvent);
			// ロングタップされていない場合の処理
			if(!isHold){
				if (pSceneTouchEvent.isActionUp()){
					isTouchOK = false; // これはなくてもイイのかな
					// タップ時の処理
					// 処理が終わったら isTouchOK = true とする
				}
			}
		}
		return true;
	}
	
	@Override
	public void onHoldStarted(HoldDetector pHoldDetector, int pPointerID, float pHoldX, float pHoldY){
		isTouchOK = false;
 	}

	@Override
	public void onHold(HoldDetector pHoldDetector, long pHoldTimeMilliseconds, int pPointerID, float pHoldX, float pHoldY){
		// onHold() はロングタップ中何度も呼ばれるので、規定時間経過後に1度だけ if 内処理に移る
		if(!isHold && pHoldTimeMilliseconds > holdTime){
			isHold = true;
			// ロングタップ時の処理
			// 処理が終わったら isTouchOK = true とする
			// 処理が終わっても isHold は true のまま
		}
	}
        
	@Override
	public void onHoldFinished(HoldDetector pHoldDetector, long pHoldTimeMilliseconds, int pPointerID, float pHoldX, float pHoldY){
	}
}

と、まあ onHold() の呼び出しに応じて何度もロングタップ処理してしまうわ、continuousHoldDetector のリセットに思い至らず、二度目のタップ時は間を置かずロングタップ処理に入りパネルが動かないわで、相当な時間を費やしました。
 
 onSceneTouchEvent() 内の短いタップ時の処理は onHoldFinished() 内に入れても動く気がするのですが、このロジックで現に動いているので試してはいません。

 「現に動いている」というのが肝要です。

パロディことわざをつぶやく

 スライドパズル化した画像をツイッターに添付できるようにしようと思って調べてみると、画像添付のコードがちょい面倒そう。
 
 寄り道しちゃう。
 
 テキストを流し込んでのつぶやきは簡単なので、「パロディことわざ」に実装してみました。

    public void startTwitter(String message){
	    Intent intent = new Intent(Intent.ACTION_VIEW);
	    intent.setData(Uri.parse("twitter://post/?text=" + Uri.encode(" #ParodyKotowaza \n" + message + "\n")));
	    startActivity(intent);
    }
    
    public boolean isInstalledApp(String uri){
    	PackageManager pm = getPackageManager();
    	boolean isInstalled = false;
    	try{
    		pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
    		isInstalled = true;
    	}
        catch (Exception e){}
    	return isInstalled;
    }

 isInstallApp(String uri)でツイッター標準アプリのあるなしを確認して、startTwitter(String message)でつぶやきます。

    boolean isTwitter = activity.isInstalledApp("com.twitter.android");
    if(isTwitter){
        activity.runOnUiThread(new Runnable(){
            @Override
            public void run(){
                activity.startTwitter(kotowaza[i].getKotowaza() + "(" + kotowaza[i].getKotowazaYomi() + ")");
            }
        });
    }

 AndengineのSceneからの呼び出しは、別スレッドにしないと落ちるので気をつけましょう。
 
と、簡単にできたので「パロディことわざ」をバージョンアップし、早速つぶやいています。
 @chabaoriで #ParodyKotowaza のハッシュタグを付けてつぶやいております。

現在作成中のアプリは・・・

 前回の記事までは、和文縦書きを頑張っていた私でありますが、とうに興味を失くしています。
 device-2014-05-26-004356
 8行目の「英雄」のルビ「ヒーロー」の分割を嫌って7行目から追い出し、7行目の字間を調整しています。あぁ、面倒・・・。やめよ・・・。
 という訳です。
 
 
 現在の興味の中心は、一向にダウンロード数が上がらないスライドパズルの改良です。
device-2014-05-26-003621
 撮った写真をその場でスライドパズル化します。
device-2014-05-26-003656
 正しく並べ替えることは、とてもできない程細かくもできます。この3倍まで細かくする予定。
 正解手順の画像への埋め込みにも成功したので、あんな写真やこんな写真を微細スライドパズルにして配布することもできます。この辺りの機能を有料化しようかと。
 完成までには、まだまだなのですが、山場は越えたので途中経過報告です。
 
 
 寝かしているゲームも完成させねばね。
device-2014-05-26-004543
 ドット絵のアニメーションと問題作りが大変なのよ。