I am looking to create a similar tunnel effect in COCOS2D (iOS). Could anyone suggest any pointers?

Ref Image

ref Video 1

ref Video 2

Till now I have tried with several ring shape sprites with decreasing scale and positioned center to a same point and keeping Z decreasing as well for each smaller sprite.

With that, animating it with CCScaleTo and changing the size to 2.0 with animation duration but it does not come anyway near to the tunnel effect shown in the reference.

Thanks, sam


5 Answers 5


I found the implementation description from the author of this effect:

It surely was a lot of work to create the depth illusion in a 2D plane.

The principle is very easy though: circles start in the middle of the screen with scale 0. Then the first circle of the tunnel starts scaling proportionally to the time elapsed (linear scaling doesn't work) and after some time the second circle starts scaling, then the 3rd, and 4th and so on.

You then lower proportionally the alpha value for the circles (the ones in the far back have alpha value lower than the ones in front to give the illusion of blur), you define a path that every circle has to follow, moving the X and Y coordinates of it, then you put a spaceship in the middle of the screen. Tilting the device makes the tunnel to shift left and right, up and down (but that gives the impression that the spaceship is moving instead!).

Once the circles go out of the screen, they are quickly faded and put back into initial position (to save memory so I don't need to create new circles but I reuse the same ones).

Sorry about my english, but I hope that explained the general idea :)


You're almost there with having multiple ring sprites of decreasing Z value and scale. Just don't center them all.

You need to keep track of the point where you want the tunnel to hit the far away event horizon. You can move that point around over time however you like.

Then, as you place each new sprite, place it at that point, scale it small, set it's opacity how you like, then start a CCSpawn with CCScaleTo and CCFadeTo, for example:

    CCScaleTo::create(2.0f, 1.5f),
    CCFadeTo::create(5.0f, 255),

Pre-create all the sprites and rotate which one is in the back to keep it efficient.


I would probably try to get it sorted with a background layer and particle effets. You could test the effects in particle designer and play them in the backgroung layer afterwards.


To be honest I don't think that image is rendered using a 2D camera. It looks like the game is rendered using a 3D rendering system. But since you want to use cocos2d, you need to simulate that 3D transormation matrix yourself. Here is an idea to begin with: you know in a 3D scene, every object is defined by 3 scalar values, x,y, and z. The simplest method you can use is scaling as you suggested, but not as you implemented! ccScaleTo will result in a linear scaling over time, which will not produce 3D feel. You can start with scaling object by value of 1/z. This is somehow identical to the simplest projection matrix you can think of! if you feel even that doesn't satisfy you, take a look at more modern and more complex projection matrices.

Side note: implementing custom projection matrix in cocos2D will be a little bit dirty. if you really don't like the effect, I strongly suggest changing your engine to one with 3D support.

  • \$\begingroup\$ I do not want to introduce 3d to make things more complex but this effect is made in cocos2d for rendering fake tunnel view (i had a conversation with the author of this game sometime back) \$\endgroup\$ Oct 13, 2012 at 10:45

Here is how I did it, in pseudo-code

Activate Tunnel-effect:

  1. Create a CCRepeatForever(CCFunc(createCircle))
  2. Add a node to your scene called "ViewNode"


  1. Create layer, postion in center of Scene. Add it as child to "ViewNode".
  2. run action: CCSequence( CCEaseExponentialIn(CCScaleTo) , CCRemoveSelf )
  3. Put stuff in your layer, i.e. cirkels, enemies, spaceships, whatever.

Control (with parallax)

  1. For all layers with tunnel-effect (i.e. children of ViewNode)
  2. update anchor position based on touch position.

The position is the Vanishing Point, therefore, you can't move layers without moving the vanishing point. However, if you move the anchor point, the layer appear to move, but the Vanishing Point stays the same -- this creates a parallax effect, because moving ccp(0.2,0.2) on a close layer (large scale) has more effect than moving the same on a far-away layer.

You wrap everything in layers of the same size, to make sure that repositioning the anchor creates the same movement in all layers.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .