cocos2D(七)---- CCScene
CCScene普通情况是游戏里面的根节点。称之为"场景",执行游戏时须要通过CCDirector启动第一个场景。
当然,游戏略微复杂一点的话。可能会包括非常多个场景,这就涉及到场景的切换,也是通过CCDirector来完毕。
CCScene是个抽象的概念。也没有可视化显示的功能。对照CCNode。CCScene基本上没有额外的代码:
- // CCScene.h
- #import "CCNode.h"
- @interface CCScene : CCNode
- {
- }
- @end
- // 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:方法结尾处执行游戏的第一个场景
- [[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];
这里的[HelloWorldLayer scene]返回的是一个CCScene对象
2.替换场景
- [[CCDirector sharedDirector] replaceScene:scene];
这种方法会用新的场景替换旧的场景,cocos2d会释放旧场景的内存,删除旧场景中全部的节点。停止全部动作和消息调度。因此我们不用手动释放旧场景的内存
3.推入和弹出场景
我们知道能够用replaceScene:来执行一个新场景,可是会释放掉旧场景的内存。有时候我们希望在不释放旧场景内存的前提下执行一个新场景,这时候就要用到CCDirector的pushScene:和popScene两个方法了。
1> 使用pushScene:方法推入一个新场景。新场景会层叠在旧场景的上面,但并没有释放旧场景的内存,旧场景继续保留在内存中
- [[CCDirector sharedDirector] pushScene:scene];
2> 使用popScene方法弹出最上层的场景并释放其内存。使保留在内存中的旧场景又一次显示出来
- [[CCDirector sharedDirector] popScene];
CCTransitionScene
上面介绍了场景的切换。只是都是瞬间完毕的,有时候我们想在场景切换的时候有些过渡效果,即以动画的形式切换场景,我们称之为"场景过渡"。要想做场景过渡效果,就必须用CCTransitionScene的子类,CCTransitionScene本身继承了CCScene,它包括了许多的子类。每一个子类都有不同的场景过渡效果,比方CCTransitionFade是淡入淡出效果。CCTransitionPageTurn是翻页效果。
以下演示一个翻页效果:
- 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提供了对应的生命周期方法:
- // 节点被加入到屏幕上 或者 又一次显示到屏幕上 时调用
- -(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的代码
- // BaseLayer.h
- #import "cocos2d.h"
- @interface BaseLayer : CCLayerColor
- // 用来创建图层所在的场景
- + (CCScene *)scene;
- // 图层的背景颜色。交给子类去实现
- + (ccColor4B)bgColor;
- @end
- // 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的代码
- // RedLayer.h
- #import "BaseLayer.h"
- @interface RedLayer : BaseLayer
- @end
- // 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的代码
- // BlueLayer.h
- #import "BaseLayer.h"
- @interface BlueLayer : BaseLayer
- @end
- // 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:方法中启动第一个场景 ---- 红色图层所在的场景
- [[CCDirector sharedDirector] runWithScene: [RedLayer scene]];
执行完成后,效果例如以下:
生命周期方法打印例如以下:
- 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> 假设没有使用过渡效果
屏幕直接变为蓝色
生命周期方法打印例如以下:
- 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中的代码:
- #pragma mark - 点击红色图层时。跳到蓝色图层所在的场景
- - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- // 初始化蓝色图层所在的场景
- CCScene *scene = [BlueLayer scene];
- // 旧场景一边旋转一边缩小,新场景一边旋转一边方法
- CCTransitionRotoZoom *page = [CCTransitionRotoZoom transitionWithDuration:2 scene:scene];
- // 推入场景(临时没有使用过渡效果)
- [[CCDirector sharedDirector] pushScene:page];
- }
接下来看一下屏幕效果和信息打印
过渡效果刚開始就会打印:
- 2013-02-22 15:59:38.420 HelloWorld[2862:c07] BlueLayer --> onEnter
说明是先初始化并添加BlueLayer
然后中间经历了长达2s的过渡效果:
红色是在一边旋转一边缩小
红色全然消失后。蓝色在一边旋转一边放大
蓝色放大到屏幕大小后
最后会出现下面信息打印:
- 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> 点击蓝色图层。弹出蓝色图层所在的场景,又一次显示红色图层所在的场景
信息打印例如以下:
- 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(七)---- CCScene的更多相关文章
- Cocos2d-android (01) 创建一个简单的cocos2d应用程序
下载Cocos2d-android的源代码:cocos2d-android-1 git@github.com:ZhouWeikuan/cocos2d.git 将项目导入到eclipse中.运行实例: ...
- 基于cocos2d开发的android小游戏——採花仙
/*cocos 2d 已经成为了如今移动端游戏开发的强有力的工具,眼下主流游戏中多採用cocos 2d游戏引擎. 我也尝试了一下该引擎.我是用的是cocos2d-android,以后要移植到Cocos ...
- CCScrollView
#ifndef TestCCScrollView_testScene_h #define TestCCScrollView_testScene_h #include "cocos2d.h&q ...
- cocos2d_android 第一个游戏
依据上一篇文章.创建好cocos2d--android的开发环境 先上效果图 实现该效果的代码: package com.cn.firstgame; import org.cocos2d.layers ...
- 第四十天 阿乐在其中—Android小游戏的飞机(四)加入敌人
8月9日,晴. "江城如画里,山晓望晴空. 雨水夹明镜.双桥落彩虹. 人烟寒橘柚,秋色老梧桐." 上篇已经让飞机载入子弹和音效及背景音乐,本篇主要加入敌机. 本篇要用到的几个函数解 ...
- 七、CCScene
CCScene一般情况是游戏里面的根节点,称之为"场景",运行游戏时需要通过CCDirector启动第一个场景.当然,游戏稍微复杂一点的话,可能会包含很多个场景,这就涉及到场景的切 ...
- Touch Handling in Cocos2D 3.x(七)
在touchMoved方法中寻找触摸在父节点(CCScene)中的位置并且移动CCDragSprite到其父节点的相应位置中去. 在我们在动作中观赏拖放机制之前,我们需要使用这个新实现的类.打开Mai ...
- 【Cocos2d入门教程七】三分钟看懂Cocos2d坐标系
无论是搞2d还是3d开发,最需要搞清楚的就是坐标系,这部分混乱的话就没啥搞头了.所以玩cocos2d,一上来就需要先把各种与坐标有关的东西搞清楚. 1.OpenGL坐标系 Cocos2d-x使用的是O ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(七):弹出地鼠
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
随机推荐
- Angular JS (2)
通过Angular JS的官方教学文档,了解 routeProvider 的用法, angular.module('aaa').config(['$locationProvider','$routeP ...
- Android Camera 3D效果
一.概念 在Android中要想实现3D效果,第一个想到的应该就是OpenGL ES,因为在很多基础教材中几乎都提到了它.但是其使用起来还是稍微麻烦一些,而且它也主要用在游戏方面,那在应用方面有没有更 ...
- MERGE INTO USING用法
MERGE INTO [your table-name] [rename your table here] USING ( [write your query here] )[rename your ...
- golang协程——通道channel阻塞
新的一年开始了,不管今天以前发生了什么,向前看,就够了. 说到channel,就一定要说一说线程了.任何实际项目,无论大小,并发是必然存在的.并发的存在,就涉及到线程通信.在当下的开发语言中,线程通讯 ...
- HDU多校Round 6
Solved:2 rank:452 I. Werewolf 没有铁人 找铁狼 如果一个环中只有一条狼人边那个人就是铁狼 说铁狼是好人的人也是铁狼 #include <bits/stdc++.h& ...
- telnet mysql3306端口失败
在linux上telnet远程mysql端口失败,经过上网查找后,找到多种方法. (1)我在本地的Navicat上新增了一个用户,主机名是linux的ip,也可以是 %(百分号代表这个用户可以在任何地 ...
- 话说Form标签的target属性-----无刷新表单提交
国庆前(2013)无聊,就在铁道部的12306上“逛”了下下. PS:原来之所以叫12306,是因为其客服号码是12306,好吧,我很无知…… 首先是被“逛”的页面:票价查询. 之所以去逛,是因为一直 ...
- UVA - 247 Calling Circles(Floyd求传递闭包)
题目: 思路: 利用Floyd求传递闭包(mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);),当mp[i][j]=1&&mp[j][ ...
- Go:字符串操作
Package strings:https://golang.google.cn/pkg/strings/ package main import ( "fmt" "st ...
- const int * 和 int * const 傻傻分不清楚
const int * a和int const *a一样,定义时不是必须初始化,指针可以指向其他变量,但是指向的变量的值不能修改. int * const定义时必须初始化,即必须指明指向哪个变量,定义 ...