bool CCScene::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { CC_SAFE_RELEASE_NULL(m_touchNode); const CCPoint p = pTouch->getLocation(); CCObject *node; CCNode *touchNode = NULL; CCNode *checkNode = NULL; bool visible = true; sortAllTouchableNodes(); CCARRAY_FOREACH(m_touchableNodes, node) { checkNode = touchNode = dynamic_cast<CCNode*>(node); // check node is visible visible = true; do { visible = visible && checkNode->isVisible(); checkNode = checkNode->getParent(); } while (checkNode && visible); if (!visible) continue; const CCRect boundingBox = touchNode->getCascadeBoundingBox(); if (boundingBox.containsPoint(p)) { touchNode->retain(); bool ret = touchNode->ccTouchBegan(pTouch, pEvent); if (ret && touchNode->isRunning()) { m_touchNode = touchNode; m_touchNode->retain(); } touchNode->release(); if (ret) return true; } }
void CCScene::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) { if (!m_touchDispatchingEnabled) return; // cleanup m_touchingTargets->removeAllObjects(); // sort touchable nodes sortAllTouchableNodes(m_touchableNodes); // find touching target bool isTouchable = true; CCObject *obj = NULL; CCNode *node = NULL; CCNode *checkTouchableNode = NULL; CCTouchTargetNode *touchTarget = NULL; CCARRAY_FOREACH(m_touchableNodes, obj) { checkTouchableNode = node = dynamic_cast<CCNode*>(obj); // check node is visible and capturing enabled isTouchable = true; do { isTouchable = isTouchable && checkTouchableNode->isRunning() && checkTouchableNode->isVisible() && checkTouchableNode->isTouchCaptureEnabled(); checkTouchableNode = checkTouchableNode->getParent(); } while (checkTouchableNode && isTouchable); if (!isTouchable) continue; // prepare for touch testing touchTarget = NULL; const CCRect boundingBox = node->getCascadeBoundingBox(); // set touch target CCTouch *touch = NULL; for (CCSetIterator it = pTouches->begin(); it != pTouches->end(); ++it) { touch = (CCTouch*)*it; const CCPoint touchPoint = touch->getLocation(); if (boundingBox.containsPoint(touchPoint)) { if (!touchTarget) { touchTarget = CCTouchTargetNode::create(node); } if (touchTarget->getTouchMode() == kCCTouchesOneByOne) { touchTarget->setTouchId(touch->getID()); break; } } } if (!touchTarget) { // touch points not in current target, try to next continue; } // try to dispatching event CCArray *path = CCArray::createWithCapacity(10); node = touchTarget->getNode(); do { path->addObject(node); node = node->getParent(); } while (node != NULL && node != this); // phase: capturing // from parent to child bool dispatchingContinue = true; int touchMode = touchTarget->getTouchMode(); for (int i = path->count() - 1; dispatchingContinue && i >= 0; --i) { node = dynamic_cast<CCNode*>(path->objectAtIndex(i)); if (touchMode == kCCTouchesAllAtOnce) { node->ccTouchesCaptureBegan(pTouches, touchTarget->getNode()); } else { dispatchingContinue = node->ccTouchCaptureBegan(touchTarget->findTouch(pTouches), touchTarget->getNode()); } } if (!dispatchingContinue) { // the target stop dispatching, try to next continue; } // phase: targeting node = touchTarget->getNode(); bool ret = true; if (touchMode == kCCTouchesAllAtOnce) { node->ccTouchesBegan(pTouches, pEvent); } else { ret = node->ccTouchBegan(touchTarget->findTouch(pTouches), pEvent); } if (ret) { m_touchingTargets->addObject(touchTarget); // CCLOG("ADD TOUCH TARGET [%p]", touchTarget); } if (node->isTouchSwallowEnabled()) { // target swallow touch event, stop dispatching break; } // continue dispatching, try to next }