Musings of amateur game development

Menu

Card flipping effect using Cocos2D-x without fisheye distortion

Getting a nice working card flipping effect has been more difficult than I expected.

Here’s the basic description of the process that can be used to obtain a card flip effect:

Animate the card sprite for half the rotation.

Swap the texture.

Animate the second half of the rotation

My initial implementation was using the CCOrbitCamera action, which worked beautifully and was perfect. And then I moved the sprite I was animating off the center of the screen and what do you know? The effect was no longer working as one would expect. When the sprite is rotated 90 degrees on the X axis you would expect that it would become invisible, but in fact, due to the field of view of the camera observing the scene a 90 degrees rotation will expose more and more of the sprite as you distance yourself from the center of the screen.

To check this just create an empty project and set the pSprite position in the HelloWorldScene file at the following position:

Then, run the flipping animation, preferably after adding the sprite to the scene layer.

pSprite->runAction(CCOrbitCamera::create(2, 1, 0, 0, 90, 0, 0));

This is what you should be seeing:

Not exactly what would be preferable.

An alternative would be to change the projection mode of the CCDirector. You would do this by calling during the init() of the scene:

CCDirector::sharedDirector()->setProjection(kCCDirectorProjection2D);

But now the effect looks, like you would expect, very flat and the near side of the sprite is no longer enlarged when the card is spinning on its axis.

What’s left then? Faking it, of course.

To fake a 3D flipping effect we would use a combination of two effects: scaling the sprite on the X axis, therefore reducing its width, and applying a skew effect so we can simulate at least a part of the near-side of the sprite exiting the view plane towards us. For this you’ll need to extend CCSprite and create your own sprite. In it, place a runFlipAnimation() method that you’ll call when you’ll want to flip the sprite.