开始学习一个新的库或者是框架是令人望而生畏的,特别是当有一大堆参考材料要读。本章提供了一个很快的介绍,但是没要写所有的细节
Hello, World
Hello Actions
Handling Events
Where to next?
Hello, World¶
我们会从必要的“Hello,Word”介绍开始。这个程序会打开一个有一些字的窗口,然后等待关闭。你可以找到整个程序,在samples/hello_world.py
从引入cocos包开始:
import cocos
定义一个子类Layer 并在此定义你程序的逻辑:
class HelloWorld(cocos.layer.Layer):
总是调用super来构造函数:
def __init__(self):
super(HelloWorld, self).__init__()
为了显示文字,我们创建了一个Label。关键词参数用来设置其文字,位置和对齐方式
label = cocos.text.Label(
'Hello, world',
font_name='Times New Roman',
font_size=32,
anchor_x='center', anchor_y='center'
)
标签位置会在屏幕中央:
label.position = 320, 240
由于Label是CocosNode的一个子类,所以可以被添加为其子项。所有的 CocosNode对象都知道如何渲染自己,执行动作和做出转换。为了把它添加为层的子项,用CocosNode.add 方法:
self.add(label)
在定义HelloWorld类以后,我们需要初始化并创建一个窗口。要做到这些,我们要初始化Director:
cocos.director.director.init()
然后我们创建一个HelloWorld 实例:
hello_layer = HelloWorld()
然后我们创建一个Scene使HelloWorld 层成为其子项:
main_scene = cocos.scene.Scene (hello_layer)
最后运行这个图层:
cocos.director.director.run(main_scene)
最后三句话的简写:
#cocos.director.director.run(cocos.scene.Scene(HelloWorld()))
Hello Actions¶
这个例子与例一很像,不同之处在于它像我们介绍了动作的世界。一个动作就像是一个指令。你可以让任何一个 CocosNode对象执行一个动作。你可以在samples/hello_world_actions.py找到整个文件。
如前例,我们导入cocos包:
import cocos
如果你想使用多个动作,你可以在此命名空间中导入所有可用的动作,像这样:
from cocos.actions import *
我们继承了ColorLayer使其拥有背景色,然后以青蓝色为参数来调用super()
class HelloWorld(cocos.layer.ColorLayer):
def __init__(self):
# blueish color
super( HelloWorld, self ).__init__( 64,64,224,255)
如前例,我们创建并添加了一个标签
label = cocos.text.Label('Hello, World!',
font_name='Times New Roman',
font_size=32,
anchor_x='center', anchor_y='center')
# set the label in the center of the screen
label.position = 320,240
self.add( label )
在此例中,我们要创建一个图像精灵(sprite)并把其添加为一个子项。在cocos2d中,图像精灵就是Sprite对象(sprite-->图像控件):
sprite = cocos.sprite.Sprite('grossini.png')
我们将图像精灵放在屏幕的中心。默认位置为(0,0):
sprite.position = 320,240
我们把比例属性设为3,这意味着我们的图像精灵会有3倍大。默认值为1
sprite.scale = 3
我们把图像精灵作为一个子项,并把它的z值设为1,使其在标签上显示,因为z的默认值为0
self.add( sprite, z=1 )
我们创建了一个ScaleBy动作。它会把对象在两秒内缩放三倍
scale = ScaleBy(3, duration=2)
我们让这个标签:
- 在两秒内放大三倍
- 然后在两秒内按比例缩小三倍
- 然后永远重复这两个动作
label.do( Repeat( scale + Reverse( scale) ) )
我们让图像控件做相同的事情,但从缩小开始:
sprite.do( Repeat( Reverse(scale) + scale ) )
如前例,初始化导演:
cocos.director.director.init()
hello_layer = HelloWorld ()
然后我们让Layer (对,所有的 CocosNode对象都可以执行动作)来执行RotateBy动作——在十秒内转360度:
hello_layer.do( RotateBy(360, duration=10) )
最后我们开始执行:
# A scene that contains the layer hello_layer
main_scene = cocos.scene.Scene (hello_layer)
# And now, start the application, starting with main_scene
cocos.director.director.run (main_scene)
处理事件¶
我们以前的例子都是不可交互的。他们可以显示一些东西,但是不能对用户的输入进行相应(除了当你按ESC或关闭窗口来退出)。cocos从监听 director.window 事件来获得输入。很方便,cocos.layer 可以自动的监听director.window 事件:在layer子类中设 is_event_handler项为True,cocos就会开始接收。
在此部分,我们会一步一步的创建这个示例-->samples/handling_events.py;这是一个很简单的cocos应用,它可以显示你按了那个键且对鼠标动作和点击事件进行反应。在阅读前运行此程序可以让你对我们要创建什么产生一个更清晰的思路。
这个示例有一个有两个层的图层
我们开始定义 KeyDisplay 层类。如常,我们把初始化参数放入__init__
并写上显示它的代码:
class KeyDisplay(cocos.layer.Layer):
# 如果你希望你的层可以接收 director.window 事件
# 你需把它的值设为 'True'
is_event_handler = True
def __init__(self):
super( KeyDisplay, self ).__init__()
self.text = cocos.text.Label("", x=100, y=280 )
# 记录按了什么键
self.keys_pressed = set()
self.update_text()
self.add(self.text)
def update_text(self):
key_names = [pyglet.window.key.symbol_string (k) for k in self.keys_pressed]
text = 'Keys: '+','.join (key_names)
# 更新 self.text
self.text.element.text = text
这是一个类,定义了一个叫 key_pressed 的集合(set)——任何时候被按下的键的集合。但是,这段代码其实并没有做什么事。我们需要让这个层当按键按下或释放时更新这个集合。换句话说,我们需要像这个层添加事件处理器。 向层添加事件处理器就是一个添加名为 on_
的方法。如我们现在需要做的on_key_press
和 on_key_release
:
def on_key_press (self, key, modifiers):
"""这个函数在按下一个键的时候被调用。
'key'是一个常量,指示按下哪个键。
'modifiers(修饰符)'是一个按位或几个常量,指示哪些
修饰符在按下时处于活动状态(ctrl,shift,capslock等)
"""
self.keys_pressed.add (key)
self.update_text()
def on_key_release (self, key, modifiers):
"""这个函数在释放一个键的时候被调用。
'key'是一个常量,指示按下哪个键。
'modifiers(修饰符)'是一个按位或几个常量,指示哪些
修饰符在按下时处于活动状态(ctrl,shift,capslock等)
常量来自 pyglet.window.key
"""
self.keys_pressed.remove (key)
self.update_text()
def update_text(self):
key_names = [pyglet.window.key.symbol_string (k) for k in self.keys_pressed]
text = 'Keys: '+','.join (key_names)
# 更新 self.text
self.text.element.text = text
使用该代码,该层现在完全正常工作。你可以按下并释放按键或组合键,在任何时候你都将会看到显示的更新——告诉你刚按下什么键。
处理鼠标输入类似。你需要这三个事件: on_mouse_press, on_mouse_motion 和 on_mouse_drag。这样,我们就可以定义我们的层了。
class MouseDisplay(cocos.layer.Layer):
is_event_handler = True #: enable director.window events
def __init__(self):
super( MouseDisplay, self ).__init__()
self.posx = 100
self.posy = 240
self.text = cocos.text.Label('No mouse events yet', font_size=18, x=self.posx, y=self.posy )
self.add( self.text )
def update_text (self, x, y):
text = 'Mouse @ %d,%d' % (x, y)
self.text.element.text = text
self.text.element.x = self.posx
self.text.element.y = self.posy
然后添加事件处理程序——在鼠标移动时更新文本,并且在按任何鼠标按键时更改文本位置:
def on_mouse_motion (self, x, y, dx, dy):
"""当鼠标移动到应用程序窗口上并且没有按鼠标按键时
(x,y)是鼠标的物理坐标
(dx,dy)是鼠标至上次调用后经过的的距离向量
"""
self.update_text (x, y)
def on_mouse_drag (self, x, y, dx, dy, buttons, modifiers):
"""此函数在鼠标在应用程序窗口上移动并按下鼠标按键时被调用
(x,y)是鼠标的物理坐标
(dx,dy)是鼠标至上次调用后经过的的距离向量
'buttons' 是一个按位或pyglet.window.mouse常量-->LEFT,MIDDLE,RIGHT
'modifiers' 是一个按位或pyglet.window.key修饰符常量
(值如 'SHIFT', 'OPTION', 'ALT')
"""
self.update_text (x, y)
def on_mouse_press (self, x, y, buttons, modifiers):
"""此函数在按任何键时被调用
(x,y)是鼠标的物理坐标
'buttons' 是一个按位或pyglet.window.mouse常量-->LEFT,MIDDLE,RIGHT
'modifiers' 是一个按位或pyglet.window.key修饰符常量
(值如 'SHIFT', 'OPTION', 'ALT')
"""
self.posx, self.posy = director.get_virtual_coordinates (x, y)
self.update_text (x,y)
唯一有点不寻常的是调用director.get_virtual_coordinates (x, y). cocos 有两个坐标系统,一个物理的,一个虚拟的。鼠标事件处理器从pyglet接收其物理坐标。如果你想把它映射为虚拟坐标,你得用 director.get_virtual_coordinates 方法, 该方法可以正确映射。如果你取而代之用self.posx
, self.posy=x,y
,你会发现应用程序似乎正常运作,但如果你缩放窗口,点击会把文本放在错误的地方。
下面是其他鼠标事件:
- on_mouse_release : 当按键松开
- on_mouse_scroll : 当滚轮转动
- on_mouse_leave : 当鼠标指针移除窗口
- on_mouse_enter : 当鼠标指针移入窗口
此示例没有更多代码了,最后创建一个包含两层的图层并运行它:
director.init(resizable=True)
# Run a scene with our event displayers:
director.run( cocos.scene.Scene( KeyDisplay(), MouseDisplay() ) )
您现在可以玩一下这个示例并更改。你可以尝试的一些事情:
- 更改on_mouse_press处理程序并将映射移至虚拟坐标; 注意调整窗口大小后,它的行为是否奇怪
- 请注意,屏幕上的鼠标坐标是物理坐标,因此在调整窗口大小时它们的范围会发生变化; 修改示例以显示虚拟坐标。
- 修改代码,使标签跟随鼠标拖动
- 更改代码,使键盘显示屏也会显示修饰符
接下来呢?
本章中提供的示例应该为您提供足够的信息,以开始编写简单的街机和基于点击的游戏。
这个编程指南的其余部分涉及到一些cocos的功能的相当多的技术细节。开始使用时,建议您从每个章节开始阅读,但不要从头到尾阅读整篇指南。
要在2D应用程序中实现最佳性能,您需要直接使用OpenGL。OpenGL的规范参考是The OpenGL Programming Guide和 The OpenGL Shading Language.
由于cocos2d使用pyglet,您还应该查看pyglet Programming Guide 和 pyglet API Reference
在文档和下载的源文件包的samples/
目录中还有很多例子。继续看 http://www.cocos2d.org/以了解更多示例和教程。