转场动画 (Transitions)

介绍

One of the cool features that Cocos2d-x has to offer is the power of transitions within two different scene. Transitions are effects such as: wipe, fade, zoom, and split. You can use transitions to switch between Cocos2d-x Scene objects. Sceneclass is derived from CocosNode and it is similar to Layer. You can add other CocosNode, such as Layer(s) and Sprite(s) into a Scene.

Some transitions has custom parameter(s); for example, FadeTransition has the fade color as extra parameter.
static CCTransitionFade* create(float duration,CCScene* scene, const ccColor3B& color);
To enable a transition, it is not much more difficult. Here we have an small example:

Comment

粒子(Particles)

简介

The term particle system refers to a computer graphics technique that uses a large number of very small sprites or other graphic objects to simulate certain kinds of “fuzzy” phenomena, which are otherwise very hard to reproduce with conventional rendering techniques - usually highly chaotic systems, natural phenomena, and/or processes caused by chemical reactions.

Point vs Quad

In early versions of Cocos2d-x, there were two types of particle system in cocos2d-x: Quad and Point particle system:

在Cocos2d-x早期版本中,Cocos2d-x里粒子系统有两种类型:Quad 和 Point粒子系统:

CCParticleSystemQuad

CCParticleSystemPoint

The CCParticleSystemQuad has these additional features that CCParticleSystemPoint doesn’t support:

CCParticleSystemQuad有很多特性是CCParticleSystemPoint不支持的:

- Spinning particles: particles can rotate around its axis. CCParticleSystemPoint ignores this property.
- Particles can have any size. In CCParticleSystemPoint if the size is bigger than 64, it will be treated as 64.
- The whole system can be scaled using the scale property.

Spinning particles:粒子可以绕自身的轴旋转。CCParticleSystemPoint忽略了该属性。

粒子可以为任意大小。在CCParticleSystemPoint中，如果大小大于64时，就视为64。

通过scale属性可以缩放整个系统。

Because of CCParticleSystemPoint does not support CCParticleBatchNode. As the result, CCParticleSystemPoint has been removed from cocos2d-x particle system.

CCParticleBatchNode

A CCParticleBatchNode can reference one and only one texture (one image file, one texture atlas). Only the CCParticleSystems that are contained in that texture can be added to the CCSpriteBatchNode. All CCParticleSystems added to a CCSpriteBatchNode are drawn in one OpenGL ES draw call. If the CCParticleSystems are not added to a CCParticleBatchNode then an OpenGL ES draw call will be needed for each one, which is less efficient.

粒子系统通用属性：

- emissionRate (a float). How many particle are emitted per second
- duration (a float). How many seconds does the particle system (different than the life property) lives. Use kCCParticleDurationInfinity for infity.
- blendFunc (a ccBlendFunc). The OpenGL blending function used for the system
- positionType (a tCCPositionType). Use kCCPositionTypeFree (default one) for moving particles freely. Or use kCCPositionTypeGrouped to move them in a group.
- texture (a CCTexture2D). The texture used for the particles

Liquid, like any other grid action, receives the grid parameter. You can adjust the quality of the effect by increasing the size of the grid. But it also implies less FPS.
The Effects are IntervalAction actions so you can treat them like any other action. eg:

参考

骨骼动画 vs. 精灵表

You can creat animations using “sprite sheets” which is quick and easy. Until you realize your game needs lots of animations and the memory consumption goes way up, together with the time required to load all the data. Also, to limit the size, you need to limit yourself to a low FPS for the animation, which also means the animation doesn’t look as smooth as you’d like. This is where skeletal animation comes in.

骨骼动画简述

Skeletal animation is a technique in cocos2d-x animation in which a character is represented in two parts: a surface representation used to draw the character (called skin or mesh) and a hierarchical set of interconnected bones (called the skeleton or rig) used to animate (pose and keyframe) the mesh.

Cocos2d-x provides a way to have 2d skeletal animations in your applications. The process of skeletal animation may be a bit complicated to setup, but using them afterwards is easy, and there are some tools to simplify the process.

When using skeletal animation, the animation is composed of several bones which are connected to one another. Affecting a bone also affects all of its children. By composing different transformations on each bone, you obtain different poses for the skeleton.

当使用骨骼动画时，动画由一些相互连接的骨骼组成。影响一个骨骼将会影响其所有的子对象。通过每根骨头上不同的变换组合，你会得到骨骼的各种造型。

Now, if you define keyframes with certain transformations for a point in time for each of the bones in the skeleton, you can interpolate between the keyframes to obtain a smooth transition and thus animate the skeleton.

现在，如果你定义了关键帧，即某个时间点骨骼中每根骨头特定的变换，你就能在关键帧之间插入平滑的过渡，从而使骨骼运动。

In the attached code, I used a class named Transformation, which contains data about 2D transformations, like translation, rotation and scale. Then, a Keyframe is defined by a frame number and one such Transformation. A collection of Keyframes defines a KeyframeAnimation. Finally, a SkeletonAnimation is a collection of KeyframeAnimations, one for each bone in the skeleton.

Separately, you use a Skeleton, which keeps a list of Joints that define the hierarchy of bones in the skeleton. Different from “sprite sheets”,each bone is then assigned a certain texture, like the ones below:

另外，你使用骨骼，它保存了关节列表，关节定义了骨骼中骨头的层级。不同于“精灵表”，每根骨头指定了特定的texture，如下所示：

骨骼动画工具

So far as we know, [CocosBuilder](http://cocosbuilder.com/) is a great, free (MIT license) tool for creating skeleton animations.
CocosBuilder is built for Cocos2d’s Javascript bindings, which means that your code, animations, and interfaces will run unmodified in Cocos2d-x.
A tutorial for cocos2d-iphone can be found at the [Zynga Engineering blog](http://code.zynga.com/2012/10/creating-a-game-with-cocosbuilder/)

与cocosbuilder动画协作

You can use CocosBuilder for creating character animations, animating complete scenes or just about any animation you can imagine. The animation editor has full support for multiple resolutions, easing between keyframes, boned animations and multiple timelines to name a few of the features.
h3.The Basics
In the bottom of the main window you can find the timeline. You use the timeline to create your animations.

基础

在主窗口的下部，你可以找到时间轴。你可以使用时间轴来创建你的动画。

By default your ccb-file has a single timeline that is 10 seconds long. CocosBuilder edits animations at a frame rate of 30 frames per second, but when you play back the animation in your app it will use whatever you have set cocos2d to use (the default in cocos2d is 60 fps). The current time is displayed in the top right corner, and has the format minute:second:frame. The blue vertical line also shows the current time. Click the time display to change the duration of the current timeline.

增加 Keyframes

Animations in CocosBuilder are keyframe based. You can add keyframes to different properties of a node and CocosBuilder will automatically interpolate between the keyframes, optionally with different types of easing.
To add a keyframe, first expand the view of the node by clicking the triangle to the right of the name of the node. This will reveal all the animatable properties of the node. What can be animated varies slightly depending on what type of node you have selected. Once the properties are visible you can click the property in the timeline with the option key held down. This will create a new keyframe at the time of the click. Alternatively, you can create a new keyframe at the time of the time marker by selecting a node then choosing Insert Keyframe in the Animation menu.
Keyframes are automatically added at the current time if you transform a node in the canvas area, given that the transformed property already has one or more keyframes in the timeline.

编辑 Keyframes

You edit a specific keyframe of a node by moving the time marker to the time of the keyframe and selecting the node. You can focus on a keyframe by double clicking it (which will select the node and move the time marker).

移动时间标志器至特定关键帧的时间点并选择该node，编辑该关键帧。你可以通过双击关键帧聚焦于该帧（聚焦即选择该node并移动时间标志器）。

You can select keyframes and move them together by dragging a selection box around them. You can also copy and paste keyframes between nodes. Make sure you only have one selected node when pasting the keyframes. The keyframes will be pasted starting at the time of the time marker.

If you have selected a set of keyframes it is possible to reverse the order of them by selecting Reverse Selected Keyframes in the Animation menu. Use the Stretch Selected Keyframes… option to speed up or slow down an animation by a scaling factor.

导入多张连续图片

If you have an animation created by sprite frames it can be tedious to move each individual frame to the timeline. CocosBuilder simplifies this process by automatically importing a sequence of images. Select the frames that you want to import in the left hand project view, then select a CCSprite in the timeline. Now choose Create Frames from Selected Resources in the Animation menu. The frames will automatically be created at the start of the marker. If you need to slow down the animation, select the newly created keyframes and use the Stretch Selected Keyframes… command.

Some of the easings have additional options, after the easing has been applied you can right click again and select Easing Setting… from the popup menu.

一些缓冲动作有额外的选项，在应用缓冲动作之后，你可以再次右击并从弹出菜单中选择Easing Setting…。

使用多个时间轴

A very powerful feature of CocosBuilder’s animation editor is the ability to have multiple timelines in a single file. You can name the different sequences and play them back from your code by using their name. It’s even possible to smoothly transition between the different timelines.
To select, add or edit your timelines use the timeline popup menu:

In the edit timelines dialog you can get an overview of your timelines, rename them, add new ones and (optionally) set one of the timelines to automatically start playback directly when the ccbi-file is loaded by your app.

Properties in timelines that do not have keyframes set share their values across timelines. E.g. if you move one node in one timeline it will be moved in all timelines as long as they do not have a keyframe set for the position property. I can sometimes be useful to add a single keyframe to a property just to override the shared value for a specific timeline.

锁定时间轴

You can automatically play back a sequence of timelines by chaining them. You can also use this feature for automatically looping a timeline.

你可以通过锁定时间轴来自动回放时间轴序列。你也可以使用这个特性来自动重播一个时间轴。

To have a timeline play in sequence, click the No chained timeline text and select the timeline you want to play right after the current one.

为了播放时间轴序列中的一个时间轴，点击No chained timeline文本并选择当前时间轴后你想播放的那个。

通过代码播放动画

To programmatically control the animations you create with CocosBuilder you will need to retrieve theCCBAnimationManager. The animation manager will be assigned to the nodes userObject when the ccbi-file is loaded.

The action manager will be returned as an autoreleased object. To play back a specific timeline call therunAnimationsForSequenceNamed: method. If a timeline is currently playing it will be immediately stopped when calling this method.

It is also possible to receive a callback whenever a timeline has finished playing. You will receive these callbacks even if another timeline is chained in sequence. Use the CCBAnimationManagerDelegate to receive the callbacks.

参考

Scheduler and Timer Callback

Scheduler is responsible for triggering the scheduled callbacks.

调度器负责触发调度回调.

两种不同类型的回调 (selectors):

update selector: the ‘update’ selector will be called every frame. You can customize the priority.
custom selector: A custom selector will be called every frame, or with a custom interval of time.
The ‘custom selectors’ should be avoided when possible. It is faster, and consumes less memory to use the ‘update selector’.

更新selector: ‘update’ selector会被每个frame调用.你可以自定义优先级.

自定义selector: 自定义selector会被每个frame调用, 或自定义的时间段内调用.

‘custom selectors’尽可能避免使用。相对于使用’update selector’来说，它比较快，且内存消耗较小.

CCScheduler vs. NSTimer

The Cocos2D Scheduler provides your game with timed events and calls. You should not use NSTimer. Instead use CCScheduler class.
The reasons as follow:

Cocos2D Scheduler 为你的游戏提供了时间事件和调用.你最好不要使用NSTimer，而用CCScheduler类替代.

原因如下:

CCNode objects know how to schedule and unschedule events,and using the Cocos2D Scheduler has several distinct advantages over just using NSTimer.

- CCNode objects know how to schedule and unschedule events,and using the Cocos2D Scheduler has several distinct advantages over just using NSTimer.
- The scheduler calls get deactivated whenever the CCNode is no longer visible or is removed from the scene.
- The scheduler calls are also deactivated when Cocos2D is paused and are rescheduled when Cocos2D is resumed.
- The scheduler delivers a interval time of the milliseconds that have passed since the last call.This interval time is useful in Physics engines.
- Using scheduler with this->scheduleUpdate(); call ensures that your update function will be called before each frame needs to be rendered.

CCNode对象知道如何去调度和解除调度事件，和仅使用NSTimer相比，使用Cocos2D Scheduler有很多独特的优点.

每当CCNode不再可见或者需从场景中移除时，调度器调用会失效。

当Cocos2D暂停或者Cocos2D继续时重新调度，调度器调用也会失效。

调度器会传递距离上一次调用的间隔时间(单位毫秒)。间隔时间在物理引擎中十分有用。

通过调用this->scheduleUpdate();使用调度器能确保你的更新方法在每帧需要渲染前调用。

Accordingly,CCScheduler can save you a lot of time over NSTimer and let you focus on the mechanics of your game.
Last updated by Iven Yang at Updated about 1 month ago.

This is a typical sprite sheet. It can be a sequence of sprite frames for an animation, or can be images pack that will be used in a same scene.

下面是一个典型的sprite sheet.它是动画中的一连串sprite frames，或者是可以在一个场景中用到的一组图片.

In OpenGL ES 1.1 period, sprite sheets was widely used for these benefits:
Reduce times of file I/O. Loading a big sprite sheet file is faster than loading lots of small files.
Reduce the memory consumption. OpenGL ES 1.1 can only use power-of-two sized textures (that is a width or height of 2,4,864,128,256,512,1024,…). In other words, OpenGL ES 1.1 allocates power-of-two sized memory for each texture even if this texture has smaller width and height. So using packed sprite sheet image will reduce the fragments of memory.
Reduce the draw calls to OpenGL ES draw method and speed up rendering.

Then how about the animation? As we can see, sprite sheet has no MUST-BE relationship with animations. But considering to these benefits above, sprite sheet animations are efficient. There’re different ways to create sprite sheet animations in cocos2d.

A CCSpriteBatchNode object contains the actual image texture of all the sprite frames. You must add it to a scene, even though it won’t draw anything itself; it just needs to be there so that it is part of the rendering pipeline. For example:

1CCSpriteBatchNode* spritebatch = CCSpriteBatchNode::create(“animations/grossini.png”);
Next, you need to use the CCSpriteFrameCache singleton to keep track how frame names correspond to frame bounds – that is, what rectangular area of the sprite sheet. Example:

Once your sprite sheet and frames are loaded, and the sprite sheet has been added to the scene, you can create sprites that use these frames by using the “createWithSpriteFrameName” method, and adding it as a child of the sprite sheet:

Now we need to create a CCArray object and add all frames of the animation to it. In the case of this animation, we know all 14 frames have the same size, so we can use a nested loop to iterate through them all, and break the loop when we finish adding the 14th frame.

Finally, we need to create a CCAnimate action instance which we can run on the CCSprite. Below, we also wrap the CCAnimate action in a CCRepeatForever action that does what you would expect: repeats the animation forever,like so:

CCAnimationCache*cache=CCAnimationCache::sharedAnimationCache();// "caches" are always singletons in cocos2dcache->addAnimationsWithFile("animations/animations-2.plist");CCAnimationanimation=cache->animationByName("dance_1");// I apologize for this method name, it should be getAnimationByName(..) in future versionsCCAnimateanimate=CCAnimate::create(animation);// Don't confused between CCAnimation and CCAnimate :)sprite->runAction(animate);

Easy to use, isn’t it?

简单易用吧？哈哈

骨骼动画(Skeleton Animation)

评论

Actions

Actions are like orders given to any CCNode object. These actions usually modify some of the object’s attributes like position, rotation, scale, etc. If these attributes are modified during a period of time, they are CCIntervalAction actions, otherwise they are CCInstantAction actions.
For example, the CCMoveBy action modifies the position property during a period of time, hence, it is a subclass of CCIntervalAction.

笛卡尔坐标系

不同坐标系简介

笛卡尔坐标系

You probably have known “Cartesian Coordinate System” from school where it’s heavily used in geometry lessons. If you have forgotten, these image will remind you quickly:

你可能上学的时候就已经知道“笛卡尔坐标系”了，它在几何课本里经常用到。如果你已经忘得差不多了，下面这些图片可以很快唤起你的记忆：

There’re 3 types of coordinate system that you will meet in mobile games development.

在移动游戏开发过程中，你可能会遇到三种类型的坐标系：

#### UI Coordinate System·

UI坐标系

In common UI Coordinates on iOS/Android/Windows SDK:
- The origin (x=0, y=0) is at the top-left corner.
- X axis starts at the left side of the screen and increase to the right;
- Y coordinates start at the top of the screen and increase downward,

iOS/Android/Windows SDK中的通用UI坐标系：

起点坐标(x=0, y=0)位于左上角

X轴从屏幕最左边开始，由左向右渐增

Y轴坐标从屏幕最上方开始，由上向下渐增

looks like this

详见下图

#### Direct3D Coordinate System·

Direct3D坐标系

DirectX uses Left-handed Cartesian Coordinate.

DirectX 使用Left-handed Cartesian Coordinate（左手笛卡尔坐标系）。

#### OpenGL and Cocos2d Coordinate System

OpenGL和Cocos2d坐标系

Cocos2d-x/-html5/-iphone uses the same coordinate system as OpenGL, which is so called “Right-handed Cartesian Coordinate System”.

We only use x-axis & y-axis in 2D world. So in your cocos2d games:
- The origin (x=0, y=0) is in the bottom-left corner of screen, which means the screen is in the first quartile of right-handed cartesian coordinate system,
- X axis starts at the left side of the screen and increase to the right;
- Y axis starts at the bottom of the screen and increase upwards.

在2D世界中，我们仅会使用x轴和y轴。所以在你的cocos2d游戏中：

起点坐标(x=0, y=0)位于右下角，这意味着屏幕位于右手笛卡尔坐标系的第一象限

X轴从屏幕最左边开始，由左向右渐增

Y轴坐标从屏幕最下方开始，由下向上渐增

And here’s a picture that helps illustrate Cocos2d-x Coordinates a bit better:

下面这张图片有助于更好的阐述Cocos2d-x坐标：

Note that it’s different from common UI coordinate systems and DirectX coordinate systems.

一定要注意：通用UI坐标系和DirectX坐标系是不一样的。

Parent and Childrens

Every class derived from CCNode (Ultimate cocos2d-x class) will have a anchorPoint property.
When determining where to draw the object (sprite, layer, whatever), cocos2d-x will combine both properties position and anchorPoint. Also, when rotating an object, cocos2d-x will rotate it around its anchorPoint.

如何转换坐标

convertToNodeSpace：

convertToNodeSpace will be used in, for example, tile-based games, where you have a big map. convertToNodeSpace will convert your openGL touch co-ordinates to the co-ordinates of the .tmx map or anything similar.
Example:
The following picture shows that we have node1 with anchor point (0,0) and node2 with anchor point (1,1).
We invoke CCPoint point = node1->convertToNodeSpace(node2->getPosition()); convert node2’s SCREEN coords to node1’s local.As the result,node2 with the position of (-25，-60).

convertToWorldSpace：

convertToWorldSpace(const CCPoint& nodePoint) converts on-node coords to SCREEN coordinates.convertToWorldSpace will always return SCREEN position of our sprite, might be very useful if you want to capture taps on your sprite but need to move/scale your layer
Example:

the above code will convert the node2‘s coordinates to the coordinates on the screen.
For example if the position of node2 is (0, 0) which will be the bottom left corner of the node1, but not necessarily on the screen. This will convert (0, 0) of the node2 to the position of the screen(in this case is (15,20)). The result shows in the following picture:

convertToWorldSpaceAR

convertToWorldSpaceAR will return the position relatevely to anchor point: so if our scene - root layer has Anchor Point of ccp(0.5f, 0.5f) - default, convertToWorldSpaceAR should return position relatively to screen center.
convertToNodeSpaceAR - the same logic as for .convertToWorldSpaceAR

参考

Comment

Director Scene Layer and Sprite

Director Scene Layer and Sprite

Scenes

Director

Layers

Multiple Layers Example:

Sprites

References

Comment

Scenes·场景

A scene (implemented with the CCScene object) is more or less an independent piece of the app workflow. Some people may call them “screens” or “stages”. Your app can have many scenes, but only one of them is active at a given time.

For example, you could have a game with the following scenes: Intro, Menu, Level 1, Cutscene 1, Level 2, Winning cutscene, losing cutscene, High scores screen.

比如，某个游戏有如下场景：介绍，菜单，Level 1, 画面1, Level 2, 获胜画面, 失败画面, 最高记录screen等.

You can define every one of these scenes more or less as separate apps; there is a bit of glue between them containing the logic for connecting scenes (the intro goes to the menu when interrupted or finishing, Level 1 can lead you to the cutscene 1 if finished or to the losing cutscene if you lose, etc.).

A cocos2d CCScene is composed of one or more layers (implemented with the CCLayer object), all of them piled up. Layers give the scene an appearance and behavior; the normal use case is to just make instances of Scene with the layers that you want.

There is also a family of CCScene classes called transitions (implemented with the CCTransitionScene object) which allow you to make transitions between two scenes (fade out/in, slide from a side, etc).

Since scenes are subclasses of CCNode, they can be transformed manually or by using actions. See Actions for more detail about actions.

由于场景都是CCNode的子类，所以可以手动或者通过actions方式来改变它们，详见actions部分。

- See more at: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Director_Scene_Layer_and_Sprite#sthash.jF0fVw56.dpuf

Director·导演类

The CCDirector is the component which takes care of going back and forth between scenes.

CCDirector是控制场景之间进出的组件。

The CCDirector is a shared (singleton) object. It knows which scene is currently active, and it handles a stack of scenes to allow things like “scene calls” (pausing a Scene and putting it on hold while another enters, and then returning to the original). The CCDirector is the one who will actually change the CCScene, after a CCLayer has asked for push, replacement or end of the current scene.

- See more at: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Director_Scene_Layer_and_Sprite#sthash.jF0fVw56.dpuf

Layers·层

A CCLayer has a size of the whole drawable area, and knows how to draw itself. It can be semi transparent (having holes and/or partial transparency in some/all places), allowing to see other layers behind it. Layers are the ones defining appearance and behavior, so most of your programming time will be spent coding CCLayer subclasses that do what you need.

The CCLayer is where you define event handlers. Events are propagated to layers (from front to back) until some layer catches the event and accepts it.

CCLayer是你定义事件处理的地方，事件会被传播到layer上（从前到后，冒泡），直到某个layer捕获此事件并接受它为止。

Although some serious apps will require you to define custom CCLayer classes, cocos2d provides a library of useful predefined layers (a simple menu layer: CCMenu, a color layer: CCColorLayer, a multiplexor between other layers: CCMultiplexLayer, and more ).