タッチイベントをforループで作った場合

最近は勉強も兼ねてjavascriptを触っている。

 

今日試したのは以下の文。

for(var i = 0; i < 16; i++){

   document.getElementById('id'+i).addEventListener('click', function() {

      checkPosition(i);

   });

}

 こんな風にしたときに、関数に渡したiが上手くいかない模様。

要はそのidがタッチされたらその位置を調べて欲しいんだが、良く分からない状態になっている。

 

コンソールに表示してみたら、i=16になっていた。

なんじゃそりゃ。

 

横着せずに1つずつタッチイベントを作るべきか。

 

フレーム毎の処理、衝突時の処理

またメモ。

 

◇フレーム毎の処理

init()内

this->schedule(schedule_selector(HelloWorld::maiFrame));

 

こうすると、フレーム毎にHelloWorld::maiFrameが呼ばれる。

(綴りはわざとね

 

キャラがゴールに到達したときの判定や、時間を測りたいときなんかに。

秒数指定も出来るので、一定間隔で処理させることも可能。

 

 

◇衝突時の判定

init内

auto contactListener = EventListenerPhysicsContact::create();

contactListener->onContactBeginCC_CALLBACK_1(HelloWorld::onContactBegin, this);

this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);

物理演算世界で使用。

物体がぶつかるとHelloWorld::onContactBeginが呼ばれる。

 

bool HelloWorld::onContactBegin(PhysicsContact& contact)

関数の頭はこんな感じ。

PhysicsContact型というのに色々ステータスが入っているのだろうか。

 

ちなみにこれだけではここまで来ない。

衝突時に処理させたい2つのパーマネントに以下の仕込みを行う。

 

pBall1->setContactTestBitmask(1);

pBall2->setContactTestBitmask(1);

こうすると衝突時にHelloWorld::onContactBeginが走る。

ただし、物理的にはぶつからなくなる様子。

ボールがすり抜けてしまう。

 

解決策知ってる方いたら教えて。

 

タッチ処理や物理演算絡みメモ

◇タッチ処理

init内

auto listener = EventListenerTouchOneByOne::create();

listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);

this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

この辺誰かに解説してほしい。

「listener」(りすなー)はタッチイベントを受信している様子。

で、タッチ開始時(onTouchBegan)に「HelloWorld::onTouchBegan」を呼ぶように仕込まれている?

最後に現在のシーンにイベントとして追加されているのかもしれない。

違ったら誰か教えて。

 

関数側

bool HelloWorld::onTouchBegan(cocos2d::Touch* pTouch, cocos2d::Event* pEvent)

「pTouch」にはタッチした位置が入ってくるはず。「pEvent」は何やろうね。

 

 

◇壁や床の作成

void HelloWorld::wallsCast()に分離。

 

PhysicsBodyは一つのパーマネントに一つ作った方が良いようだ。

使い回そうとしたら当たり判定消えた。

 

auto material = PHYSICSBODY_MATERIAL_DEFAULT;

こっちは使い回せた。

 

 

◇ボールの作成

球状の当たり判定。

auto pBall = PhysicsBody::createCircle(10.0f);

数値は半径。

球状に色塗りは出来ないため、別途pngを用意。

 

上手く飛ばすため

pBall->setMass(1.0f);

で重さを追加。

 

ball->setTag(1);

タグを仕込んどくと幸せになれる。

 

 

◇ボール動かす処理

 onTouchBegan内

Sprite* ball = (Sprite*)this->getChildByTag(1);

これでさっきタグをセットしたボールを呼べる。

 

ball->getPhysicsBody()->applyImpulse(force);

ボールに「force」分の力積をかける。

連打でボールが吹っ飛ばないように、位置を見てforceを0にしてみた。

あまりスマートでは無い。

 

 

◇クリア処理

ボールがある位置よりも下に行くとクリアに。

 

auto *retryLabel = MenuItemFont::create("Retry", CC_CALLBACK_1(HelloWorld::menuRetryButton, this));

リトライ用ボタンを作る。

「Retry」という文字。

押されると「HelloWorld::menuRetryButton」を呼び出す。

 

auto menu = Menu::create(retryLabel, NULL);

上記ボタンは「MenuItemFont」を使用しているからか、このMenuの中に入れて表示する様子。

ただし位置はretryLabelにセットする。

 

 

◇リトライ処理

menuRetryButton内

Director::getInstance()->getEventDispatcher()->removeAllEventListeners();

auto gameScene = (Scene*)HelloWorld::createScene();

Director::getInstance()->replaceScene(gameScene);

 全てのイベントを一度抹消。

「gameScene」に最初のシーンをセット。

そして最初のシーンに移動。

 

 

 

いつもの通り中途半端。

ver3.0 iOS