
Introduction
The implementation of Cocos2d in Objective-C is used to develop games for the iPhone very widely. According to the
official website, the number of games on this engine already exceeds 1,800. It has been
mentioned more than once on Habré. Other ports (cocos2d-x in C ++ and cocos2d-android in Java) are also known and gaining popularity. However, the progenitor of these engines, the
original Cocos2d, turned out to be undeservedly overlooked. I will try to fill this gap.
Cocos2d is written in Python using the
pyglet library. Due to the use of Python and simple architecture, it is cross-platform and is well suited for rapid prototyping and testing of game concepts. The engine lags somewhat behind its descendants in terms of the implementation of certain possibilities, but in practice this does not cause difficulties. The problem with the engine is the poor quality of the documentation: the
official guide describes the most basic concepts, and then replete with permanent TODO stubs.
The API also contains few comments. Nevertheless, the set includes examples and tests that allow you to familiarize yourself with the basic programming techniques.
So,
install Cocos2d and proceed.
')
Scenes and flow control
A scene (
cocos.scene.Scene
class) is a single level or screen of your game. All game objects belonging to a particular level are placed on the corresponding scene. For managing scenes, use singleton director (
cocos.director.director
).
# cocos2d
import cocos
# director; , .
cocos.director.director.init()
# ,
cocos.director.director.run(cocos.scene.Scene())
During the game, the director controls the stack of scenes. Stack scenes are a very convenient concept. When a new scene is placed on the stack, the director proceeds to its execution, and the previous scene pauses. When the top scene is removed from the stack, the director resumes the execution of the previous scene. Thus, for example, you can implement nested levels or in-game menus. For operations with the stack of scenes, the methods of the director
push()
,
pop()
and
replace()
. The
replace()
call is equivalent to a successive call to
pop()
and
push()
.
Scene structure
A scene is a collection of objects (nodes) organized in a tree. The root of the tree is the scene itself. Parent transformations (position, angle, scale) in this model affect the transformation of children. Thus it is possible to build complex composite objects and easily manage their display. The engine contains a wide range of ready-made primitive nodes (for example, a layer (
cocos.layer.Layer
), a sprite (
cocos.sprite.Sprite
), text (
cocos.text.Label
), a particle system (
cocos.particle.ParticleSystem
) and many ). You can write your nodes, inheriting from
cocos.cocosnode.CocosNode
or derived classes.
import cocos
cocos.director.director.init()
#
scene = cocos.scene.Scene()
#
scene.add(cocos.text.Label("Hello world!", position = (100, 200))
#
cocos.director.director.run(scene)
The scene structure is formed using the node methods
add()
,
remove()
and
kill()
.
Objects can control their (and not only their) state using callback functions, which are quite simple to create. To illustrate, create a derived node with a rotating text:
import cocos
class RotatingText(cocos.text.Label):
#
def __init__(self, text = "", position = (0, 0)):
super(RotatingText, self).__init__(text, position)
self.schedule(self.update)
# ,
def update(self, dt):
self.rotation += dt * 20
cocos.director.director.init()
scene = cocos.scene.Scene()
scene.add(RotatingText("Hello world!", (100, 200)))
cocos.director.director.run(scene)
Actions
The above is already enough to write a simple demo, creating objects and setting their behavior. However, what makes Cocos2d so flexible and powerful is a system of actions (actions), and now we'll figure it out.
An action is an indication to an object to change its state.
import cocos
cocos.director.director.init()
scene = cocos.scene.Scene()
label = cocos.text.Label("Hello world!", position = (100, 200))
scene.add(label)
# 200 5
label.do(cocos.actions.MoveBy((200, 0), duration = 5))
cocos.director.director.run(scene)
Actions are instantaneous and interval. In addition, actions are absolute and relative. The list of standard actions includes:
- move (instant -
Place
, interval - MoveTo
, MoveBy
, JumpTo
, JumpBy
) - scaling (
ScaleTo
, ScaleBy
) - turn (
RotateTo
, RotateBy
) - object visibility control (
Show
, Hide
, Blink
, ToggleVisibility
) - transparency management (
FadeIn
, FadeOut
, FadeTo
)
Thanks to the overridden operators
+
and
|
actions can be combined. The actions combined by summation are executed sequentially one after the other.
# 100 5 3
label.do(cocos.actions.MoveBy((0, 100), 5) + cocos.actions.FadeOut(3))
Actions combined with a disjunction are executed in parallel.
# 100 , 90 , 5
label.do(cocos.actions.MoveBy((0, 100), 5) | cocos.actions.RotateBy(90, 5))
In addition, there are modifier actions that affect the way actions are applied. Standard modifier actions:
- Repeat (
Repeat
) - repeats a given action infinitely - acceleration (
Accelerate
, AccelDeccel
) - change the acceleration of the action in its process - change speed (
Speed
) - changes the time of action execution - reverse action (
Reverse
) - this action will be executed in the opposite direction, if possible - other
# - 200 3
action = cocos.actions.MoveBy((200, 0), 3)
label.do(cocos.actions.Repeat(action + cocos.actions.Reverse(action)))
Debugging
Cocos2d contains a built-in Python interpreter, which is called by default by pressing Ctrl-I. With the help of the interpreter, you can get a full introspection of the game and develop it interactively. The performance does not stop.
Conclusion
Unfortunately, many issues (such as user interaction, event handling, scene transitions, and effects) were beyond the scope of this article. If habrovchanam interested in these topics, I will try to present them in the next article.
Cocos2d official website