Before we create some games using Cocos2D, let's create some basis for a 2d platform game. You know, stereotypical 2d kinds of stuff. Remember, we are making games back in the 70's.
Basic things we need is rendering, which is about Sprites, input, and physics. It's a bit weird compared to the first series because collision wasn't the first thing we have discussed. Put that in mind that Cocos2D is all about making games.
Let's talk about inputs first. When we were studying tkinter
, we used bind
method to bind a key to an event. This time, we don't need to bind anything. All we have to check is whether a key is being pressed or released. This kind of input handling is called event handling. In order to activate event handling, we have to tell the layer that the events are being handled through is_event_handler = True
.
import cocos
class MainLayer(cocos.layer.Layer):
is_event_handler = True
This time, instead of labeling, we will load some graphical data. We have drawn shapes through methods in tkinter
. This time, no more drawing, but loading. Download the 'ball.png' and put them in the exact folder where you've saved your python file.
Now, we will assign this image to the sprite object.
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
Then we will assign two methods called on_key_press
and on_key_release
. These two methods are ready-made. The first parameter is a key parameter. The second parameter is a modifier. We are not going to discuss what is a modifier. Let's check if the method works well or not by printing the key being pressed.
def on_key_press(self, k, m):
print('Pressed', k)
def on_key_release(self, k, m):
print('Released', k)
Let's run the program and check whether the key input is going alright.
import cocos
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
def on_key_press(self, k, m):
print('Pressed', k)
def on_key_release(self, k, m):
print('Released', k)
if __name__ == '__main__':
cocos.director.director.init(caption = 'Hello, World!')
layer = MainLayer()
scene = cocos.scene.Scene(layer)
cocos.director.director.run(scene)
You can see that some numbers are indicated on the shell. These codes are pyglet key constants. You can check them out at this link.
http://pythonhosted.org/pyglet/api/pyglet.window.key-module.html
Now, we want to visually see which key is being pressed. So we will import key
from the pyglet.window
module.
from pyglet.window import key
We want to convert the constants, the symbols into the string format. We are going to use key.symbol_string
method.
def on_key_press(self, k, m):
print('Pressed', key.symbol_string(k))
def on_key_release(self, k, m):
print('Released', key.symbol_string(k))
Now we will make the ball move through these methods. The logic is as follows.
- for right side is x positive and left is x negative,
x = right - left
. - Make a new variable
new_x
and new_y
in new update
method in order to update the x and y coordinate of the specific object. - Set the velocity of the object.
new_x = x + v * key_input_check * dt
(dt is the differential of time. The basic dt of cocos2d is 60 fps)- if
on_key_press
is activated, key_input_check is True, which means that the value of the variable is 1 - if
on_key_release
is activated, key_input_check is False, which means that the value of the variable is 0
Let's code these.
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
self.speed = 100.0
self.pressed = {}
self.schedule(self.update)
def on_key_press(self, k, m):
self.pressed[k] = 1
def on_key_release(self, k, m):
self.pressed[k] = 0
def update(self, dt):
x = self.pressed[key.RIGHT] - self.pressed[key.LEFT]
y = self.pressed[key.UP] - self.pressed[key.DOWN]
if x != 0 or y != 0:
pos = self.player.position
new_x = pos[0] + self.speed * x * dt
new_y = pos[1] + self.speed * y * dt
self.player.position = (new_x, new_y)
But there's one problem. We don't press right or left at the same time the program starts. Which means that in the update
method, the x
and y
variables are asking for a value of a key that doesn't exist. In order to solve this, we are going to use a special dictionary from an external method called collections
. From this module, we will import defaultdict
. This dictionary stores default 0 value for the absent keys.
from collections import defaultdict
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
self.speed = 100.0
self.pressed = defaultdict(int)
self.schedule(self.update)
def on_key_press(self, k, m):
self.pressed[k] = 1
def on_key_release(self, k, m):
self.pressed[k] = 0
def update(self, dt):
x = self.pressed[key.RIGHT] - self.pressed[key.LEFT]
y = self.pressed[key.UP] - self.pressed[key.DOWN]
if x != 0 or y != 0:
pos = self.player.position
new_x = pos[0] + self.speed * x * dt
new_y = pos[1] + self.speed * y * dt
self.player.position = (new_x, new_y)
When you run the final output, you will be surprised that the key input, the movement of the ball is smoother than the one of tkinter
's.
In next episode, we will discuss the collision, the basic physics of the game.
import cocos
from collections import defaultdict
from pyglet.window import key
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
self.speed = 100.0
self.pressed = defaultdict(int)
self.schedule(self.update)
def on_key_press(self, k, m):
self.pressed[k] = 1
def on_key_release(self, k, m):
self.pressed[k] = 0
def update(self, dt):
x = self.pressed[key.RIGHT] - self.pressed[key.LEFT]
y = self.pressed[key.UP] - self.pressed[key.DOWN]
if x != 0 or y != 0:
pos = self.player.position
new_x = pos[0] + self.speed * x * dt
new_y = pos[1] + self.speed * y * dt
self.player.position = (new_x, new_y)
if __name__ == '__main__':
cocos.director.director.init(caption='Hello, World!')
layer = MainLayer()
scene = cocos.scene.Scene(layer)
cocos.director.director.run(scene)
Before we create some games using Cocos2D, let's create some basis for a 2d platform game. You know, stereotypical 2d kinds of stuff. Remember, we are making games back in the 70's.
Basic things we need is rendering, which is about Sprites, input, and physics. It's a bit weird compared to the first series because collision wasn't the first thing we have discussed. Put that in mind that Cocos2D is all about making games.
Let's talk about inputs first. When we were studying
tkinter
, we usedbind
method to bind a key to an event. This time, we don't need to bind anything. All we have to check is whether a key is being pressed or released. This kind of input handling is called event handling. In order to activate event handling, we have to tell the layer that the events are being handled throughis_event_handler = True
.import cocos
class MainLayer(cocos.layer.Layer):
is_event_handler = True
This time, instead of labeling, we will load some graphical data. We have drawn shapes through methods in
tkinter
. This time, no more drawing, but loading. Download the 'ball.png' and put them in the exact folder where you've saved your python file.Now, we will assign this image to the sprite object.
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
Then we will assign two methods called
on_key_press
andon_key_release
. These two methods are ready-made. The first parameter is a key parameter. The second parameter is a modifier. We are not going to discuss what is a modifier. Let's check if the method works well or not by printing the key being pressed.def on_key_press(self, k, m):
print('Pressed', k)
def on_key_release(self, k, m):
print('Released', k)
Let's run the program and check whether the key input is going alright.
import cocos
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
def on_key_press(self, k, m):
print('Pressed', k)
def on_key_release(self, k, m):
print('Released', k)
if __name__ == '__main__':
cocos.director.director.init(caption = 'Hello, World!')
layer = MainLayer()
scene = cocos.scene.Scene(layer)
cocos.director.director.run(scene)
You can see that some numbers are indicated on the shell. These codes are pyglet key constants. You can check them out at this link.
http://pythonhosted.org/pyglet/api/pyglet.window.key-module.html
Now, we want to visually see which key is being pressed. So we will import
key
from thepyglet.window
module.from pyglet.window import key
We want to convert the constants, the symbols into the string format. We are going to use
key.symbol_string
method.def on_key_press(self, k, m):
print('Pressed', key.symbol_string(k))
def on_key_release(self, k, m):
print('Released', key.symbol_string(k))
Now we will make the ball move through these methods. The logic is as follows.
x = right - left
.new_x
andnew_y
in newupdate
method in order to update the x and y coordinate of the specific object.new_x = x + v * key_input_check * dt
(dt is the differential of time. The basic dt of cocos2d is 60 fps)on_key_press
is activated, key_input_check is True, which means that the value of the variable is 1on_key_release
is activated, key_input_check is False, which means that the value of the variable is 0Let's code these.
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
self.speed = 100.0
self.pressed = {}
self.schedule(self.update)
def on_key_press(self, k, m):
self.pressed[k] = 1
def on_key_release(self, k, m):
self.pressed[k] = 0
def update(self, dt):
x = self.pressed[key.RIGHT] - self.pressed[key.LEFT]
y = self.pressed[key.UP] - self.pressed[key.DOWN]
if x != 0 or y != 0:
pos = self.player.position
new_x = pos[0] + self.speed * x * dt
new_y = pos[1] + self.speed * y * dt
self.player.position = (new_x, new_y)
But there's one problem. We don't press right or left at the same time the program starts. Which means that in the
update
method, thex
andy
variables are asking for a value of a key that doesn't exist. In order to solve this, we are going to use a special dictionary from an external method calledcollections
. From this module, we will importdefaultdict
. This dictionary stores default 0 value for the absent keys.from collections import defaultdict
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
self.speed = 100.0
self.pressed = defaultdict(int)
self.schedule(self.update)
def on_key_press(self, k, m):
self.pressed[k] = 1
def on_key_release(self, k, m):
self.pressed[k] = 0
def update(self, dt):
x = self.pressed[key.RIGHT] - self.pressed[key.LEFT]
y = self.pressed[key.UP] - self.pressed[key.DOWN]
if x != 0 or y != 0:
pos = self.player.position
new_x = pos[0] + self.speed * x * dt
new_y = pos[1] + self.speed * y * dt
self.player.position = (new_x, new_y)
When you run the final output, you will be surprised that the key input, the movement of the ball is smoother than the one of
tkinter
's.In next episode, we will discuss the collision, the basic physics of the game.
import cocos
from collections import defaultdict
from pyglet.window import key
class MainLayer(cocos.layer.Layer):
is_event_handler = True
def __init__(self):
super(MainLayer, self).__init__()
self.player = cocos.sprite.Sprite('ball.png')
self.player.color = (0, 0, 255)
self.player.position = (320, 240)
self.add(self.player)
self.speed = 100.0
self.pressed = defaultdict(int)
self.schedule(self.update)
def on_key_press(self, k, m):
self.pressed[k] = 1
def on_key_release(self, k, m):
self.pressed[k] = 0
def update(self, dt):
x = self.pressed[key.RIGHT] - self.pressed[key.LEFT]
y = self.pressed[key.UP] - self.pressed[key.DOWN]
if x != 0 or y != 0:
pos = self.player.position
new_x = pos[0] + self.speed * x * dt
new_y = pos[1] + self.speed * y * dt
self.player.position = (new_x, new_y)
if __name__ == '__main__':
cocos.director.director.init(caption='Hello, World!')
layer = MainLayer()
scene = cocos.scene.Scene(layer)
cocos.director.director.run(scene)