モーリーのメモ

アプリ開発等(プログラミング、CG作成)、興味を持ったことを実践してまとめるブログです。

モーリーのメモ

タッチイベントの設定:Cocos2d-x v3.7(JavaScript)

 ノード(シーン、レイヤー、スプライト等)が、タッチイベントを受け取れるように設定します。
 タッチイベントとして、下記の処理を設定します。

  • タッチ開始時の処理
  • タッチ中(スワイプ中)の処理
    • タッチ位置が変わる度に処理されます。
    • タッチ位置が変わらない(タッチして離すだけ)の場合は処理されません。
  • タッチ終了時処理
  • タッチキャンセル時処理

 使用しているCocos2d-xのバージョンは3.7です。

タッチイベントの設定

 例として、レイヤーにタッチイベントを設定しています。

シングルタッチの設定例

var HelloWorldLayer = cc.Layer.extend({
	sprite:null,
	ctor:function () {
		this._super();
		var size = cc.winSize;
		var mainscene = ccs.load(res.MainScene_json);
		this.addChild(mainscene.node);

		cc.eventManager.addListener({ // タッチイベントを登録
			event: cc.EventListener.TOUCH_ONE_BY_ONE, // シングルタッチのみ対応
        		swallowTouches:false, // 以降のノードにタッチイベントを渡す
        		onTouchBegan:this.onTouchBegan.bind(this), // タッチ開始時
        		onTouchMoved:this.onTouchMoved.bind(this), // タッチ中
        		onTouchEnded:this.onTouchEnded.bind(this), // タッチ終了時
        		onTouchCanceled:this.onTouchCancelled.bind(this), // タッチキャンセル時
        	}, this);

		return true;
	},
	onTouchBegan:function(touch, event){ // タッチ開始時処理
		// タッチ開始時処理
		return true;
	},
	onTouchMoved:function(touch, event){ // タッチ中の処理
		// タッチ中の処理
	},
	onTouchEnded:function(touch, event){ // タッチ終了時処理
		// タッチ終了時処理
	},
	onTouchCancelled:function(touch, event){ // タッチキャンセル時処理
		// タッチキャンセル時処理
	}
});

マルチタッチの設定例

var HelloWorldLayer = cc.Layer.extend({
	sprite:null,
	ctor:function () {
		this._super();
        	var size = cc.winSize;
        	var mainscene = ccs.load(res.MainScene_json);
        	this.addChild(mainscene.node);
		
		cc.eventManager.addListener({ // タッチイベントを登録
			event: cc.EventListener.TOUCH_ALL_AT_ONCE, // マルチタッチ対応
			onTouchesBegan:this.onTouchesBegan.bind(this), // タッチ開始時
			onTouchesMoved:this.onTouchesMoved.bind(this), // タッチ中
			onTouchesEnded:this.onTouchesEnded.bind(this), // タッチ終了時
			onTouchesCanceled:this.onTouchesCancelled.bind(this), // タッチキャンセル時
		}, this);

		return true;
	},
	onTouchesBegan:function(touches, event){ // タッチ開始時処理
		// タッチ開始時処理
		var location = touches[0].getLocation(); // 最初のタッチの位置を取得(処理の例)
		return true;
	},
	onTouchesMoved:function(touches, event){ // タッチ中の処理
		// タッチ中の処理
		return;
	},
	onTouchesEnded:function(touches, event){ // タッチ終了時処理
    		// タッチ終了時処理
	},
	onTouchesCancelled:function(touches, event){ // タッチキャンセル時処理
		// タッチキャンセル時処理
	}
});

シングルタッチとマルチタッチの違い

 シングルタッチのみ処理する場合は、『event: cc.EventListener.TOUCH_ONE_BY_ONE』とします。
 マルチタッチの処理をする場合は、『event: cc.EventListener.TOUCH_ALL_AT_ONCE』とします。

『onTouch◯◯:』と『onTouches◯◯:』

 シングルタッチとマルチタッチで、下記の部分が変わります。
 シングルタッチの場合、『onTouch◯◯:〜』の部分が単数形です。
・『onTouchBegan:〜』
・『onTouchMoved:〜』
・『onTouchEnded:〜』
・『onTouchCanceled:〜』
 マルチタッチの場合、『onTouches◯◯:〜』の部分が複数形です。
・『onTouchesBegan:〜』
・『onTouchesMoved:〜』
・『onTouchesEnded:〜』
・『onTouchesCanceled:〜』

『swallowTouches:〜』

 ノード(シーン、レイヤー、スプライト等)が複数ある場合、それぞれが順にタッチイベントを受け取りますが、『swallowTouches:true』とすると、このノードより以降のノードは、タッチイベントを受け取れなくなります。
 シングルタッチの場合のみ有効です。

タッチイベントを受け取る順序

全てシングルタッチまたはマルチタッチの場合

 ①→②→③→④→⑤の順にタッチイベントを受け取ります。
 下の例の場合は、③が『swallowTouches:true』にしているため、④と⑤はタッチイベントを受け取れません。

①   ┏孫スプライト2      :『swallowTouches:false』:シングルタッチ
② ┏子レイヤー2(Zオーダー=1):『swallowTouches:false』:シングルタッチ
③ ┃ ┏孫スプライト1      :『swallowTouches:true』 :シングルタッチ
④ ┣子レイヤー1(Zオーダー=0):『swallowTouches:false』:シングルタッチ
⑤親シーン             :『swallowTouches:false』:シングルタッチ
シングルタッチとマルチタッチが混在する場合

 ②→④→⑤→①→③の順にタッチイベントを受け取ります。シングルタッチのほうが先にタッチイベントを受け取ります。
 下の例の場合は、④が『swallowTouches:true』にしているため、⑤①③はタッチイベントを受け取れません。

①   ┏孫スプライト2      :             :マルチタッチ
② ┏子レイヤー2(Zオーダー=1):『swallowTouches:false』:シングルタッチ
③ ┃ ┏孫スプライト1      :             :マルチタッチ
④ ┣子レイヤー1(Zオーダー=0):『swallowTouches:true』 :シングルタッチ
⑤親シーン             :『swallowTouches:false』:シングルタッチ

『this.~』を使うためには、『〜.bind(this)』が必要

 『onTouchBegan:this.onTouchBegan.bind(this)』のように最後に『.bind(this)』をつけることで、『onTouchBegan:function(touch, event){}』内で、『this.〜』が使えるようになります。逆に言えば付けないと使えません。

『〜.bind(this)』を使わない方法(『 event.getCurrentTarget()』を使用)

 下記のようにすれば、『target』に『自身のノード』が取得できるので『target.〜』が『this.〜』と同意になります。

    onTouchBegan:function(touch, event){ // タッチ開始時処理
        var target = event.getCurrentTarget();
    	return true;
    },

『onTouchBegan()』では『return true』または『return false』が必要

『onTouchBegan:function(touch, event){}』は『boolean値(trueまたはfalse)』を返さないとエラーになります。

『return false』でタッチイベントを中断

 『onTouchBegan:function(touch, event){}』で『return false』とすると、タッチイベントが中断され、『onTouchMoved』、『onTouchEnded』が処理されません。
 自身のノードのタッチイベントが中断されるだけで、下のノードのタッチイベントは影響を受けません。
 
以上です。

あとがき

 『onTouchBegan:function(touch, event){}』の中で、『this.〜』がエラーになったのは原因がわかりにくかったです。また、マルチタッチの場合に『touches』と複数形にしないと行けないのもわかりにくかったです。
 タッチの受け取り順は仕様を見たわけではなく、『Cocos Code IDE』のデバッグ実行でログを出力しながら確かめました。シングルタッチとマルチタッチの優先順位はなにか不思議ですね。ただ実際にはこんな使い方はなかなかやらないとは思いますが;なお、ブラウザでの実行等、他の実行環境ではでは試していません。変わらないことを祈ります。