cocos2d-x开发记录:二,基本概念(动作,动画,坐标系统)
既然我们选择用cocos2d,那么他里面的一些基本概念我们肯定是要熟悉下的,以下资料来源于官网,英语好的可以直接去官网看。
一.Actions(动作)
动作都由于CCNode对象发出。这些动作通常修改对象的一些属性,比如位置,旋转,比例等。如果这些属性在某一个时间周期内被修改,那么它们是CCIntervalAction动作。否则它们是CCInstantAction动作。例如CCMoveBy动作在某段时间内修改了位置属性,因此,它是CCIntervalAction的子类。我们能运行TestCpp->Actions来看看动作的可视化效果。这个文件位于cocos2d-x/samples/Cpp/TestCpp/Classes/ActionsTest下。ActionsEaseTest是很好的示例代码用法。
CCIntervalAction动作有一些有趣的属性:
它们用于改变动作加速的快慢。你能使用CCActionManager恢复或暂停所有动作。
- // Pause actions
- CCDirector *director = CCDirector::sharedDirector();
- m_pPausedTargets = director->getActionManager()->pauseAllRunningActions();
- // resume actions
- CCDirector *director = CCDirector::sharedDirector();
- director->getActionManager()->resumeTargets(m_pPausedTargets);
基本动作
位置
CCMoveBy
CCMoveTo
CCJumpBy
CCJumpTo
CCBezierBy
CCBezierTo
CCPlace
比例
CCScaleBy
CCScaleTo
旋转
CCRotateBy
CCRotateTo
可见度
CCShow
CCHide
CCBlink
CCToggleVisibility
透明度
CCFadeIn
CCFadeOut
CCFadeTo
颜色
CCTintBy
CCTintTo
Example:
- CCSprite *sprite = CCSprite::create("Images/grossini.png");
- sprite->setPosition(ccp(, ));
- addChild(sprite);
- CCMoveBy* act1 = CCMoveBy::create(0.5, ccp(, ));
- sprite->runAction(CCRepeat::create(act1, ));
二.动画
帧动画
你能从一系列的图片文件中创建一个动画,如下所示:
- CCAnimation *animation = CCAnimation::create();
- // load image file from local file system to CCSpriteFrame, then add into CCAnimation
- for (int i = ; i < ; i++)
- {
- char szImageFileName[] = {};
- sprintf(szImageFileName, "Images/grossini_dance_%02d.png", i);
- animation->addSpriteFrameWithFileName(szImageFileName);
- }
- animation->setDelayPerUnit(2.8f / 14.0f); // This animation contains 14 frames, will continuous 2.8 seconds.
- animation->setRestoreOriginalFrame(true); // Return to the 1st frame after the 14th frame is played.
- CCAnimate *action = CCAnimate::create(animation);
- sprite->runAction(action); // run action on sprite object
注意CCAnimation由精灵(sprite)帧组成。每帧间隔时间,动画持续时间等,这是一个“数据包”。然而CCAnimate是一个动作,它基于CCAnimation对象。
Sprite Sheet动画
虽然手动动画是非常容易理解的,但很少用于真正的游戏项目。所以精灵动画是更通用的2D动画解决方案。下图是一个典型的Sprite Sheet。它可以是一个序列帧动画,或者是一个图片包被用在同一场景中。
在 OpenGL ES 1.1时期,sprite sheets被广泛用于以下这些福利:
◆减少文件IO时间,载入一个大的sprite sheet文件跟载入大量小的文件整体速度更快。
◆减少内存消耗。OpenGL ES 1.1仅能用于纹理的2次方大小。(2,4,8,64,128,256,512,1024等)。换句话说,OpenGL ES 1.1分配2次方大小的内存给每一个纹理,即使这个纹理小于分配的宽高。因此使用sprite sheet包裹在一起的图片将会减少内存碎片。
◆减少OpenGL ES 绘制方法的调用并加速渲染。
Cocos2d-x v2.0升级到了OpenGL ES 2.0。OpenGL ES 2.0不再分配2次方纹理大小了。但减少文件IO和绘制调用的福利仍然有效。那么怎么样关联动画?正如我们所见,sprite sheet没有和动画有必然会发生的关系。但考虑到以上这些福利,sprite sheet动画是有效率的。在cocos2d中有不同的方法来创建sprite sheet动画。
从.png和 .plist文件中创建
在cocos2d-x 0.x和1.x 版本中,CCSpriteSheet是用于这个目的。然而 自从v2.0开始CCSpriteBatchNode已经替代了CCSpriteSheet。
一个CCSpriteBatchNode对象包含所有精灵帧的实际图像纹理。你必须添加它到场景中。即使它不会绘制它自己。但它只需要一部分的渲染管道。例如:
- CCSpriteBatchNode* spritebatch = CCSpriteBatchNode::create("animations/grossini.png");
下一步,你需要使用CCSpriteFrameCache单例来跟踪帧名和宽高。下面是prite sheet的矩形区域,例如:
- CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
- cache->addSpriteFramesWithFile("animations/grossini.plist");
一旦你的sprite sheet和帧被载入,并且sprite sheet被添加到场景中,你能使用“createWithSpriteFrameName”方法来创建精灵用于这些帧数中,并作为一个孩子把这个Sprite添加到batch中:
- m_pSprite1 = CCSprite::createWithSpriteFrameName("grossini_dance_01.png");
- spritebatch->addChild(m_pSprite1);
- addChild(spritebatch);
createWithSpriteFrameName方法会从grossini.plist中找到正确的坐标和矩形,然后裁切纹理到一个精灵帧中。现在我们需要创建一个CCArray对象并添加所有动画帧到它里面去。对于这个动画,我们知道所有14帧有同样的尺寸,因此我们可以用一个循环遍历它们,当添加到第14帧的时候跳出循环。
- CCArray* animFrames = CCArray::createWithCapacity();
- char str[] = {};
- for(int i = ; i < ; i++)
- {
- sprintf(str, "grossini_dance_%02d.png", i);
- CCSpriteFrame* frame = cache->spriteFrameByName( str );
- animFrames->addObject(frame);
- }
最后,我们需要创建一个CCAnimate动作实例,我们可以在CCSprite 执行。我们也把CCAnimate动作包裹到CCRepeatForever 动作里,然后你想要的就是永远重复这个动画:
- CCAnimation* animation = CCAnimation::createWithSpriteFrames(animFrames, 0.3f);
- m_pSprite1->runAction( CCRepeatForever::create( CCAnimate::create(animation) ) );
文件动画
CCAnimationCache 能载入xml/plist文件,很好的描述了批处理节点,精灵帧名字和它们的矩形。接口更容易使用
- CCAnimationCache *cache = CCAnimationCache::sharedAnimationCache(); // "caches" are always singletons in cocos2d
- cache->addAnimationsWithFile("animations/animations-2.plist");
- CCAnimation animation = cache->animationByName("dance_1"); // I apologize for this method name, it should be getAnimationByName(..) in future versions
- CCAnimate animate = CCAnimate::create(animation); // Don't confused between CCAnimation and CCAnimate :)
- sprite->runAction(animate);
三.坐标系统
不同坐标系统的介绍
1.笛卡尔坐标系统
你在学校的时候可能知道笛卡尔坐标系统它大量用于几何课程中。如果你已经忘记了,下面这些图片会让你马上回想起来:
在手机游戏开发中,你会遇到3种坐标系统
2.UI坐标系统
UI坐标系在iOS/Android/Windows SDK中常见:
原点(x=0,y=0)在左上角。
X轴从屏幕的左边往右边增加。
Y轴从屏幕的顶部往底部增加。
如下所示:
3.Direct3D坐标系统
DirectX使用的是左手笛卡尔坐标系统。
4.OpenGL和Cocos2d坐标系统
Cocos2d-x/-html5/-iphone和OpenGL一样使用同样的坐标系统,它被叫做右手笛卡尔坐标系
在2D世界中,我们仅使用X轴和Y轴。因此在你的cocos2d游戏中:
原点(x=0, y=0)在屏幕左下方,这意味着屏幕在右手笛卡尔坐标系的第一象限
X轴从屏幕的左边往右边增加。
Y轴从屏幕的底部往顶部增加。
下图更直接的解释了cocos2d-x的坐标系:
注意它不同于常见的UI坐标系和DirectX 坐标系
父类于子类
每个类都是CCNode(这是cocos2d-x的最基类,就像java中的Object一样)的子类,并且都有一个anchorPoint(锚点)属性。当确定绘制对象的位置时,cocos2d-x将联合position和anchorPoint属性。当旋转对象时,cocos2d-x也会根据此锚点旋转。我们创建一个父类(灰色)精灵和一个子类(蓝色)精灵。并且父类的位置为cpp(100,100),子类的锚点设置为中心,代码如下所示:
- CCSprite* parent = CCSprite::create("parent.png");
- parent->setAnchorPoint(ccp(, ));// Anchor Point
- parent->setPosition(ccp(, ));
- parent->setAnchorPoint(ccp(, ));
- addChild(parent);
- //create child
- CCSprite* child = CCSprite::create("child.png");
- child->setAnchorPoint(ccp(0.5, 0.5));
- child->setPosition(ccp(, ));
- parent->addChild(child);//add child sprite into parent sprite.
虽然我们设置子类的cpp(0,0),但父类的位置为cpp(100,100),因此运行后效果图,如下所示:
锚点
锚点被用于位置和旋转中。锚点坐标是相对坐标,通常对应于对象中的一个点。例如,锚点cpp(0.5,0.5)对应于对象的中心。当设置对象的位置时,setPosition()方法内部会调用锚点。旋转也是如此。例如,下面是一个精灵,它的锚点为cpp(0,0)并且位置为cpp(0,0);
代码如下所示:
- // create sprite
- CCSprite* sprite = CCSprite::create("bottomleft.png");
- sprite->setAnchorPoint(ccp(, ));// Anchor Point
- sprite->setPosition(ccp(,));
- addChild(sprite);
运行后的效果如下所示:
如果锚点想设置为精灵的中心,则使用ccp(0.5,
0.5),代码如下所示:
- // create sprite
- CCSprite* sprite = CCSprite::create("center.png");
- sprite->setAnchorPoint(ccp(0.5, 0.5));// Anchor Point
- sprite->setPosition(ccp(,));
- addChild(sprite);
运行后的效果如下:
getVisibleSize,
getVisibleOrigin vs getWinSize
VisibleSize返回OpenGL视图中的可见大小。如果不调用CCEGLView::setDesignResolutionSize()的情况下它的值等于getWinSize
getVisibleOrigin返回可见的OpeaGL视图中的原点。更多细节可以参考官网的Multi resolution support
怎么转换到co坐标系
1.convertToNodeSpace(转换到节点空间):
convertToNodeSpace将被用于有一个大地图的骰牌游戏。convertToNodeSpace 将转换你的openGL触摸co-坐标到.tmx地图中或其他相似的文件中。例如:以下图片显示了2个节点。node1的锚点为(0,0),node2的锚点为(1,1)。
我们调用CCPoint point =
node1->convertToNodeSpace(node2->getPosition()); 转换 node2的屏幕坐标到node1的本地坐标。node2的位置为(-25,-60),如下图所示 :
2.convertToWorldSpace(转换到世界空间):
convertToWorldSpace(const
CCPoint& nodePoint)
转换节点坐标到屏幕坐标。convertToWorldSpace将一直返回屏幕坐标,如果你想要在精灵上捕捉信号,但需要移动/缩放你的layer时,这个方法可能很有用。通常父节点通过子节点的位置调用这个方法,返回子节点的世界位置作为结果。如果调用者不是父节点,那么调用这个方法似乎毫无含义。
例如:
- CCPoint point = node1->convertToWorldSpace(node2->getPosition());
上面的代码将转换节点2的坐标到屏幕坐标中。例如如果节点2的位置是(0,0),它在节点1的左下方,它不一定在屏幕上。节点2在屏幕的位置将被转换为(0,0),在本例中为(15,20),如下图所示:
3.convertToWorldSpaceAR(相对于锚点转换)
convertToWorldSpaceAR将返回相对于锚点的位置:如果我们的场景根节点layer的锚点为cpp(0.5f,0.5f)这是默认的。convertToWorldSpaceAR 将返回相对于屏幕中心的位置
convertToNodeSpaceAR逻辑和convertToWorldSpaceAR一样,如下面代码所示:
- CCSprite *sprite1 = CCSprite::create("CloseNormal.png");
- sprite1->setPosition(ccp(,));
- sprite1->setAnchorPoint(ccp(,));
- this->addChild(sprite1);
- CCSprite *sprite2 = CCSprite::create("CloseNormal.png");
- sprite2->setPosition(ccp(-,-));
- sprite2->setAnchorPoint(ccp(,));
- this->addChild(sprite2);
- CCPoint point1 = sprite1->convertToNodeSpace(sprite2->getPosition());
- CCPoint point2 = sprite1->convertToWorldSpace(sprite2->getPosition());
- CCPoint point3 = sprite1->convertToNodeSpaceAR(sprite2->getPosition());
- CCPoint point4 = sprite1->convertToWorldSpaceAR(sprite2->getPosition());
- CCLog("position = (%f,%f)",point1.x,point1.y);
- CCLog("position = (%f,%f)",point2.x,point2.y);
- CCLog("position = (%f,%f)",point3.x,point3.y);
- CCLog("position = (%f,%f)",point4.x,point4.y);
结果为:
position = (-25.000000,-60.000000)
position = (15.000000,20.000000)
position = (-25.000000,-60.000000)
position = (15.000000,20.000000)
cocos2d-x开发记录:二,基本概念(动作,动画,坐标系统)的更多相关文章
- Qt移动应用开发(二):使用动画框架
Qt移动应用开发(二):使用动画框架 上一篇博客介绍了怎样使用Qt的QML来对屏幕分辨率大小进行适应,其实,不同分辨率的适应是一个很棘手的问题,除了分辨率不同外,宽高比(aspect ratio)也不 ...
- OpenHarmony标准设备应用开发(二)——布局、动画与音乐
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 邢碌 上一章我们讲解了应用编译环境准备,设备编译环境准备,开发板烧录,将一个最简单的 OpenAtom OpenHar ...
- cocos2d-x开发记录:二,基本概念(骨骼动画)
九,骨骼动画 1.骨骼动画vs Sprite sheets 你能使用sprite sheets 创建动画,它很快又容易.直到你意识到你的游戏需要大量的动画并且内存消耗越来越高,并且需要时间载入全部数据 ...
- Dokuwiki 二次开发记录
Dokuwiki 二次开发记录 [转]http://www.syyong.com/other/Dokuwiki-Secondary-Development-Record.html DokuWiki 是 ...
- SQL开发技巧(二)
本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...
- Chrome扩展开发之二——Chrome扩展中脚本的运行机制和通信方式
目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...
- MS CRM 2011的自定义和开发(11)——插件(plugin)开发(二)
http://www.cnblogs.com/StoneGarden/archive/2012/02/06/2339490.html MS CRM 2011的自定义和开发(11)——插件(plugin ...
- .NET Web开发总结(二)
第二章 4.1 Application对象 在.NET开发中具有举足轻重的作用 Application对象的作用和运行机制存储所有用户的信息将一个网站创建一个应用程序一 . 创建一个Global文件 ...
- SQL开发技巧(二) 【转】感觉他写的很好
本文转自: http://www.cnblogs.com/marvin/p/DevelopSQLSkill_2.html 本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列 ...
- Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发
一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...
随机推荐
- spring源代码系列(一)sring源代码编译 spring源代码下载 spring源代码阅读
想对spring框架进行深入的学习一下,看看源码,提升和沉淀下自己,工欲善其事必先利其器,还是先搭建好开发环境吧. 环境搭建 sping源代码之前是svn管理,如今已经迁移到了github中了.新版本 ...
- Java File 与 Bytes相互转换
public static byte[] fileToBytes(String filePath) { byte[] buffer = null; File file = new File(fileP ...
- STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partial_sort / partial_sort_copy ------------- ...
- 算法笔记_126:算法集训之编程大题集二(Java)
目录 1 连续数的公倍数 2 漏掉的账目明细 3 罗马数字转十进制 4 逻辑推断 5 平面4点最小距离 6 取球博弈 7 人民币金额大写 8 人员排日程 9 三角螺旋阵 10 手机尾号评分 1 ...
- Unix时间戳转换
import time def timestamp_datetime(value): format = '%Y-%m-%d %H:%M:%S' # value为传入的值为时间戳(整 ...
- 页面回到顶部的三种实现(锚标记,js)
一.使用锚标记返回页面顶部 使用HTML锚标记最简单,就是看起来有点不好看,点击后会在地址栏显示这个锚标记,其它的倒没什么. 页面顶部放置: <a name="top" id ...
- eclipes设置默认注释作者
打开Perfences首选项页,搜索Template,找到Java>> Code Style >> Code Template功能,在打开的树中,找到Comments.Type ...
- java beanUtils框架
beanUtils是Apache觉得sun公司的内省不够爽,自己又开发了一套可以操作JavaBean的API 所以beanUtils是第三方jar包,使用beanUtils要导包: 在工程目录下新建一 ...
- DIV+CSS专题:十天学会DIV+CSS
DIV+CSS专题:十天学会DIV+CSS,在网上看到的.感觉蛮好,推荐一下. 十天学会DIV+CSS(WEB标准)CHM格式文件下载 第十天 div+css网页标准布局实例教程(三) 第十天 div ...
- 解决Mysql中文乱码问题的方案
MySQL会出现中文乱码的原因不外乎下列几点: 1.server本身设定问题,例如还停留在latin12.table的语系设定问题(包含character与collation)3.客户端程式(例如ph ...