📜 ⬆️ ⬇️

Developing games using Cocos2d in Python

image

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:
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:
# - 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

Source: https://habr.com/ru/post/120438/


All Articles