游戏的主角啊什么,花花草草都可以看成是一个个Sprites
cocoaChina 上有个更官方的解释这4个概念:http://www.cocoachina.com/gamedev/gameengine/2010/0419/1116.html
我觉得写的很好,理解起来也很明了
好了,理解了以上4个最重要的元素后,我们开始着手编码也运用他们了
我们的第一个helloword就问候完本人顺便问候家里人了
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Create the main window window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; CCGLView *glView = [CCGLView viewWithFrame:[window_ bounds] pixelFormat:kEAGLColorFormatRGB565 //kEAGLColorFormatRGBA8 depthFormat:0 //GL_DEPTH_COMPONENT24_OES preserveBackbuffer:NO sharegroup:nil multiSampling:NO numberOfSamples:0]; director_ = (CCDirectorIOS*) [CCDirector sharedDirector]; director_.wantsFullScreenLayout = YES; [director_ setDisplayStats:YES]; [director_ setAnimationInterval:1.0/60]; [director_ setView:glView]; [director_ setDelegate:self]; [director_ setProjection:kCCDirectorProjection2D]; // [director setProjection:kCCDirectorProjection3D]; if( ! [director_ enableRetinaDisplay:YES] ) CCLOG(@"Retina Display Not supported"); navController_ = [[UINavigationController alloc] initWithRootViewController:director_]; navController_.navigationBarHidden = YES; [window_ addSubview:navController_.view]; [window_ makeKeyAndVisible]; [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888]; CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils]; [sharedFileUtils setEnableFallbackSuffixes:NO]; // Default: NO. No fallback suffixes are going to be used [sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"]; // Default on iPhone RetinaDisplay is "-hd" [sharedFileUtils setiPadSuffix:@"-ipad"]; // Default on iPad is "ipad" [sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"]; // Default on iPad RetinaDisplay is "-ipadhd" [CCTexture2D PVRImagesHavePremultipliedAlpha:YES]; //以上都是模板自动给你生成的,就是配置一些全局参数 //启动一个场景 [director_ runWithScene: [MenuLayer scene]]; return YES; }
以上代码基本就模板自己生成,就是一些相关的设置。这里为了简洁,我把注释都删除了,大家新建后能看到注释。
这也是对Director这个概念最入门的印象,导演么,布置整场戏的道具,演员配置,灯光啊,音响啊什么的。
然后布置完后,第一场景开始 runWithScene。
我这边第一场景假设是菜单选择场景。
@implementation MenuLayer +(CCScene *)scene { CCScene *scene = [CCScene node];//其实就是执行了init,使用自动释放 CCLayer *layer = [MenuLayer node]; [scene addChild:layer]; return scene; } -(void)playNewGame { [[CCDirector sharedDirector] replaceScene:[HelloWorldLayer scene]]; } -(void)test { CCNode *node = [self getChildByTag:100]; NSAssert([node isKindOfClass:[CCMenu class]],@"出错了"); // 使用文字创建一个item CCMenuItemFont *item1 = [CCMenuItemFont itemWithString:@"退出游戏" target:self selector:@selector(playNewGame)]; [node addChild:item1]; [node alignItemsVerticallyWithPadding:10]; } - (id)init { self = [super init]; if (self) { // 使用文字创建一个item CCMenuItemFont *item1 = [CCMenuItemFont itemWithString:@"开始新游戏" target:self selector:@selector(playNewGame)]; //使用精灵创建一个item CCSprite *item2_nor = [CCSprite spriteWithFile:@"icon.png"]; CCSprite *item2_sel = [CCSprite spriteWithFile:@"icon.png"]; CCMenuItemSprite *item2 = [CCMenuItemSprite itemWithNormalSprite:item2_nor selectedSprite:item2_sel]; //创建menu CCMenu *menu = [CCMenu menuWithItems:item1,item2, nil]; menu.tag = 100; CGSize winSize = [[CCDirector sharedDirector] winSize]; menu.position = CGPointMake(winSize.width/2, winSize.height); [self addChild:menu]; [menu alignItemsVerticallyWithPadding:20]; //动作1 id ac = [CCMoveTo actionWithDuration:2 position:CGPointMake(winSize.width/2, winSize.height/2)]; CCRepeat *repe = [CCRepeat actionWithAction:ac times:4]; //动作二 id bc = [CCCallFunc actionWithTarget:self selector:@selector(test)]; CCSequence *seq = [CCSequence actions:repe,bc,nil]; [menu runAction:seq]; } return self; } @end
一个类方法,这段代码我也注释了,+(void)scene中对象以node创建,其实就是一个init,只不过将内存管理交给了管理池,而不是以前我们
认为的,只要init后,必须有个地方手动的去release。cocos2d这么做,其实也是为了方便。
分析下这段代码来看,scene场景这个真是个够抽象的概念。它唯一做的就是实例化后,添加进去表现层。
以后基本编码逻辑操作都是在layer层上完成的。
回过来看下表现层layer,也就是我的menuLayer,在scene方法中我们看到它也node实例化了,跳进源码我们看到node其实就是这样的:
#pragma mark CCNode - Init & cleanup +(id) node { return [[[self alloc] init] autorelease]; }
对于场景和层有了基本了解后,那么我们来看Sprites
在init中,我们往这个menuLayer上添加上一个节点(menu).
代码中很明了的看到,先创建两个按钮节点(一个纯粹是以node表现,一个是以Sprites表现),添加到menu节点,再将这个menu节点添加到最顶层的menuLayer(说白就是一个命名而已,不要理解为感觉有两个menu层~)。
就是这么简单。
好了,以上,我们基本熟悉了这四个概念如何在cocos2d整个项目的一种表现。
其实最好的学习方法不是看或着读,而是自己去写一边。同样你可以做一些简单的改进,比如提供多个场景,实现场景替换replace,push和pop等等。
PS:1.在第一段代码中我们看到模板有了个导航,这是因为模板生成的helloword本身是跳转到系统的gameCenter(还是gameKit~~)。只是这个例子的表现形式。
2.其实以前一直没注意,文件名和文件里面的类名可以不一样(当然在以前写类别时有写过,只是没注意)。
因为我们知道,一个场景是可以包含多个layer,因此,为了更加直观,我们可以有的文件,比如我上面的游戏开始的菜单当做一个个场景。
文件命名为MenuScene,然后里面类名命名为MenuLayer。这样就更符合我们常规的思路。