I've created a video tutorial that shows how to create this effect using LevelHelper, SpriteHelper and Cocos2d-x. Don't mind the
It's my first video tutorial ever, so keep your expectations moderated :P
The process, as described in the video is:
- Create a Cocos2d-x project
- Create a Project in LevelHelper
- Use SpriteHelper to create the sprites
- Create the parallax layer in LevelHelper, using the new sprites
- Place the billboard sprites in LevelHelper, assigning them a special tag
- Export the Cocos2d-X code (would also work the same with Cocos2D)
- In XCode, handle both the touchmove and touchend events
- On touchmove move the parallax on a ratio of 1:1 with the gesture
- On touchend try to find the nearest snapping point, and trigger an animation to move the parallax to that point.
The source-code used in the tutorial is:
HelloWorldScene.h:
--------------------
inside the private section
LevelHelperLoader* loader; LHParallaxNode* myParallax;
HelloWorldScene.cpp
----------------------
HelloWorld::HelloWorld()
loader = new LevelHelperLoader("ScrollableParalax.plhs");
myParallax = loader->paralaxNodeWithUniqueName("Parallax_1");
HelloWorld::ccTouchesMoved()
CCSetIterator it;
CCTouch* touch;
for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);
if(!touch)
break;
CCPoint location = touch->locationInView();
location = CCDirector::sharedDirector()->convertToGL(location);
CCPoint prevLocation = touch->previousLocationInView();
prevLocation = CCDirector::sharedDirector()->convertToGL(prevLocation);
CCPoint touchDelta = ccpSub(location,prevLocation);
if(NULL != myParallax)
{
CCPoint parallaxPosition = myParallax->getPosition();
myParallax->setPosition(ccp(parallaxPosition.x + touchDelta.x, parallaxPosition.y + touchDelta.y));
}
}
HelloWorld::ccTouchesEnded()
//find nearest selector
CCArray* sprTag = loader->spritesWithTag(SELECTOR);
if(sprTag->count() == 0)
{
return;
}
float minOffset = MAXFLOAT;
for(int i =0; i< sprTag->count(); ++i)
{
LHSprite* curSprite = (LHSprite*)sprTag->objectAtIndex(i);
float spritePosition = curSprite->getPositionX();
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
float centerPosition = screenSize.width/2 -
curSprite->getRealScale().width / 2;
float offset = centerPosition - spritePosition;
if(abs(offset) < abs(minOffset))
{
minOffset = offset;
}
}
CCPoint parallaxPosition = myParallax->getPosition();
//if less than a threshold snap directly without any animation
if(abs(minOffset) < 50)
{
myParallax->setPosition(
ccp(parallaxPosition.x + minOffset, parallaxPosition.y));
}
else
{
myParallax->runAction(
CCMoveBy::actionWithDuration(0.3f, ccp(minOffset, 0)));
}
HelloWorld::~HelloWorld
delete myParallax; myParallax = NULL;
Hey Pedro,
ReplyDeleteThanks for the post and the video! It's making me seriously consider learning cocos2d and levelhelper. I'm still not sure if it's overkill for my app though. I was wondering if I could get your opinion on whether or not it's a good move for me considering the performance issues I'm getting in my Core Animation parallax effect right now. I recorded a 90 second video of it here - http://youtu.be/ZN2pSk8N3lc
I'd appreciate any insight you have! Thanks!
I really love the art-style you got there, great stuff man. Regarding performance (and mostly everything else) it's, IMHO, a great move to learn Cocos2D. Cocos2D uses OpenGL ES do handle the drawing, which is much faster than Core Animation.
ReplyDeleteAlso, it handles most of the fuss, and creating a parallax effect is incredibly easy, even without LevelHelper. My suggestion, go to http://www.raywenderlich.com and check the Cocos2D tutorials. You won't regret it.
I'm looking his stuff up now. Thanks Pedro!
ReplyDeleteLevelHelper does not support Cocos2dx version 3 now unfortunately
ReplyDelete