読者です 読者をやめる 読者になる 読者になる

フニゲの開発日記

Electronとか...

描画順序の制御とイベントリスナー

Cocos2d-JS

 新しいCocos2d-JSではこれまでのsetLocalZOrder()に加えてsetGlobalZOrder()ができたのだが、web版ではsetGlobalZOrder()は動かない。互換性のためにメソッドは存在するが、ブラウザでは何の効果もないので注意。とりあえず忘れよう。

 新しいイベントリスナーはサンプルを書いて慣れるのが一番だと思う。……ていうか、前はどうやっていたのか、慣れてしまうとよく思い出せない。

var layer1, layer2, layer3;

var MyScene = cc.Scene.extend({
    onEnter:function () {
        this._super();

        // 3色のプレートを画面に配置する
        // どうでもいいけどシアンの定数が定義されていないような
        layer1 = new cc.LayerColor(cc.color(0, 255, 255, 255), 200, 200);
        layer1.setPosition(0, 200);
        layer1.setTag("シアンです");
        this.addChild(layer1, 10);

        // マゼンタ
        layer2 = new cc.LayerColor(cc.color.MAGENTA, 200, 200);
        layer2.setPosition(100, 100);
        layer2.setTag("マゼンタです");
        this.addChild(layer2, 20);

        // 黄色
        layer3 = new cc.LayerColor(cc.color.YELLOW, 200, 200);
        layer3.setPosition(-50, -50);
        layer3.setTag("黄色ですよ");
        layer2.addChild(layer3, 1);

        // イベントリスナーを各プレートにつけてみる
        cc.eventManager.addListener(listener, layer1);
        cc.eventManager.addListener(listener.clone(), layer2);
        cc.eventManager.addListener(listener.clone(), layer3);
    }
});

 イベントリスナーは使い回しができないことに注意。複数のオブジェクトにaddEventListenerする時は、cloneしてからつける。オブジェクトが削除されるときはイベントリスナーも勝手に一緒に削除してくれるので、まあそういうトレードオフなのだと思う。

 このへんは公式のイベントリスナーのサンプルの丸パクリです。

f:id:funige:20150320142736p:plain

 レイヤーに限らず、どんなオブジェクトにもイベントリスナーはつけられるのだが、タッチした位置の当たり判定を自動でやってくれるわけではない。画面のどこをタップしたかに無関係に、ただ描画順序がいちばん上の物から下に順番にlistenerが呼ばれるだけだ。この場合だと、黄色→マゼンタ→シアン。

 イベントリスナーの中身はこんな感じ。

var listener = cc.EventListener.create({
    event: cc.EventListener.TOUCH_ONE_BY_ONE,
    swallowTouches: true,
    onTouchBegan: function (touch, event) {
        var target = event.getCurrentTarget();
        
        var locationInNode = target.convertToNodeSpace(touch.getLocation());
        var s = target.getContentSize();
        var rect = cc.rect(0, 0, s.width, s.height);

        // タッチした位置が内側かどうか判定
        if (cc.rectContainsPoint(rect, locationInNode)) {
            cc.log(target.getTag() + " => hit");
            return true;
        }
        cc.log(target.getTag() + " => not hit");
        return false;
    },
});

 イベントリスナーにonTouchMovedとonTouchEndedも追加してみる。

    onTouchMoved: function (touch, event) {
        var target = event.getCurrentTarget();
        var delta = touch.getDelta();
        target.x += delta.x;
        target.y += delta.y;
    },

    onTouchEnded: function (touch, event) {
    },

 onTouchMovedやonTouchEndedはonTouchBeganでtrueを返したリスナーにだけ送られるので、この2つは当たり判定を書く必要がない。

 サンプル

広告を非表示にする