展会信息港展会大全

cocos2D(七)---- CCScene,cocos2dccscene 常用操作 CCTransitionScene 节点的生命周期
来源:互联网   发布日期:2015-09-28 15:28:38   浏览:1201次  

导读: cocos2D(七)---- CCScene,cocos2dccscene CCScene一般情况是游戏里面的根节点,称之为"场景\",运行游戏时需要通过CCDirector启动第一个场景。当...

cocos2D(七)---- CCScene,cocos2dccscene

CCScene一般情况是游戏里面的根节点,称之为"场景",运行游戏时需要通过CCDirector启动第一个场景。当然,游戏稍微复杂一点的话,可能会包含很多个场景,这就涉及到场景的切换,也是通过CCDirector来完成。CCScene是个抽象的概念,也没有可视化显示的功能,对比CCNode,CCScene基本上没有额外的代码:

[java] view

plaincopy

// CCScene.h

#import "CCNode.h"

@interface CCScene : CCNode

{

}

@end

[java] view

plaincopy

// CCScene,m

#import "CCScene.h"

#import "Support/CGPointExtension.h"

#import "CCDirector.h"

@implementation CCScene

-(id) init

{

if( (self=[super init]) ) {

CGSize s = [[CCDirector sharedDirector] winSize];

// 设置position不受anchorPoint影响

self.isRelativeAnchorPoint = NO;

// 设置anchorPoint

anchorPoint_ = ccp(0.5f, 0.5f);

// 设置CCScene的大小为屏幕大小

[self setContentSize:s];

}

return self;

}

@end

可以发现,对比CCNode,CCScene只是重写了init方法而已,而且也只是做了一个简单的设置

常用操作

1.运行第一个场景

我们一般是在应用程序代理AppDelegate的applicationDidFinishLaunching:方法结尾处运行游戏的第一个场景

[java] view

plaincopy

[[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];

这里的[HelloWorldLayer scene]返回的是一个CCScene对象

2.替换场景

[java] view

plaincopy

[[CCDirector sharedDirector] replaceScene:scene];

这个方法会用新的场景替换旧的场景,cocos2d会释放旧场景的内存,删除旧场景中所有的节点,停止所有动作和消息调度,因此我们不用手动释放旧场景的内存

3.推入和弹出场景

我们知道可以用replaceScene:来运行一个新场景,但是会释放掉旧场景的内存。有时候我们希望在不释放旧场景内存的前提下运行一个新场景,这时候就要用到CCDirector的pushScene:和popScene两个方法了。

1> 使用pushScene:方法推入一个新场景,新场景会层叠在旧场景的上面,但并没有释放旧场景的内存,旧场景继续保留在内存中

[java] view

plaincopy

[[CCDirector sharedDirector] pushScene:scene];

2> 使用popScene方法弹出最上层的场景并释放其内存,使保留在内存中的旧场景重新显示出来

[java] view

plaincopy

[[CCDirector sharedDirector] popScene];

CCTransitionScene

上面介绍了场景的切换,不过都是瞬间完成的,有时候我们想在场景切换的时候有些过渡效果,即以动画的形式切换场景,我们称之为"场景过渡"。要想做场景过渡效果,就必须用CCTransitionScene的子类,CCTransitionScene本身继承了CCScene,它包含了非常多的子类,每个子类都有不同的场景过渡效果,比如CCTransitionFade是淡入淡出效果,CCTransitionPageTurn是翻页效果。

下面演示一个翻页效果:

[java] view

plaincopy

CCTransitionPageTurn *page = [CCTransitionPageTurn transitionWithDuration:0.5 scene:scene];

[[CCDirector sharedDirector] replaceScene:page];

意思是在0.5秒的时间内使用翻页效果从旧场景过渡到scene这个新场景,因为CCTransitionScene是CCScene的子类,所以可以作为replaceScene:的参数。

cocos2d中有非常多的过渡效果可以使用,都是CCTransitionScene的子类,类名一般都是以CCTransition开头的。我就不在这里一一介绍每个子类有什么效果,也没有必要,用到时自己再去查API吧。

注意:CCTransitionScene只能使用在replaceScene:和pushScene:的时候,在popScene弹出场景时是不能用这个过渡效果的

节点的生命周期

说到场景过渡,那就不得不说一下节点的生命周期,即一个节点从开始被添加到屏幕上 到 从屏幕中移除的过程,CCNode提供了相应的生命周期方法:

[java] view

plaincopy

// 节点被添加到屏幕上或者 重新显示到屏幕上 时调用

-(void) onEnter;

// 调用完onEnter后就会调用此方法,如果使用了场景过渡效果,将在场景过渡完毕后才调用此方法

-(void) onEnterTransitionDidFinish;

// 节点从屏幕中移除 或者 暂时离开屏幕 时调用

-(void) onExit;

下面演示在场景切换时,节点生命周期方法的调用顺序

假设有2个图层RedLayer和BlueLayer,它们分别在不同的场景中。点击RedLayer,就推入BlueLayer所在的场景,点击BlueLayer就弹出BlueLayer所在的场景。我们就在场景切换的过程中观察这2个图层的生命周期。

为了区分这2个图层,我让它们继承了CCLayerColor,分别设置不用的背景颜色,RedLayer为红色,BlueLayer为蓝色。

因为RedLayer和BlueLayer都继承CCLayerColor,而且都需要负责创建自己的图层、负责观察生命周期方法的调用,那么我就先抽出一个继承了CCLayerColor的公共父类BaseLayer,在它里面完成一些公共操作,然后让RedLayer和BlueLayer都继承它

BaseLayer的代码

[java] view

plaincopy

// BaseLayer.h

#import "cocos2d.h"

@interface BaseLayer : CCLayerColor

// 用来创建图层所在的场景

+ (CCScene *)scene;

// 图层的背景颜色,交给子类去实现

+ (ccColor4B)bgColor;

@end

[java] view

plaincopy

// BaseLayer.m

#import "BaseLayer.h"

@implementation BaseLayer

#pragma mark - 初始化场景

+ (CCScene *)scene {

// 获取当前类的背景颜色

ccColor4B color = [self bgColor];

// 根据当前类名创建图层

BaseLayer *layer = [[self class] layerWithColor:color];

// 接收触摸输入

layer.isTouchEnabled = YES;

CCScene *scene = [CCScene node];

[scene addChild:layer];

return scene;

}

#pragma mark - 打印生命周期方法

- (void)onEnter { // _cmd 代表着当前的selector

[super onEnter];

// 第一个%@是打印类名,第二个%@是打印方法名

NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));

}

- (void)onEnterTransitionDidFinish {

[super onEnterTransitionDidFinish];

NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));

}

- (void)onExit {

[super onExit];

NSLog(@"%@ --> %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd));

}

@end

RedLayer的代码

[java] view

plaincopy

// RedLayer.h

#import "BaseLayer.h"

@interface RedLayer : BaseLayer

@end

[java] view

plaincopy

// RedLayer.m

#import "RedLayer.h"

#import "BlueLayer.h"

@implementation RedLayer

#pragma mark - 点击红色图层时,跳到蓝色图层所在的场景

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

// 初始化蓝色图层所在的场景

CCScene *scene = [BlueLayer scene];

// 推入场景(暂时没有使用过渡效果)

[[CCDirector sharedDirector] pushScene:scene];

}

#pragma mark - 背景颜色为红色

+ (ccColor4B)bgColor {

return ccc4(255, 0, 0, 255);

}

@end

BlueLayer的代码

[java] view

plaincopy

// BlueLayer.h

#import "BaseLayer.h"

@interface BlueLayer : BaseLayer

@end

[java] view

plaincopy

// BlueLayer.m

#import "BlueLayer.h"

@implementation BlueLayer

#pragma mark - 当点击蓝色图层时,弹出场景

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

[[CCDirector sharedDirector] popScene];

}

#pragma mark - 背景颜色为蓝色

+ (ccColor4B)bgColor {

return ccc4(0, 0, 255, 255);

}

@end

1.在应用程序加载完毕后,即在AppDelegate的applicationDidFinishLaunching:方法中启动第一个场景 ---- 红色图层所在的场景

[java] view

plaincopy

[[CCDirector sharedDirector] runWithScene: [RedLayer scene]];

运行完毕后,效果如下:

生命周期方法打印如下:

[java] view

plaincopy

2013-02-22 15:47:56.473 HelloWorld[2679:c07] RedLayer --> onEnter

2013-02-22 15:47:56.474 HelloWorld[2679:c07] RedLayer --> onEnterTransitionDidFinish

2.点击红色图层,跳到蓝色图层所在的场景

这里根据有没有使用过渡效果,要分2种情况

1> 如果没有使用过渡效果

屏幕直接变为蓝色

生命周期方法打印如下:

[java] view

plaincopy

2013-02-22 15:50:16.381 HelloWorld[2679:c07] RedLayer --> onExit

2013-02-22 15:50:16.382 HelloWorld[2679:c07] BlueLayer --> onEnter

2013-02-22 15:50:16.384 HelloWorld[2679:c07] BlueLayer --> onEnterTransitionDidFinish

可以看出,是先移除红色,再添加蓝色

2> 如果使用了过渡效果

先改变下RedLayer中的代码:

[java] view

plaincopy

#pragma mark - 点击红色图层时,跳到蓝色图层所在的场景

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

// 初始化蓝色图层所在的场景

CCScene *scene = [BlueLayer scene];

// 旧场景一边旋转一边缩小,新场景一边旋转一边方法

CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene];

// 推入场景(暂时没有使用过渡效果)

[[CCDirector sharedDirector] pushScene:page];

}

接下来看一下屏幕效果和打印信息

过渡效果刚开始就会打印:

[java] view

plaincopy

2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter

说明是先初始化并添加BlueLayer

然后中间经历了长达2s的过渡效果:

红色是在一边旋转一边缩小

红色完全消失后,蓝色在一边旋转一边放大

蓝色放大到屏幕大小后

最后会出现以下打印信息:

[java] view

plaincopy

2013-02-22 16:04:28.852 HelloWorld[2910:c07] RedLayer --> onExit

2013-02-22 16:04:28.853 HelloWorld[2910:c07] BlueLayer --> onEnterTransitionDidFinish

移除红色,蓝色过渡完毕

3> 点击蓝色图层,弹出蓝色图层所在的场景,重新显示红色图层所在的场景

打印信息如下:

[java] view

plaincopy

2013-02-22 16:06:47.013 HelloWorld[2910:c07] BlueLayer --> onExit

2013-02-22 16:06:47.014 HelloWorld[2910:c07] RedLayer --> onEnter

2013-02-22 16:06:47.015 HelloWorld[2910:c07] RedLayer --> onEnterTransitionDidFinish

移除蓝色,重新显示红色

原文地址:http://blog.csdn.net/q199109106q/article/details/8602106

感谢作者~!

Cocos2d新手助

如果你是新手的话 1和3问题并不是你需要考虑的1是保证在你使用默认的导演CCDirectorTypeDisplayLink失败时 (如SDK<3.1)设置你的导演类型为CCDirectorTypeDefault3是使用RGBBA8888像素输出这两项都不会影响你的场景切换功能2.CGSize size=[[CCDirector sharedDirector] winSize];这句显而易见,获取你屏幕的大小,你可以点进CGSize查看,它是一个结构体,包含宽度和高度两个元素struct CGSize {CGFloat width;CGFloat height;};如果你认为这个是场景的话,说明你还不了解cocos2d的整体框架,建议先了解CCScene场景、CCLayer层、CCSprite精灵等基本概念再动手,否则只知操作不知其原理终归只是一个码农。

赞助本站

人工智能实验室

相关热词: android开发 应用开发

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港