Hello All,
I am trying to make a button out of spine Skeleton animation in cocos2dx. Its a simple, flat animation, that repeats over and over again. Here what I am doing
spAtlas* _atlasIcon;
spAttachmentLoader* _attachmentLoaderIcon;
spSkeletonData* _skeletonDataIcon;
spAnimationStateData* _stateDataIcon;
_atlasIcon=spAtlas_createFromFile("icon.atlas", 0);
_attachmentLoaderIcon=(spAttachmentLoader*)Cocos2dAttachmentLoader_create(_atlasIcon);
spSkeletonJson* jsonIcon= spSkeletonJson_createWithLoader(_attachmentLoaderIcon);
jsonIcon->scale = 1.0f;
_skeletonDataIcon=spSkeletonJson_readSkeletonDataFile(jsonIcon, "icon.json");
spSkeletonJson_dispose(jsonIcon);
_stateDataIcon=spAnimationStateData_create(_skeletonDataIcon);
auto spinner= spine::SkeletonAnimation::createWithData(_skeletonDataIcon, false);
spinner->addAnimation(0, "animation", true);
spinner->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
spinner->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
this->addChild(spinner, 100);
auto listenerSpinner = cocos2d::EventListenerTouchOneByOne::create();
listenerSpinner->setSwallowTouches(true);
listenerSpinner->onTouchBegan = [&, spinner](cocos2d::Touch* touch, cocos2d::Event* event)
{
auto target = static_cast<spine::SkeletonAnimation*>(event->getCurrentTarget());
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
auto s = target->getBoundingBox();
Rect rect = Rect(0,0, s.size.width, s.size.height);
if (rect.containsPoint(locationInNode))
{
log("spinner began... x = %f, y = %f", locationInNode.x, locationInNode.y);
// do something here
return true; // consume touch for button
}
return false;
};
listenerSpinner->onTouchEnded = [=](cocos2d::Touch* touch, cocos2d::Event* event)
{
log("spinner touch ended");
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listenerSpinner, spinner);
the issue with this code is that it only consume touch at top right corner of the skeleton animation and not on the center and other corners. I cant understand what could be the issue, its has something to do with world transform or something but I just cant figure out what it is, having tried every thing. We still need to test bounding box made from the editor. I have also tested it by getting the spRegionAttachment* of the main image, but result are same. Please help/guide us to get the correct touch position.
thanks
Hello ALL,
So I was able to fix this problem/issue by using bounding box made in editor on skeleton.
here is the touch detection code. Enjoy!
spinner= spine::SkeletonAnimation::createWithData(_skeletonDataIcon, false);
spinner->addAnimation(0, "animation", true);
spinner->setPosition(Vec2(visibleSize.width/2, visibleSize.height /2));
spinner->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
this->addChild(spinner, 100);
auto spinnerBound = spSkeletonBounds_create();
auto listenerSpinner = cocos2d::EventListenerTouchOneByOne::create();
listenerSpinner->setSwallowTouches(true);
listenerSpinner->onTouchBegan = [&, spinnerBound](cocos2d::Touch* touch, cocos2d::Event* event)
{
spSkeletonBounds_update(spinnerBound, spinner->getSkeleton(), true);
auto target = event->getCurrentTarget();
Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
if (spSkeletonBounds_containsPoint(spinnerBound, locationInNode.x, locationInNode.y))
{
return true; // consume touch
}
return false;
};
listenerSpinner->onTouchEnded = [&, spinnerBound](cocos2d::Touch* touch, cocos2d::Event* event)
{
log("spinner touch ended");
spSkeletonBounds_update(spinnerBound, spinner->getSkeleton(), true);
auto target = event->getCurrentTarget();
Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
if (spSkeletonBounds_containsPoint(spinnerBound, locationInNode.x, locationInNode.y))
{
log("spinner began... x = %f, y = %f", locationInNode.x, locationInNode.y);
// do some thing
}
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listenerSpinner, spinner);