cocos2d和cocos2d-x!
制作plist工具:CocosBuilder
图片位置工具:Zwoptex
1.[shelf insertObject:book atIndex:2]
方括号语法不应该读作“调用 shelf 对象的 insertObject 方法”,而应该是“向 shelf 对象发送一个 insertObject 消息”。这是Objective-C 的实现方式。你可以向任何对象发送任何消息。如果目标对象不能处理这个消息,它就会将消息忽略(这会引发一个异常,但不会终止程序)。如果接收到一个消息,目标对象能够处理,那么,目标对象就会调用相应的方法。
2.实例方法以减号 – 开头,而 static 方法以 + 开头。以 – 开头的是实例 方法(多数情况下都应该是实例方法);以 + 开头的是类方法(相当于 C++ 里面的static 函数)。Objective-C的方法都是 public 的;
3.Objective-C 的类声明关键字是 @interface,而不是 @class。@class 关键字只用于前向声明。
4.指向成员函数的指针被称为选择器 selector。它的类型是 SEL,值通过 @selector 获得。typedef struct objc_selector *SEL;
5.参数的类型要在小括号中,参数之间使用冒号 : 分隔。Objective-C 中,类声明的末尾不需要使用分号 ;
6.Objective-C可以在 @implementation 块中实现一些方法,而不在 @interface 中声明.Objective-C 中的继承只能是 public 的,不可以是 private 和 protected 继承。
7.NS 前缀:我们前面看到的类 NSObject,NSString 都有一个前缀 NS。这是 Cocoa 框架的前缀(Cocoa 开发公司是 NeXTStep)。
8.在 C++ 中,还有一些可以作为函数原型的修饰符,但在 Objective-C 中,这都是不允许的。以下是这个的列表:
· co n st:方法不能使用 co n s t 修饰。既然没有了 co n st,也就不存在 mutable 了;
· static:用于区别实例方法和类方法的是原型前面的 – 和 +;
· virtual:Objective-C 中所有方法都是 virtual 的,因此没有必要使用这个修饰符。纯虚方法则是声明为一个典型的协议 protocol;
· friend:Objective-C 里面没有 friend 这个概念;
· throw:在 C++ 中,可以指定函数会抛除哪些异常,但是 Objective-C 不能这么做。
9.@protocol 协议名 (可能是代表纯虚)
10.注意,在 Objective-C 中,id 类似于 void* . (id) 就是对象的“一般”类型
11.self 是每个方法的一个隐藏参数,指向当前对象。(类似与 c++ 的this指针) . super 指父对象
12.// 调用父类的初始化方法
if (!(self = [super init])) // 如果父类是 NSObject,必须进行 init 操作
return nil; // 如果父类 init 失败,返回 nil
// 父类调用成功,进行自己的初始化操作
析构函数
-(void) dealloc;
13. Foo* foo3 = [[Foo alloc] init];
==>C++写法 Foo* foo = new Foo;
14.
obiective-c:
+(id) itemFromString: (NSString*) value
{
return [[[self alloc] initFromString: value target:nil selector:nil] autorelease];
}
c++:
CCMenuItemFont * CCMenuItemFont::itemFromString(c o n st char *value)
{
CCMenuItemFont *pRet = new CCMenuItemFont();
pRet->initFromString(value, NULL, NULL);
pRet->autorelease();
return pRet;
}
15.
obiective-c:
if((self=[super initWithLabel:label target:rec selector:cb]) )
C++:
if (CCMenuItemLabel::initWithLabel(label, target, selector))
16.
obiective-c:
if ((self=[super init]))
C++:
调用父类的初始化函数init()
obiective-c:
HelloWorldLayer *layer=(HelloWorldLayer*)[[self parent] parent]; //
C++:
HelloWorld *layer = (HelloWorld *)this->getParent()->getParent();
17.
obiective-c:
NSString *fileName=[NSString stringWithFormat:@"s-%@-r-1.png",typeName]; //??
C++:
NSString *fileName = NSString::stringWithFormat("s-%s-r-1.png", typeName); //OC里的 @ 转成 s
18.ISO C++ forbids declaration of 错误需要加一个类的前向声明
例如:
CCRect *collideBox; 报这个错可以加cocos2d::写成 cocos2d::CCRect *collideBox;
19.for循环遍历方法比较普遍,但是效率不好,而且安全性不高。Objective-C 提供了一种快速枚举遍历方法,推荐大家都使用这种方法来遍历。
for(NSObject *object in array) : 遍历array这个数组,每一次循环将数组中的元素赋值给 *object ,实现循环遍历。
例子:数组
for (cocos2d::CCSprite *sp in backgroundSprites) //#include "CityLayer.h"
cocos2d::CCArray *backgroundSprites; //数组指针
backgroundSprites = cocos2d::CCArray::array(); //初始化 申请一个内存
backgroundSprites->retain(); //建立数组指针要写retain() 计数器+1
cocos2d::CCSprite *childSp = cocos2d::CCSprite::spriteWithSpriteFrameName(format("world_%i_%i_%i", layerTheme, type, j));
backgroundSprites->addObject(childSp); //向数组里添加一个CCSprite 的指针
for (int i = 0; i < backgroundSprites->count(); i++) //for (cocos2d::CCSprite *sp in backgroundSprites)
{
sp = (cocos2d::CCSprite *)backgroundSprites->objectAtIndex(i);//->objectAtIndex(i)
if (sp->getPosition().x + sp->getContentSize().width + this->getPosition().x < 0)
{
sp->setPosition(ccp(lastSprite->getPosition().x + lastSprite->getContentSize().width, sp->getPosition().y));
lastSprite = sp;
}
}
20.
self schedule:@selector(method:) interval:0.1];
-(void)method:(id)sender
{
[self unschedule:_cmd];
}
以上代码,本来每隔0.1秒后自动调用method,但是[self unschedule:_cmd];停止了该定时器,
结果是只调用了method一次,这样理解的话_cmd应该指的就是包含了代码[self unschedule:_cmd]
的函数method
21.函数指针 selector 选择器
obiective-c:
CCMenuItemFont *reset=[CCMenuItemFont itemFromString:@"reset" target:self selector:@selector(reSetPos)];//oc
C++:
CCMenuItemFont *reset = CCMenuItemFont::itemFromString("reset", this, menu_selector(HelloWorld::reSetPos));
//selector_protocol.h
#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)
22.
obiective-c:
HelloWorldLayer *layer=(HelloWorldLayer*)[[self parent] parent]; //oc 调用父类的父类
C++:
HelloWorld *layer = (HelloWorld *)this->getParent()->getParent();
23.
obiective-c:
CCTexture2D *texture=[[CCTexture2D alloc]initWithImage:[UIImage imageNamed:@"ft.png"]];
[actor setTexture:texture];
C++:
CCTextureCache *a;
CCTexture2D *texture = a->sharedTextureCache()->addImage("ft.png"); //单例
actor->setTexture(texture);
24.
C++
loadingLayer->setIsVisible(false);
OC:
loadingLayer.visible = NO;
25.property方法
.h中
@property(nonatomic,assign)CityLayerTheme nowWorldTheme;
.m中
@synthesize nowWorldTheme;
c++中两种方法:
1.)
virtual void setNowWorldTheme(CityLayerTheme set);
virtual CityLayerTheme getNowWorldTheme();
void GameLayer::setNowWorldTheme(CityLayerTheme set)
{
nowWorldTheme = set;
}
CityLayerTheme GameLayer::getNowWorldTheme()
{
return nowWorldTheme;
}
2.)
CC_SYNTHESIZE(CityLayerTheme*, nowWorldTheme, NowWorldTheme);
#include "CCPlatformMacros.h"
#define CC_SYNTHESIZE(varType, varName, funName)\
protected: varType varName;\
public: inline varType get##funName(void) c o n st { return varName; }\
public: inline void set##funName(varType var){ varName = var; }
26。
//获取系统毫秒
long GameTimeLayer::millisecondNow()
{
struct cc_timeval now;
CCTime::gettimeofdayCocos2d(&now, NULL);
return (now.tv_sec * 1000 + now.tv_usec / 1000);
}
27.浅谈iOS5.1中使用cocos2d-x出现的闪退及闪屏问题
在 void CCDirector::setGLDefaultValues(void)函数里加入
CCDirector::sharedDirector()->setProjection(kCCDirectorProjection2D);
28.ARC 自动计数要关掉 在targets->building settings里 搜索count
错误收集:
1
no matching function for call to `xushu::set(xushu)'
就是说编译器没有找到签名为 xushu::set(xushu)的函数。要么是函数写错了,要么是调用的时候写错了。
2
cannot call member function 'char* CCAnimation1::format(char*, ...)' without object
将函数声明为static
3
警告:
control reaches end of non-void function
到了函数结尾还没有返回值 需要有返回值
4
Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang++ failed with exit code 1
5
duplicate symbol Level::loadData() in /Users/anyanyone/Library/Developer/Xcode/DerivedData/NewBulkNinja-gyytdvkxivkrqkbuxekucuokhbum/Build/Intermediates/NewBulkNinja.build/Debug-iphonesimulator/NewBulkNinja.build/Objects-normal/i386/LevelTime.o and /Users/anyanyone/Library/Developer/Xcode/DerivedData/NewBulkNinja-gyytdvkxivkrqkbuxekucuokhbum/Build/Intermediates/NewBulkNinja.build/Debug-iphonesimulator/NewBulkNinja.build/Objects-normal/i386/Level.o for architecture i386
Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang++ failed with exit code 1
6.
SIGABRT 一般是过度release 或者 发送 unrecogized selector (调用了不存在的方法)导致
EXC_BAD_ACCESS 是访问已被释放的内存导致
7.
fatal error: file '/Applications/Xcode5-DP.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIDynamicAnimator.h' has been modified since the precompiled header '/Users/sumomochuufuku/Library/Developer/Xcode/DerivedData/ModuleCache/2NEVAP7X943D2/UIKit.pcm' was built
note: after modifying system headers, please delete the module cache at '/Users/sumomochuufuku/Library/Developer/Xcode/DerivedData/ModuleCache/2NEVAP7X943D2'
1 error generated.
解决办法:前往 '/Users/sumomochuufuku/Library/Developer/Xcode/DerivedData/ModuleCache/2NEVAP7X943D2 这个文件夹,删除其文件夹中的内容,然后运行app,没问题了,注意不是删除 2NEVAP7X943D2 文件夹,而是其中的内容。然后再 clean下项目就可以了(product -> clean)
注意:
1)、 sumomochuufuku 是我的用户名,你要改成你自己的。
2)、NEVAP7X943D2 文件夹应该是对应应用的,所以会随着app的不同而改变,要理解并灵活使用。
在练习时,有这么段代码:
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor blueColor].CGColor;
sublayer.shadowOffset = CGSizeMake(0, 3);
sublayer.shadowRadius = 5.0;
sublayer.shadowColor = [UIColor blackColor].CGColor;
sublayer.shadowOpacity = 0.8;
sublayer.frame = CGRectMake(30, 30, 128, 192);
[self.view.layer addSublayer:sublayer];
由于被书上的内存泄露吓唬住了,所以又在最后追加了[sublayer release];来释放内存而在程序调试运行退出时碰到了Program received signal: “EXC_BAD_ACCESS" 错误。经网络搜索搞清楚了这个错误产生的几个原因:
1、访问受保护或者不存在的内存空间,导致返回了一个错误的指针;
2、访问未进行内存分配或初始化的内存空间;
3、在对象被释放后仍然采用原来的指针进行访问;
4、采用了[object release]释放对象,但其实对象并未采用 alloc/copy/retain 等形式进行内存分配;(这是我此次错误的原因)
5、其他不合法的内存访问方式;
总之,对于常见的EXEC_BAD_ACCESS,EXC_BAD_INSTRUCTION,错误,一般都是因为访问已经被release的对象造成的。尤其是在一个线程中访问另外一个线程的autorelease库中的对象,尤其要注意此类问题。
成员函数被重载的特征
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
重写(也就是覆盖 或者 多态)是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
覆盖就是看不见,隐藏就是通过类名::函数名可以访问到。如果基类被重写的函数是虚函数的话就是覆盖,否则就是隐藏。