Hello iDevBlogADay
This is our first post in iDevBlogADay (thanks @mysterycoconut for all your hard work!), but I’ll not waste your time with lengthy introductions. If you want to know more about Crocodella Software, take a look at the 1-year anniversary post as it sums up quite nicely what we’ve been up to. I tend to prefer writing about technical subjects, so you can expect to see more posts like that in the future. Also, take a look at our older posts, there are some code snippets you may find useful. Enjoy!
Tell me a story
There’s much debate about the use of non-interactive scenes in games. Some people think they are a great aid in creating a cinematic feel (Metal Gear Solid series, Xenosaga), while others feel that they break the immersion and prefer to tell the story in-game through the use of dialogue and props (Half-Life). I tend to side more with the first group, even though I enjoy games using both approaches (or any mix in-between) as long as they’re good. Most games however require at least some form of presenting content that does not require direct interaction to the player, be it a tutorial or story scene.
As I’ve mentioned before, we are working on an old-style 2D top-down JRPG for the iPad (more on it soon!), and in this genre cutscenes are essential in moving the story forward. Therefore, we have been thinking of ways of creating these scenes with as little work from the programmer/designer as possible, while also allowing rapid modification and testing for quick iteration. And as always, cocos2d comes to the rescue!
Ready, set, CCAction!
Flash is the tool of choice for most animators, with its keyframe-based timeline aiding in the creation of complex sequences without having to draw each frame. We decided to build an editor tool with a similar approach, where the key points are:
- Each object in a scene (sprite, camera, background) is represented by an entity
- Each entity has its own timeline, with one or more keyframes.
- A keyframe defines a state in time of an entity’s properties
- Frames in-between keyframes are generated by tweening (interpolating) these properties
- The editor should run on the device itself, to allow testing in a real environment
One of the most powerful features of the cocos2d engine is the action mechanism. With it, interpolating between values is very easy, and thus actions play a great part in our scene editor. Also note that any mechanism which allows tweening of graphic properties could be used, like UIView animations for instance.
The editor

The almighty scene editor! Also this is the game's first official screenshot
As mentioned, each object in the scene is described by an entity. Entities have a name, Z-Index (for depth ordering), any other parameters necessary for that specific entity (such as the image file for a sprite) and a timeline, which is nothing more than a NSArray containing keyframe objects. Each keyframe has a time in seconds at which it occurs and a list of the values for all the entity’s properties in that instant, such as position, scale, opacity and animation frame. A keyframe may also have a command, allowing it to hook into the script engine to perform an action.
The timeline is displayed in a popover, where the user can select any instant in time (in half second increments) and see the existing keyframes. Entities can be dragged around in the editor and if a keyframe at the selected instant does not exist a new one will be created with the new position of the entity. Keyframes can also be manually added or modified by double-tapping the timeline, when a modal dialog with all properties will be brought up for tweaking.
The player
After a scene has been created, it has to be put in motion. For that, there’s an implementation of CCScene which takes a list of entities (with their respective timelines) and creates cocos2d nodes as appropriate (CCSprite, CCTMXTiledMap, etc.). A game loop is established and at each tick it will loop through all the entities performing the following steps:
- Is the entity a visual object (sprite, tile map)? If so, grabs the node from the scenegraph
- At the current instant, is there a keyframe in the entity’s timeline? If so, sets all the node’s properties from the keyframe (this is only a safety measure, in theory the next step should guarantee the the properties already have the correct values).
- Looks for the next keyframe in the timeline. If one is found, the time interval between the current keyframe and the next is calculated and one or more CCActions (CCMoveTo, CCScaleTo) are triggered on the node, where the time interval is the duration of the action and the future values are the targets.
- Repeats the process until the end of the scene.
And that’s all there is to it!
The code
I intended to share a sample project so that you could use this approach in your own code, but currently the code is not entirely presentable. There’s no error checking so it crashes whenever you don’t do exactly what it expects, and the UI is extremely non user-friendly. For the moment the editor is just enough for our internal needs, but if we have some time in the future we may polish it up a bit and release it (not likely, but possible). In the meantime, this write-up should be enough for you to create your own cutscene engine, and if you have any questions or suggestions please leave a comment!
EDIT: after the public outcry (:D), I’m now making available the source code. It is a stripped-down version of the editor we use, illustrating all the points talked about in this post. Some important considerations:
- This is an internal tool, so we will not be able to keep improving it for the public. We will however be glad to help you with anything we can!
- When you are previewing a scene and it reaches the end (it is hard-coded at 30 seconds right now), the application will quit, instead of returning to the editor.
- When saving a scene you should always include the .scn extension, as the file browser will look for those files for loading.
You can download the project here.
This article is part of iDevBlogADay, a group of independent iPhone dev-related blogs showcasing a different topic each day. Check out the rest of the group here.