(转载)cocos2d-x学习笔记(持续更新)

(转载)cocos2d-x学习笔记(持续更新)

 

http://blog.csdn.net/we000636/article/details/8263503

 

接受触屏事件的优先级是值越小,响应触屏事件的优先级越高

 

Z值越大,越外面

 

 

粒子系统设计工具Particle Designer软件  目前只支持MAC平台 导出 plist文件

地图设计工具Tiles 目前有两个版本,一个是Java版本,另一个是QT版本  导出TMX格式文件

图片编缉工具,将多个精灵整合成一个大图:  导出plist文件

Zwoptex 两个版本,一个是flash已不再维护,另一个是Mac版本,收费软件

TexturePacker:拥有Zwoptex 90%的功能,免费版中会自动向导出的图片中加入红色

 

 

JNI:允许Java代码与其它语言写的代码进行交互

 

 

cocos2d-x好像对tmx中使用bmp图片不支持

 

 

BombMan.win32.exe 中的 0x10007f50 (libcocos2d.dll) 处最可能的异常: 0xC0000005: 写入位置 0x0000000c 时发生访问冲突

 

BombMan.win32.exe(托管(v4.0.30319)): 已加载“C:\windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_zh-Hans_b77a5c561934e089\mscorlib.resources.dll

在 System.AccessViolationException 中第一次偶然出现的“未知模块”类型的异常

System.AccessViolationException”类型的未经处理的异常出现在 未知模块 中。

这里报错,是因为我的 monster 对象中,animation对象未能取出成功。所以才会发生访问冲突。其实就是一个nullpoint错误~

 

 

绘制游戏地图时应注意的问题:

1.Tiled编缉器支持同一个块层使用多个图块纹理,但cocos2d-x中的CCTMXTiledMap类仅支持一个块层对应一个纹理。所以我们需要尽量将图块纹理分类和合并,在每个块层上仅使用一个纹理图来绘制。

2.CCTMXTiledMap不允许任何一层(CCTMXLayer)中没有任何元素,否则解析TMX时会报错。

3.关于是否要将图块导出成外部图块,这一点需要看游戏本身的需求。由于Tiles不支持加密,外部图块的数据会被他人看到,所以对于正式发布的游戏,不建议将影响游戏平衡性的数值配置在外部图块中 

 

 

不要在项目名中使用空格,虽然Xcode对是否有空格不产生影响,但是当你使用其它工具时,带空格的项目名可能会引起不必要的麻烦,所以“不在项目名中使用空格”其实是为了规避潜在风险而采用的手段。在文件命名中,只有数字,减号和下划线是永远不会出错的

 

 

Libs:第三方库文件

 

 

找个时间将cocos2d-x目录解释下

 

 

Cocos2d-x中我们生成对象,一般都会自动设置其为自动释放对象。而这里就有个问题。如果我们在上一帧生成了此对象,在下一帧想访问它时,发现会出现错误,因为目标对象不存在了,已经被自动释放。解决办法是什么呢?(不包括数组)

1.将目标对象显示的添加为子节点,即addChild 使其成为子节点,所以cocos2d会保留它。但之前的对象还是没有保留,我们可通过GetChild来访问它。不保留一个内存被其它类或对象管理的对象称为“弱引用”。

2.显示的调用目标对象->retain()操作,如果目标对象没有显示的添加为子节点,都应对应其->release()操作,来释放对象。

3.通过AddChild成为子节点的对象,cocos2d-x会周期性检测对象有没有被使用,不再使用的对象会执行->release()操作。

4.Cocos2d-x周期性检查所有对象,对没有实例的对象进行释放操作。实现内存管理

还有一种,不需要添加为子节点且不需要显示调用->retain()就可以实现内存管理的方法:就是将CCNode对象添加到集合中,典型的就是CCArray,CCArray会对每个被添加进来的对象进行->retain()处理,对每个被删除的对象进行->release()处理

 

 

Assert断言

CCAssert跟cocos2d for iphone里的NSAssert的作用相似,使用断言可以创建更稳定,品质更好且不易于出错的代码。当需要在一个值为FALSE时中断当前操作的话,可以使用断言。单元测试必须使用断言。

除了类型检查和单元测试外,断言还提供了一种确定各种特性是否在程序中得到维护的极好的方法。

 

 

游戏开发者关注CPU和图形芯片的同时,更需要关注设备的RAM。

不要将RAM和闪存搞混淆,闪存是存储MP3,视频,应用程序和图像的地方。闪存就像计算机中的硬盘。RAM是内存,是程序运行时,存储代码,数据和图像的地方

 

每个设备都会存在“内存警告阈值”,一但我们程序使用的内存超过这个阈值,会被警告,甚至可能被操作系统强制关闭

Cocos2d-x和cocos2d-iphone都可以调用Director中的方法purgeCachedData()方法来帮助释放一些内存

 

当遇到程序崩溃时,建议重启设备,因为重启设备可以释放一些内存。应用程序发生突然退出的最主要原因就是内存耗尽。

 

 

IOS模拟器缺点:

1.不能评估性能:在IOS模拟器上运行的游戏,性能完全依赖计算机的CPU,渲染过程甚至没有使用MAC图形芯片的硬件加速功能

2.不能评估内存使用量:IOS模拟器可以使用计算机配置的所有内存,所以不会接收到内存报警

3.无法使用IOS设备的所有功能:比如设备转向,像多点触碰,加速计,振动,位置信息的获取

4.运行时表现可能不一样:可能在IOS模拟器运行良好的游戏,在真机上运行可能变得很慢甚至运行不起来

 

 

Xcode默认有两种构建方式:DEBUG和RELEASE.

建议打印日志都用CCLOG,因为CCLOG只在调试构建中才被编绎,在发布构建时会被删除。

这也是影响游戏性能的主要原因之一。

 

 

找个时间看下cocos2d-x/files/includes/目录下的ccConfig.h,ccEventType,ccMacros.h三个目录下的静态值及宏命令

 

 

场景图必段以CCScene对像作为根节点,对其它场景/层/节点结构不做强制要求,所以可以使用CCNode代替CCLayer类来创建“层”。事实上在我们创建层时一般会选择CCNode,而不是CCLayer类。CCLayer类封装了接收键盘和鼠标及加速计输入,所以多数情况会增另不必要的开销,除去处理输入的代码,CCLayer就是一个CCNode类。所以,在不需要处理输入的层中,会使用CCNode代替CCLayer节省不必要的开销

 

 

子节点的位置相对于父节点,且继承了父节点的特定属性(scale和 rotation)

 

 

anchor point 究竟是怎么回事? 之所以造成不容易理解的是因为我们平时看待一个图片是 以图片的中心点 这一个维度来决定图片的位置的。而在cocos2d中决定一个 图片的位置是由两个维度 一个是 position 也就是图片的中心点 另外一个是anchor point。只要我们搞清楚他们的关系,自然就迎刃而解。

他们的关系是这样的: 

actualPosition.x = position.x + width*(0.5 - anchor_point.x); acturalPosition.y = position.y + height*(0.5 - anchor_point.y)

actualPosition 是sprite实际上在屏幕显示的位置, poistion是 程序设置的, achor_point也是程序设置的。

 


对于不绘制的父节点,那么子节点标签将相对视图(视图相对于父节点)的左下角放置。对于绘制的父节点,子节点标签将会以父节点纹理的左下角为原点(左下角为中心)显示

 

 

每一个节点Node只能有一个scheduleUpdate()方法,这个方法不能被unschedule:中断,只被unscheduleAllSelectors中断

 

 

Cocos2d-iphone中的_cmd命令,对应cocos2d-x中的什么命令

 

 

CCLayerColor可以用来做场景切换时的淡入淡出

 

CCTransitionScene :可以作为中间场景管理过渡动画

继承CCTranstionScene的一些过渡类:

CCTransitionFade:淡入淡出到某个指定的颜色的背景,然后恢复

CCTransitionFadeTR(还有其他三种版本):瓦片翻转,渐渐显示新场景

CCTransitionJumpZoom:旧场景弹跳着缩小,新场景弹跳着放大

CCTransitionMoveInL(还有其它三种版本):旧场景移出,同时新场景从任意方向移入

CCTransitionSceneOriented(还有其它六种版本):整个场景会翻转过来

CCTransitionPageTurn:翻页效果

CCTransitionRadialCCW(还有一种版本):类似于雷达屏幕,使用雷达扫描动画显示新场景

CCTransitionRotoZoom:旧场景边旋转边缩小,新场景边旋转边放大

CCTransitionShrinkGrow:旧场景缩小,新场景在旧场景的基础上放大

CCTransitionSlideInL(还有其它三种版本):新场景从各个方向掠过旧场景

CCTransitionSplitCols(还有另一种版本):旧场景切成竖条,从上方或下方散开,新场景显现

CCTransitionTurnOffTiles:新场景呈瓦片状替代旧场景

 

 

当进行场景替换时,新场景往往在旧场景释放前就被加载到内存中,这会导致内存负荷瞬间增大。所以,场景替换是最容易引发内存警告或者干脆导致程序崩溃的。当你的游戏使用大量内存时,就应该尽早的对场景切换的情况进行测试

 

 

PushScene和PopScene这两个方法是在不释放旧场景内存的情况下运行新场景,推进新场景相当于在当前可见的纸上再放一张纸,而之前的纸位置何持不变。适用情况:

1.推进一个经常被用到的场景,例如游戏中的Setting场景。

2.当想要保留最初场景状态时,而不想保留和加载状态。例如在游戏过程中查看排行榜,推进排行榜场景时,游戏场景不会继续运行,会被暂停。

由于每当在推进场景时,需要保证总是有足够的额外内存可供推进的场景使用,但这一点很难测试。建议要推进的场景都应该是轻巧的,只占用少量的内存,并且只弹出自身,而不会推进其它场景

 

场景过渡,只能使pushScene产生场景过渡效果,而不能使popScene产生过渡效果,所以千万不要将过渡效果与popScene一起使用

 

 

一般处理屏幕触摸输入,在平常的开发中,一般有两种方式:

(1)继承CCLayer,在层中处理触屏函数。

(2)(2)继承CCSprite和CCTouchDelegate(或者其子类)。

 

 

IOS设备上的文件名是区分大小写,而在模拟器上是不区分大小写,这要注意

 

纹理大小的问题非常值得一提,到目前为止,IOS设备只支持尺寸为“2 的n次幂”的纹理,所以纹理的宽度和高度大小只能是“2的n次幂”。(如果纹理的尺寸大小不符合上面的规定,那么系统将会自动生成一张最接近纹理尺寸大小且符合规定的纹理)

 

 

CCSpeed动作不能被加入到CCSequence动作中,因为只有从CCFiniteTimeAction派生的动作才能被用到序列中

 

 

CCGridAction网格动作的特色在于三维效果,例如翻页效果,波浪和流体效果。其缺点是,如果不启用需要大量内存的深度缓冲,3D效果看上去会失真,但是启用的话对显示性能又会造成负面影响,特别是在第一代和第二代设备上。

为了启用深度缓冲,需要在项目应用程序委托类中修改初始化EGALView类的那个行代码,以启用对深度缓冲的支持。具体来说,就是将depthFormat参数由默认值0改为GL_DEPTH_COMPONENT16_OES(用于16位深度缓冲)或GL_DEPTH_COMPONENT24_OES(用于24位深度缓冲)。具体是使用16位还是24位视情况而定。

 

 

单件类:从理论上来讲,单件(Singleton)就是一个普通的类,它在应用程序的整件生命周期中只被实例化一次。

慎用单件类,因为它带给我们是类间的强依赖性,紧耦合。

 

 

IOS游戏首选的图像文件格式是PNG

 

 

contentSize内容尺寸不一定等于纹理尺寸

 

 

Player.position.x += value这样的语句对Objective—C中的属性是不起作用的

 

 

精灵的移动:

1.不需要频繁改变对象的方向和速度。且移动的动作为相对使用期较长的情况。可以使用move动作实现。

2.需要频繁的改变对象的方向和速度。使用move动作都不是一个好的选择,首先频繁的创建新对象分配和释放内存增加了额外开销,更糟糕的是,如果不为动作留出一点时间,动作是不会执行的。例如,如果在每帧停止所有动作并为对象添加一个新的名为MoveBy的动作,对象不会有一丁点的移动!MoveBy动作只会在下一帧改变对象的位置。但是在下一帧你就停止了所有的动作,并加入了一个新的MoveBy动作。这样做下去只会让对象寸步不移。

针对这种解决方法是,使用速度代替对精灵位置的直接修改。为些可以设计三个设计参数:

1.减速值  值越低,改变方向速度越快

2.加速计灵敏度   值越高,对加速计输入反应越敏感

3.最大速度

速度 = 速度 * 减速值 + 加速计输入 * 加速计灵敏度

 

 

由于IOS的ARM CPU不支持硬件上的除法运算,所以使用乘法改写除法是个好习惯

 

 

使加速度输入变得更加平滑的技术叫作“过滤”,过滤加速计的输入值可以减轻加速过程中突然出现的峰值的影响(高通道过滤),或者消除因重力或手的抖动而产生的影响(低通道过滤)

另外有多种方式可以让受加速计控制的物体看上去好像具有动量一样。为了实现这一效果,需要对输入值应用缓动函数。缓动函数能够模拟物体在同一方向上匀速移动直到被外力终止。换句话说,缓动能够模拟牛顿的第一定律(惯性定律)和牛顿第二运动定律(物体加速度的大小跟作用力成正比,跟物体的质量成反比,加速度的方向跟作用力的方向相同)。

 

 

在加载同一场景应先加载另个一个(过渡)场景,否则加载同一场景会使程序崩溃

 

 

标签:

创建标签时,最简单最灵活的方法是使用CCLabelTTF类,但不适用频繁更改标签文本。因为更新文本时,整个纹理都要使用IOS字体渲染方法重新创建,且分配一个新纹理的内存并释放旧的内存同样需要时间。这样对游戏性能造成的负面影响是不能接受的。

如果要创建需要频繁更改文本的标签,可以用CCLabelBMFont代替,它渲染的是位图字体,而不是TrueType字体。

 

 

CCLabelBMFont:就是占用更多的内存为代价加快标签的更新。在游戏中使用位图字体是个很棒的选择,但位图字体也有很大的不足之处,其位图字体的大小是固定的。

 

 

创建位图字体:工具介绍三种

1.Hiero:免费的JAVA WEB 程序。存在一些BUG

2.Glyph Design:收费,但稳定好用

BMFont:免费,但只运行在Windows系统下。

 

 

创建支持Retina屏幕的位图字体很简单。正常创建字体并导出,这将是非Retina屏幕字体或SD字体。然后在位图工具中将字体大小增加一倍,再以相同文件名,但是加上hd后缀,重新导出字体,现在同时有了普通/sd和Retina屏幕/HD大小的字体。

如果在具有Retina屏幕的设备上运行游戏,并且启用了对Retina屏幕支持,cocos2d将自动识别并使用带有hd后缀的字体

 

 

Cocos2d播放音频插件介绍两种:

1.SimpleAudioEngine:最好,也最简单的方法,不属于cocos2d,是CocosDenshion的组成部分。CocosDenshion是cocos2d的第三方插件,同cocos2d一起发布

2.ObjectAL:具有清晰的API,文档也做得很完善。

 

对于音乐和时间更长的演说文件,MP3文件是首选,注意一次只能在后台播放一个MP3文件(即只可能有一个背景音乐),因为只能有一首MP3在硬件中解码。

音效,WAV或CAF文件格式16位PCM(未压缩)音频效果最好。对于游戏大多数音效,22.5KHZ的采样率就足够了,好果想要更清晰的音质,应该使用44.1KHZ。

 

根据苹果的音频说明,IOS设备首选的音频格式是打包为CAF文件的16位从小到大变化的线性PCM。

 

 

音频编缉工具介绍三种:

1.Audacity:免费

2.SoundConverter:免费只可编缉500KB以下的,15美元永久免费

3.Afconvert:免费的命令行工具

 

 

Unity中渲染显示是基于相机的,场景中绘制的物体或图像是相对于相机的。

 

Cocos2D中渲染是直接相对于手机屏幕,所以在制作可移值的游戏时,最好不以固定坐标来规定游戏物体位置。而是获取屏幕大小,再针对性绘制比例位置。

 

 

pauseSchedulerAndActions 暂停当前更新和动作,在执行OnExit()方法里被调用。

resumeSchedulerAndActions 恢复当前更新和动作,在执行OnEnter()方法里被调用。

 

 

LoadingScene充当了一个中间场景的角色,它派生Cocos2D中的CCScene类。使用它对内存有很大影响。由于使用了轻量的LoadingScene替换当前场景,然后使用实际目标场景替换LoadingScene,因为此这为Cocos2D提供了足够的时间来释放上一次场景占用的内存空间。前后两个复杂场景在内存中并示同时存在,这样降低了场景转换时的内存使用高峰

 

两条规则:

1.不要在节点的Init方法中调用CCDirector的replaceScene方法

2.遵守第一条规则,原因,程序会崩溃。Director无法应付在一个正在被初始化的节点中替换场景的情况

 

 

注意声明为Static的变量在类被释放后依然存在,所以用Static变量存储动态分配类的指针时要相当小心,确保该对象要么指向有效的对象,要么为NULL。

 

 

addTargetedDelegate(CCTouchDelegate * pDelegate,

int nPriority,

bool bSwallowsTouches 

)第三个参数什么意思 后面有答案

 

 

CCTouchBegin返回YES以表时此次触摸事件有效且不应由其它低优先级的目标触摸输入委托处理

 

 

游戏中关卡实现两种方法:

1.使用场景来实现关卡

2.使用独立的层来实现关卡

选择哪种方式视情况而定

 

 

CCLayerColor可以理解为背景色

 

 

为每种游戏对象创建单独的类很重要,可能新手第一反应就是将该类继承CCSprite,然而这不是个好的做法,好的做法是使用CCSprite复合游戏对象,即继承CCNode类,在类中实现CCSprite(显示)和对象逻辑

 

 

事实上任何类都可以通过使用CCTouchDispatcher来接收触摸输入,只需要实现CCStandTouchDelegate或CCTargetedTouchDispatcher两个协义中的其中一个即可

 

 

CCProgressTimer进度计时器适用于任何类型的进度显示,如显示进度条或者使图标变为“有效”(如魔兽世界里的图标)。进度计时器基于精灵,并基于百分比,只使一部分显示来表现进度特征。进度计时器不会自动更新它自己,需自己加ScheduleUpdate去更新它。三种进度计时器类型可供选择:径向,纵向和横向

 

 

CCParallaxNode:通常用于2D游戏,它通过将不同层次的图像以不同速率运动来得到景深效果,即前景图像比背景图像的移动速度要快。

为什么视差能够创建景深效果?这是因为我们的大脑是这样工作的。想象一样你坐在一辆高速行驶的车中向窗外看。你会注意到路边的树(离你最近)一闪而过,甚至看不清它们。再往远看一点,会发现远处谷仓的速度要慢很多。再看看地平线附近的山,你甚至注意不到它们在移动。这就是包含无数视差层的三维世界,视差效果的体现。在2D游戏中,我们只能使用两到三个视差层来模拟这个效果,每个层都相对于其它层以特定速度移动,起到欺骗大脑的作用,让你误以为它离你的观察点有一定的距离。

 

CCParallaxNode:virtual void addChild(CCNode * child,

unsigned int z,

const CCPoint & parallaxRatio,

const CCPoint & positionOffset 

)

特殊的初始化器,parallaxRatio表示移动的乘数因子,positionOffset表示位置的偏移

一旦将子节点添加到CCParallaxNode之后,就不能修改子节点的位置。最底层的图像滚动到尽头就会露出下面的背景。如果要实现单向或者双向无限滚动,需要实现自己视差系统

 

 

CCRIbbon:使用一队图像创建链状效果。 在Cocos2D-x中被弃用了

取代它的可以考虑使用CCMotionStreak

CCMotionStreak:实际上相当于CCRibbon的封装器。使用它可以使CCRibbon已显示的元素表现出不同程度的淡出效果。像飞机拉线似的拖尾巴一样。

CCMotionStreak* create(float fade,

float minSeg,

float stroke,

ccColor3B color,

const char * path 

)参数意义:淡出速度,越小速度越快,片段数量,片段宽,颜色,纹理路径

 

 

Cocos2d的坐标系与分辨率无关,它使用的是点而不是像素,在SD设备上,1点等于一像素,而在支持Retina显示屏幕的设备上,1点等于2像素。总的来说cocos2d的坐标系是480*320.

 

 

Cocos2d加载图像时很智能,如果代码启用了支持Retina显示屏幕的支持,并且程序运行在一个具有Retina屏幕显示屏幕上的设备时,那么Cocos2D会首先尝试加载带有-hd后缀的精灵。因此在一个具有Retina屏幕上设备加载文件ship.png,它会首先尝试加载ship-hd.png,如果该文件不存在或者设备不具有Retina显示屏幕,将加载SD分辨率图像ship.png。

 

 

如果支持Retina显示屏幕,应该使用HD分辨率创建所有图像,然后将它们缩小50%,并另存为SD图像,放在SD图像无法获得Retina显示屏所需要图像质量的。

 

 

CCSpriteBatchNode:初始化时为其传入一个文件作为参数的原因在于,所有添加到其节点的CCSprite节点,都必须使用相同的纹理。如果违反了这一点,调试控制台会出现错误。注意这货被不会被显示

 

将CCSpriteBatchNode与纹理图册结合使用,将使绘制不会局限于一幅图像上。

 

 

具有相同Z轴次序的所有节点按照它们被添加到场景层次结构的顺序进行绘制

 

 

子弹的位置是通过将子弹的速度乘以自上次更新经历的时间,然后将结果加到原来的位置进行更新的。即Unity3D时会乘以deltaTime一样的道理。对于每帧更新节点位置这样简单的操作,最好避免使用move动作不断的移动节点

 

 

节点不应该保留任何不属于它的其它节点,特别是子节点不应该保留父节点,一个原因是,子节点不需要保留已经由Cocos2D的节点层次结构处理的父节点。保留父节点及上层节点将导致它们无法释放,而如果父节点不释放,子节点就不能释放。

 

 

释放是指release()操作,这也是上述的原因,因为如果子节点对父节点进行release()操作,那么实例数为0,系统将为释放父节点内存。使父节点不再可用。

 

到里不得不谈一下与Unity的区别

首先我们必须理清两个概念,引用与指针

引用,一个变量的别名,为什么引入别名呢?原因是我们想定义一个变量,他共享另一个变量的内存空间,使用别名无疑是一个好的选择。变量是什么?是一个内存空间的名字,如果我们给这个内存空间在起另外一个名字,那就是能够共享这个内存了,引用(别名)的由此而来。系统不再为引用变量分配内存空间
指针,指向另一个内存空间的变量,我们可以通过它来索引另一个内存空间的内容,本身有自己的内存空间

 

在Cocos2D中,用的是指针,在子节点如果存在一个指针指向父节点,这个指针本身就有自己的内存空间,当我们不再使用这个子节点,就需要释放此指针的内存空间,但另一方面由于此指针是指向父节点类型的,在释放时,会对父节点类型进行release()操作,直接导致父节点类型实例为0,其相关指针全部释放内存,父节点不再可用。

在Unity3D中,用的是引用,就不会涉及到这些问题。(引用是神器)

 

 

“对象池化”常见的一种做法是在游戏启动时实例化固定数量的对象,然后根据需要启用或禁用/隐藏对象,这就是所谓的“对象池化”(这种做法在游戏开发中经常用到以提升性能)

 

 

在Cocos2d中使用指定的选择器(schedule),首先取消指定该选择器是一种相当常见的操作

 

 

由于Cocos2d会自动缓存所有的图像,所以在更换场景中常常要卸载纹理,但注意不能在一个场景的init()方法卸载纹理,可以在LoadingScene里加代码来做处理

 

 

TexturePacker使用了几个优化纹理小技巧来实现最优打包率

1.首先移除了每幅图像的透明边框像素

2.会旋转图像以优化纹理图册空间的使用

 

小游戏数据存储方式一般采用plist xml.大数据用SQL

 

 

类似于Cocos2d中的NSNumber,在Cocos2d-x中浮点数对象是什么

 

 

 

重复贴图:可以指定大小的矩形区域里让任意纹理重复出现

 

 

虚拟手柄:解决方案 SneakyInput (Iphone版)

核心文件:

SneakyButton和SneakyButtonSkinnedBase

SneakyJoystick和SneakyJoystickSkinnedBase

ColoredCircleSprite(可选)

 

 

系统只渲染纹理中的不同部分

 

 

游戏物体只有在可见的情况其逻辑代码才会被执行

 

 

CCSpriteBatchNode只能包含基于CCSprite的对象

 

 

CCParticleSystem:点粒子系统 在1,2代IOS设备上运行快,在3,4代IOS设备上不是很流畅

CCParticleSystemQuad:方形粒子系统,在1234代IOS设备上流畅运行,在3,4代上运行较12代快

推荐使用方形粒子系统,或者通过构建目标来替你判断应该使用哪个粒子系统,我们使用预处理器定义ARCH_OPTIMAL_PARTICLE_SYSTEM而不是实际的类名来在代码编绎过程中判断应该使用的粒子系统。这个命令在Cocos2D中是基于设备处理器架构的,得到的判断将会是CCParticleSystem或CCParticleSystemQuad。

 

关于粒子系统属性分析:

1.变化度属性:很多属性后缀是Var的配对属性,它们是变化度属性,用于决定对应属性允许的模糊度范围。比如属性life= 5和lifeVar = 1,表示生命平均周期为5,而变化度1允许生命值在5-1和5+1之间变化

2.粒子数量

3.发射器持续时间:决定着发射器发射粒子的时间长短,当超过时间,将不会再生成粒子。当你想在粒子系统停止发射粒子且已发射出的粒子都消失后,将粒子系统的节点从它的父节点删除的话,可以将autoRemoveOnFinish属性设置为YES。

4.发射器模式:

重力模式:重力模式可以让粒子向一个中心点飞去,或者飞离中心点。优点可以创造非常动态和自然的效果

半径模式:可以上粒子沿着一个圆形旋转,当然也可以生成螺旋状粒子效果,漩涡效果或是旋状上升效果。

5.粒子位置:可以设置positionType来决定发射出的粒子位置随节点位置移动,还是自由不受影响的

6.粒子大小:单位是像素

7.粒子方向

8.粒子生存期:指明了粒子从生命到消失的时间长短。如果屏幕上同时显示的粒子数达到了所允许的最大数量,那么在一些已存在的粒子消失之前将不再生成新的粒子

9.粒子颜色:每个粒子都可以从一个起始颜色渐变到另一个最终颜色

10.粒子混合模式:“混合”指粒子的像素在被显示在屏幕之前所需要经历的计算过程。其工作方式为:当对粒子进行渲染时,将源图像(粒子)的红,绿 ,蓝和透明度与屏幕上已存在的图像颜色信息相混合。确定像素在屏幕上的最终颜色最终公式如下:

(源图像颜色 * 源混合函数) + (目标图像颜色 * 目标混合函数)

self.blendFunc = (ccBlendFunc){GL_SRC_ALPHA,GL_ONE}; 

第一个代表源混合函数,第二个参数代表目标混合函数,

self.blendFunc = (ccBlendFunc){GL_SRC_ALPHA,GL_ONE}; 生成递增型混合效果,当很多粒子得叠时,得到的结果是非常亮的颜色

self.blendAdditive = YES,与上面一样的效果

ccBlendFunc{GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA}得到透明粒子

11.粒子贴图:没有贴图的话,所有的粒子将会是单调的色块。用于粒子效果的贴图最好是云状的,粗略看上去像球形的图像。如果贴图有高对比区域,通常对粒子效果是不利的,粒子贴图最重要的一点是图像尺寸不能超过64*64像素,尺寸越小,粒子效果运行越流畅。

 

 

加载粒子特效所需的贴图文件,这是个很缓慢的过程。解决方法我们可以在Init方法里为需要在游戏中用到的粒子效果调用preloadParticleEffect方法,其方法做的其实就是生成一个粒子特效,但因为返回的是自动释放对象,所以它们的内存会被释放。但加载过的贴图会被保留在CCTextureCache中。

 

 

瓦片地图:使用多个瓦片层可以在cocos2d切换区域。注意每创建一个层都会带来一定的开销,尤其是当在多个层的同一位置都放置瓦片的时候,这会导致每个层都会被绘制。2至4个瓦片层对游戏基本就足够了。Tile允许在一个层中添加多个瓦片层,但是cocos2d在每个层中只支持一个瓦片集

 

 

对象层中的对象Tiles会自动帮你设定对象的x,y,width,height四个属性,x,y代表对象在瓦片地图中的位置。

 

 

在编写OpenGl代码时,修改后恢复状态是个好习惯,否则会影响其它绘制代码产生的结果

 

 

Cocos2d中的Rect是以左下顶点为X,Y。

 

 

被#ifdef DEBUG #endif包含的代码将不会出现在release构建版本中,中能在调试版中看见

 

 

睡眠刚体:它是一种允许物理模拟不需要处理而快速跳过对象的技巧。当施加在一个动态刚体的力量小于临界值一段时间后,该刚体进入睡眠状态。换句话说,如果动态刚体处于缓慢或几乎不移动和旋转状态时,物理引擎将其标记为睡眠状态,并且不再对其施加力量,直到有一个能够使刚体移动或旋转的推动力出现为止。如果游戏中并非所有刚体都在运动,那么应该设置allowBodiesToSleep为True,来激活此特性

 

在BOX2D中,一般32像素代表一米,尽可能将Box2D世界的对象尺寸控制在一米左右。但并不意味不可以创建小于0.1米,或大于10米的对象

 

Box2D世界是通过定期调用Step方法来实现动画的。它需要三个参数。第一个是timeStep,用于告诉Box2D自上一次操作过去的时间,它直接影响刚体在这一步将要移动的距离,建议采用固定时间。第二个第三个是迭代次数,分别为速度迭代次数,位置迭代次数。对于位置迭代次数一般一次就足够了,因为游戏一般不需要更精确的位置。速度的迭代次数更加重要,一个比较好的迭代次数是8,在游戏中,超过10的迭代次数效果不明显,但1~4次迭代次数无法得到稳定的模拟结果

 

PhysicsEditor:依靠这个工具,只须画出一个顶点就可以创建碰撞多边形

 

在Box2D物理引擎中定义碰撞多边形时,需要遵循两条规则:

1.  逆时针定义各个顶点

2.  多边形必须是凸多边形

 

记住,在节点的Draw方法中,所有OpenGlES代码都在Z-order为0的情况绘制图像,如果希望OpenGL ES绘制的图像覆盖其它节点,那么那些节点的z-order需要设置为负值

 

当任何连接着关节的刚体被销毁时,关节会自动销毁

 

cocos2d-x中类似于cocos2d的performselector:withObject:afterDelay的方法:(通知)

答:你问的这个是基于Objective-C特性做出来的一种功能,在iOS SDK中提供的,一般来说在cocos2d中不建议使用这玩意,使用schedule或action来做会好点。因为语言支持度的关系 objective-c是属于讯息传递的语言,也就是说要在不同的类之间传递讯息非常容易但C++中要达到相同的功能是非常复杂的一件事 语言天生的支持度就不够。使用schedule要求无参数方法 需求参数传递用action

 

原代码

[s1 isKindOfClass:[DestHole class]]

修改的代码

bool s1IsDestHole = dynamic_cast<DestHole*>(s1) != NULL;

 

SetBullet方法使得我们可以对高速移动物体进行特殊的连续的碰撞检测,将两次碰撞检测之间物体移动的距离纳入计算范围,因而,子弹模式可以检测到可能被其它方法忽视的碰撞,代价是损失性能

 

Game Center是苹果公司的社交网络解决方案。它可以验证玩家,存储玩家得分,显示排行榜,统计并显示玩家的成就。另外,玩家可以邀请朋友来进行游戏,或者与其他玩家进行快速游戏

 

Game Center只能在IOS4.1以及以上版本的设备中使用,验证用户的设备是否支持Game Center方法,在设备上查找Game Center应用程序,如果存在就可以使用,反之则不可以

 

Game Center的编程特性需要Game Kit API支持。Game Kit提供了编程访问存储在Game Center服务器上的数据的方法。Game Kit还可以显示内置的排行版,成就以及联机页面。它还提供了Game Center没有特性,例如基于蓝牙的点对点网络和语音对话

 

Prefix.pch是预编绎文件,它包含来自外部框架的头文件以便提高项目的编绎速度,当然,在当前的项目中,每一个添加到预编绎头文件中的头文件会使它自己的定义对于当前项目中的每一个源代码文件都有效。预编绎头文件名称总是以项目的名称打头

 

cocos2d-x 2.0 提供一个极有价值的新特征: setDesignResolutionSize() 。

这个函数用于指定一个 OpenGL 视图,然后将这个视图映射到设备屏幕上。根据不同的设定,视图会自动缩放显示内容,为 cocos2d-x 自适应多种分辨率提供了基本支持。

CCSize getWinSize

(

void 

 

)

 

returns the size of the OpenGL view in points.

CCSize getWinSizeInPixels

(

void 

 

)

 

returns the size of the OpenGL view in pixels.

 

setDesignResolutionSize() 设置虚拟分辨率后,会指定一个全局的缩放比例,所有的图片即便是 scale = 100%,也会自动缩放

 

SetFrameSize在Main文件中的意义是存在于Win32程序的

在手机中,手机有屏幕大小(手机分辨率),SetFrameSize相当于模拟手机屏幕

 

 

CCMenu里面的CCMenuItem的位置是可以设置,不是一成不变的水平对齐和垂直对齐

 

 

CCSprite里的透明度设置setOpacity(S),S值限为0-255,0为完全透明

 

 

CCLabelTTF里的SetDimensions(const CCSize s)这是设置文本的显示区域(而不是设置其在几行几列中显示),显示区域相对于屏幕,用于创建CCLabelTTF的字符串中的空格会自动当成换行。

 

 

addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches),bSwallowsTouches为true,则表示消耗掉此触屏消息,后面需要接收触屏消息的对象就接收不到触屏消息了。

 

假如A对象设bSwallowsTouches为true,且ccTouchBegan中返回True,表示此触摸信息已被处理,且会被A对象的ccTouchMoved,ccTouchEnded处理,但此触摸信息不会再被其它注册过响应的类接收。如果返回false表示此信息未被处理,表示此触摸信息未被消耗,将交其至其它注册过响应的类接收。

假如A对象设bSwallowsTouches为false,则ccTouchBegan中的返回值True或False只关系到是否需要被A对象的ccTouchMoved,ccTouchEnded处理,无论是True或False,此触摸信息都不会被消耗掉,将交由其它注册过响应的类接收

 

 

setRotation(angle) 其中angle为角度不是弧度。正数为顺时针旋转,负数为逆时针旋转

setSkewX(s); // 原图片坐标X轴倾斜

setSkewY(s); // 原图片坐标Y轴倾斜

X轴向右为正,Y轴向上为正。

setFlipX(bFlip);  // 水平翻转 就像镜子一样反转,本来一个标志水平向左反转后向右

setFlipY(bFlip);  // 竖直翻转 上下反转

bFlip为true,则图片翻转,false不翻转。注意,翻转是针对原图片的操作,水平翻转相当于在图片编辑软件里水平翻转一样。不根据锚点进行翻转。翻转以后,设置的以前设置的锚点不会随着图片的翻转而改变。比如设置右下角为锚点,则翻转以后,锚点为翻转后的图片的右下角(是不是有点绕?)

 

 

Cocos2d-x中的角度:

0 代表(1,0)

90代表(0,1)

180代表(-1,0)

 

ccpAngle返回角度限定在0~180中,木有负值,只返回两个向量间的弧度

 

 

Cocos2d-x中,setScaleX是以X方向为轴,沿Y轴方向进行缩放,setScaleY反之

 

未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突

未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突

     在使用的过程中,出现了标题中的错误,首先在网上搜了一些方法,费了好大的劲,终于解决了,

关于0xC0000005问题:

0xC0000005: Access Violation错误调试- -

1》数据越界或是定义的指针未释放.

2》空的指针的可能性最大。使用指针前最好能显式的赋值! 
应该是指针的问题

3》内存访问错误,检查指针,是否为空,是否越界等

 

可能性 3 种 
1: 
char *p; 
p = new char[number]; 
delete [] p; 
.... 
// always using p.... 
p = xxx; // access violation 

2: 
char *p; 
memcpy(p, xxx, number); // access violation 

3: 
char *p; 
p = new char[number]; 
delete [] p; 
......... 
delete [] p; // access violation

 

 

Invalid Address specified to RtlFreeHeap - How to Solve

If you have faced the "Invalid Address specified to RtlFreeHeap" problem then there is a high chance you have a mix of debug and release dlls and exe's in your application.

 

 

Flash动画中,只有以图形元件为目标的动画才能导出PNG序例来,否则如果是影片元件为目标,导出PNG序列将只有一帧

 

 

CCRenderTexture
自己的理解

CCRenderTexture类似一张空白的“画布“,用户通过自定义笔刷 (CCSprite*),在touch事件中把笔刷的移动痕迹“记录”起来,从而“画”出各种艺术效果。记录方法很简单,首先 CCRenderTexture调用自己的begin()函数,开启“记录”功能,然后调用笔刷->visit()把自己”画“在这张画布上,最后 CCRenderTexture调用end()结束记录,那就OK了。

    这里我想CCRenderTexture是通过把笔刷的纹理叠加到自己的纹理(Texture)里,而不是不断创建新纹理,所以消耗比较低,即使画得很频繁,帧数也能保持稳定,是个很赞的类。

    CCRenderTexture由于只要begin()开启“记录”功能后,任何之后的CCNode*对象只要调用了visit(),就能将自己“画”在其身上。所以,一般游戏的截屏功能,完全可以使用CCRenderTexture的来实现,具体可以看tests里例子,cocos2d-x已经提供了相关例子,看看源代码就能搞明白的。(注意不要Copy源代码,源代码中将其addChild时设置Zorder为-1,这将置其于所有物体的底下,假如父节点还有其它孩子,将可能看不到效果)

 

 

CCRenderTexture * create (int w, int h)初始化,参数初始化画布的大小,画布坐标系用的是GL坐标系,左下顶点为(0,0)

笔刷,设置好位置,visit()时,其位置是相对于画布的(即相当于笔刷的父节点是画布)。

例如设置笔刷的位置为(400,500),它的位置是相对于画布的左下顶点(0,0)横移400,上移500.

 

CCRenderTexture还提供了一个清理画布渲染的方法

clear (float r, float g, float b, float a)清理画布并设置画布的颜色和透明值

m_pTarget->clean(0,0,0,0)将清理画布,并设其为完全透明的

 

 

CCLabelAtlas就可以从png图中读取文字。

CCLabelAtlas* diceCount=CCLabelAtlas::labelWithString("1:", "nums_font.png", 14, 21, '0');

第一个参数:显示的内容:1x,你也许会奇怪为什么是1x,因为使用的png图必须是连续的,因为程序内部是议连续的scall码识别的。9的后一位的”:“,所以先实现x就得用”:“代替。

第二个参数:图片的名字

第三个参数:每一个数字的宽

第四个参数:每一个数字的高

每五个数字:开始字符

其工作原理个人认为是根据ACSII工作,给出第一个字符,程序自动得到其ASCII码,然后再依次得到需要显示的字符串中每个字符的ASCII码并计算其位置,所以字体图片中的字符必须按ACSII码排列,不然得不到想要的字符串.在ASCII中9后面就是:,所以要显示X就要写

 

 

不能在新开的线程中,创建texture,texture必须在主线程创建.通俗点,就是所有的opengl api都必须在主线程中调用;其它的操作,比如文件,内存,plist等,可以在新线程中做。这个不是cocos2d不支持,是opengl的标准,不管你是在android,还是windows上使用opengl,都是这个原理

 

栈空间和堆空间

栈空间存储变量,又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈

堆空间则存储实例,一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是他与数据结构的堆是两回事,分配方式倒是类似于数据结构的链表


cocos2d-x CCListView 在后期版本中改为CCTableview
 
TinyXML的使用中,插入新的数据后,要记得saveFile(保存文件)不然其操作都是无效的
在TinyXML中,除了Document是在栈中创建的,其它节点都是new出来,在堆中创建的,因为Document是在栈中创建的,退出方法时,会自己调用其析构函数,而在Document的析构函数中,会对其下的所有新建子节点进行释放Delete操作.所以我们会发现在TinyXML中出现许多new,却没有对应的Delete出现,就是因为这个原因
 
Lua随机数的第一个随机数总是固定,所以先消耗掉它
 

Windows 已在 最大数及其个数.exe 中触发一个断点。其原因可能是堆被损坏,这说明 最大数及其个数.exe 中或它所加载的任何 DLL 中有 Bug。原因也可能是用户在 最大数及其个数.exe 具有焦点时按下了 F12。输出窗口可能提供了更多诊断信息。

new() new[]的区别:new()只申请一个对象大小的内存并初始化,new[n]是申请n*对象大小内存
 
CCEditBox只可以在IOS和android上使用,因为源码中它会调用android和IOS中的原生输入控件还执行输入,而在Win32中是没有的,所以在Win32中会编绎错误
posted @ 2013-10-17 17:03  星月相随  阅读(897)  评论(0编辑  收藏  举报