[Cocos2d-x相关教程来源于红孩儿的游戏编程之路CSDN博客地址:http://blog.csdn.net/honghaier]
红孩儿Cocos2d-X学习园地QQ2群:44208467加群写:Cocos2d-x
红孩儿Cocos2d-X学习园地QQ群:249941957 [暂满]加群写:Cocos2d-x
本章为我的Cocos2d-x教程一书初稿。望各位看官多提建议!
另请转载者注明转载地址及作者。
Cocos2d-x 2.0 TestCpp之场景切换动画深入分析
另:本章所用Cocos2d-x版本为:
cocos2d-2.0-x-2.0.2@ Aug 30 2012
http://cn.cocos2d-x.org/download
大家好,今天我们来学习一下Cocos2d-x中的场景切换效果,我们在玩一些2D的RPG游戏时,常常会遇到场景的转换,这时候当前场景的画面会以百叶窗翻页或者是缩放消失的动画效果切换到新的场景。Cocos2d-x提供了大量可以直接使用的场景切换效果,我们本节将深入分析一下这些效果的实现原理。
我们知道,Cocos2d-x提供了大量的精灵动画效果,红孩儿用了“三板斧”才将这些精灵动画效果讲解完,之后又讲解了进度动画,变速动画,网格动画,这些知识对于本章的理解非常重要,希望同学们先好好理解之前的内容,如果您已经理解了这些知识,那我们现在就开始学习场景切换吧!
首先,我们来概述一下切景切换的核心原理:
场景的切换,是将当前正在运行的场景运行一个动画序列,这个动画序列一般由两部分构成,第一部分为一个精灵动画或者进度动画,第二部分为一个回调函数,场景在切换过程中,本身会进行精灵动画或进度动画的过程,比如移动或缩放动画造成场景的移出,在动画结束后,执行回调函数将原场景隐藏释放,新场景设置为显示。
为了进一步的把这个原理说明给大家,咱们来进行源码的分析。在Cocos2d-x 2.0中,提供了大量封装好的场景类来实现相应的切换动画。我们打开CCTransition.h来看一下。
首先, Cocos2d-x定义了一个用于场景切换的基类CCTransitionScene,这个类是由CCScene派生的,它本质上只是一个具有场景属性的控制器,控制在进行场景切换时的新老场景的切换处理。
class CC_DLL CCTransitionScene : public CCScene { protected: //要切入的新场景 CCScene * m_pInScene; //要切出的旧场景 CCScene * m_pOutScene; //切换动画效果的时长 float m_fDuration; //是否对场景进行渲染排序,是否保证新场景在最上面。 bool m_bIsInSceneOnTop; //在切换完成后是否清空旧场景。 bool m_bIsSendCleanupToScene; public: //构造 CCTransitionScene(); //析构 virtual ~CCTransitionScene(); //重载场景的绘制函数,修改其绘制内容。 virtual void draw(); //重载场景在被载入时调用的函数,做一些初始化的操作。 virtual void onEnter(); //重载场景在被卸载时调用的函数,做一些清理的操作。 virtual void onExit(); //重载场景在被释放时调用的函数,做一些释放的操作。 virtual void cleanup(); //静态函数,创建一个场景切换动画,这里的参数一为动画的时长,参数二为要切换到的新场景,其内部调用create来实现。 CC_DEPRECATED_ATTRIBUTE static CCTransitionScene * transitionWithDuration(float t, CCScene *scene); //同上 static CCTransitionScene * create(float t, CCScene *scene); //初始化场景切换动画。 virtual bool initWithDuration(float t,CCScene* scene); //在场景切换动画结束后调用。 void finish(void); //用来隐藏老场景。 void hideOutShowIn(void); protected: //设置对场景进行排序。 virtual void sceneOrder(); private: //私有函数,用于在场景切换动画完成后,设置新场景为当前游戏场景。 void setNewScene(float dt); };
代码很清楚的交待了场景切换的新场景创建,初始化,排序,以及结束的一些基本函数,其CPP中对应代码我也粘贴在这里进行解释:
//构造函数 CCTransitionScene::CCTransitionScene() { } //析构函数 CCTransitionScene::~CCTransitionScene() { //因为在初始化时开始占用新老场景,所以对其引用计数器做了加一操作,这里自然要减一操作。 m_pInScene->release(); m_pOutScene->release(); } //静态函数,创建一个场景切换动画,这里的参数一为动画的时长,参数二为要切换到的新场景,其内部调用create来实现。 CCTransitionScene * CCTransitionScene::transitionWithDuration(float t, CCScene *scene) { return CCTransitionScene::create(t,scene); } //同上 CCTransitionScene * CCTransitionScene::create(float t, CCScene *scene) { //使用new创建一个用来切换到的新场景。 CCTransitionScene * pScene = new CCTransitionScene(); //如果有效,则对其进行初始化。 if(pScene && pScene->initWithDuration(t,scene)) { //如果初始化成功,交由内存管理器进行管理。 pScene->autorelease(); //返回这个新的场景。 return pScene; } //如果无效或初始化失败,释放后返回NULL。 CC_SAFE_DELETE(pScene); return NULL; } //初始化场景。 bool CCTransitionScene::initWithDuration(float t, CCScene *scene) { //参数有效性判断 CCAssert( scene != NULL, "Argument scene must be non-nil"); //先调用基类的init函数进行基类成员变量初始化。 if (CCScene::init()) { //将动画时长保存到变量m_fDuration中。 m_fDuration = t; //保存要切换到的场景。 m_pInScene = scene; //动画过程会占用新场景,所以对其引用计数器加1 m_pInScene->retain(); //保存当前的场景返回到m_pOutScene中。 m_pOutScene = CCDirector::sharedDirector()->getRunningScene(); if (m_pOutScene == NULL) { //如果当前没有任何场景,就创建一个场景返回到m_pOutScene中并初始化。 m_pOutScene = CCScene::create(); m_pOutScene->init(); } //动画过程会占用当前场景,所以对其引用计数器也加1 m_pOutScene->retain(); //确保切换的两个场景不相同。 CCAssert( m_pInScene != m_pOutScene, "Incoming scene must be different from the outgoing scene" ); // 取得设备管理器。 CCDirector* pDirector = CCDirector::sharedDirector(); //在这个过程中将场景的触屏响应关闭,以免切换动画被中断。 pDirector->getTouchDispatcher()->setDispatchEvents(false); //进行场景的排序。 this->sceneOrder(); //返回成功。 return true; } else { //如果初始化不成功,返回false。 return false; } } //设置场景进行排序。 void CCTransitionScene::sceneOrder() { //设置
public class RtuMain { public static void main(String[] args) { System.out.println(getProjectPath()); System.out.println(getRealPath()); } public static String getProjectPath() throws UnsupportedEncodingException { URL url = RtuMain.class.getProtectionDomain().getCodeSource().getLocation(); String filePath = URLDecoder.decode(url.getPath(), "utf-8"); if (filePath.endsWith(".jar")) { filePath = filePath.substring(0, filePath.lastIndexOf("/") + 1); } File file = new File(filePath); filePath = file.getAbsolutePath(); return filePath; } public static String getRealPath() { String realPath = RtuMain.class.getClassLoader().getResource("").getFile(); File file = new File(realPath); realPath = file.getAbsolutePath(); try { realPath = URLDecoder.decode(realPath, "utf-8"); } catch (Exception e) { e.printStackTrace(); } return realPath; } }
一:oracle文件权限问题
错误表现:在执行ArcSDE命令操作时,不管是sdesetup或是sdemon报如下错误:
[arcsde@RedHat ~]$ sdemon -o start -p sde ------------------------------------------------------- ArcSDE 9.3.1 for Oracle10g Build 1632 Thu Feb 26 12:05:37 2009 ------------------------------------------------------- DB_open_instance()::db_connect (OCI8) error: 1034 init_DB DB_instance_open_as_dba: -51 DBMS error code: 1034 ORA-01034: ORACLE not available ORA-27123: unable to attach to shared memory segment Linux-x86_64 Error: 13: Permission denied Could not start ArcSDE -- Check Network, $SDEHOME disk, DBMS settings and dbinit.sde.
解决方法:在Oracle安装完毕之后,在Oracle操作系统用户下,在$ORACLE_HOME/bin文件夹里面有一个文件oracle的权限非常重要,该权限不能进行任意的修改,默认的oracle文件是6751,或者-rwsr-s--x,有些用户喜欢将所有文件修改为最高权限777或者755,觉得这样修改肯定没有权限问题。所以说,在找不到问题解决方法,不妨看看这个文件的权限是否被修改?
[arcsde@RedHat ~]$ su - oracle Password: [oracle@RedHat ~]$ cd $ORACLE_HOME/bin [oracle@RedHat bin]$ ll oracle -rwxrwxrwx 1 oracle oinstall 112468376 Sep 5 2011 oracle [oracle@RedHat bin]$ chmod 6751 oracle [oracle@RedHat bin]$ ll oracle -rwsr-s--x 1 oracle oinstall 112468376 Sep 5 2011 oracle [oracle@RedHat bin]$ su - arcsde Password: [arcsde@RedHat ~]$ sdemon -o start -p sde ------------------------------------------------------- ArcSDE 9.3.1 for Oracle10g Build 1632 Thu Feb 26 12:05:37 2009 ------------------------------------------------------- ST_Geometry Schema Owner: (SDE) Type Release: 1007 Instance initialized for ((sde)) . . . Connected to instance . . . DBMS Connection established... RDBMS: "Oracle" Instance Name: "esri_sde" IOMGR Process ID (PID): 2026 ArcSDE Instance esri_sde started Sat Jan 5 10:31:14 2013
二:环境变量问题
问题表现:
[arcsde@RedHat bin]$ sdemon -o start -p sde sdemon: error while loading shared libraries: libsde.so: cannot open shared object file: No such file or directory
根据上面可以看出,缺少libsde.so文件,我们可以使用ldd命令来查看是否还缺少其他文件
[arcsde@RedHat bin]$ ldd sdemon libsde.so => not found libsg.so => not found libpe.so => not found libXm.so.3 => /usr/lib64/libXm.so.3 (0x00002b6d57d3c000) libXmu.so.6 => /usr/lib64/libXmu.so.6 (0x0000003241e00000) libXp.so.6 => /usr/lib64/libXp.so.6 (0x000000351ce00000) libXt.so.6 => /usr/lib64/libXt.so.6 (0x0000003253800000) libSM.so.6 => /usr/lib64/libSM.so.6 (0x000000324a200000) libICE.so.6 => /usr/lib64/libICE.so.6 (0x000000324ae00000) libXext.so.6 => /usr/lib64/libXext.so.6 (0x0000003244600000) libX11.so.6 => /usr/lib64/libX11.so.6 (0x0000003243200000) libg2c.so.0 => /usr/lib64/libg2c.so.0 (0x00002b6d581de000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b6d58400000) libdl.so.2 => /lib64/libdl.so.2 (0x0000003241a00000) libstdc++.so.5 => /usr/lib64/libstdc++.so.5 (0x00002b6d5861b000) libm.so.6 => /lib64/libm.so.6 (0x0000003241600000) libc.so.6 => /lib64/libc.so.6 (0x0000003241200000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000324ec00000) libXau.so.6 => /usr/lib64/libXau.so.6 (0x0000003243a00000) libXdmcp.so.6 => /usr/lib64/libXdmcp.so.6 (0x0000003243600000) /lib64/ld-linux-x86-64.so.2 (0x0000003240e00000)
但是这些文件是刚安装的,而且也可以查看到有这些文件
[arcsde@RedHat ~]$ find /home/arcsde -name 'libsde.so' /home/arcsde/sdeexe93/lib/libsde.so
这时候,我们就可以看看是否是环境变量的问题
1:环境变量写错了(少分号,半角全角问题)
2:环境变量是否生效
生效环境变量
a:切换操作系统用户
b: . ./.bash_profile(点空格点斜杠点bash_profile)
可以使用echo来查看
[arcsde@RedHat ~]$ echo $PATH /usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/arcsde/bin:/home/oracle/app/product/10.2.0.4/db_1/bin:/home/arcsde/sdeexe93/bin:/usr/bin:/bin:/usr/local/bin
3:环境变量引用位置问题
PATH=$PATH:$HOME/bin export PATH export ORACLE_HOME=/home/oracle/app/product/10.2.0.4/db_1 export ORACLE_SID=orcl export PATH=$PATH:$ORACLE_HOME/bin:$SDEHOME/bin:/usr/bin:/bin:/usr/local/bin export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$SDEHOME/lib:$PATH/bin:/usr/bin:/bin:/usr/local/bin export SDEHOME=/home/arcsde/sdeexe93如上面就是新手比较常见的错误,在PATH引用$SDEHOME的时候已经无法找到相关路径,因为$SDEHOME应该写在PATH前面,如下:
PATH=$PATH:$HOME/bin export PATH export ORACLE_HOME=/home/oracle/app/product/10.2.0.4/db_1 export ORACLE_SID=orcl export SDEHOME=/home/arcsde/sdeexe93 export PATH=$PATH:$ORACLE_HOME/bin:$SDEHOME/bin:/usr/bin:/bin:/usr/local/bin export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$SDEHOME/lib:$PATH/bin:/usr/bin:/bin:/usr/local/bin
三:数据库sde用户权限问题
在ArcSDE创建Schema或者升级Schema时,都需要相关的权限,如果这些权限不够,会出现如下问题:
[arcsde@RedHat ~]$ sdesetup -o install -d oracle10g -p sde ESRI ArcSDE Server Setup Utility Sat Jan 5 11:25:08 2013 ---------------------------------------------------------------- Install or update ArcSDE, GDB schema objects: Are you sure? (Y/N): y Creating ArcSde schema..... Error: Underlying DBMS error (-51). Error: SDE release install not completed. Check SDEHOME\etc\sde_setup.log for more details. [Sat Jan 5 11:08:38 2013] ERROR installing/upgrading ArcSDE, Error = -25 [Sat Jan 5 11:12:52 2013] Error: Invalid DBA password (-93). [Sat Jan 5 11:12:52 2013] Error: Unable to connect [Sat Jan 5 11:12:52 2013] ERROR installing/upgrading ArcSDE, Error = -93 [Sat Jan 5 11:22:29 2013] DB_open_instance()::db_connect (OCI8) error: 1045 [Sat Jan 5 11:22:29 2013] Error: Underlying DBMS error (-51). [Sat Jan 5 11:22:29 2013] Error: Unable to connect [Sat Jan 5 11:22:29 2013] ORA-01045: user SDE lacks CREATE SESSION privilege; logon d enied [Sat Jan 5 11:22:29 2013] ERROR installing/upgrading ArcSDE, Error = -51一般情况下,权限问题根据错误都比较容易处理,我们需要赋予相关的权限即可,相关安装或者升级的权限如下
grant CREATE SESSION to sde; grant CREATE TABLE to sde; grant CREATE PROCEDURE to sde; grant CREATE SEQUENCE to sde; grant CREATE TRIGGER to sde; grant CREATE TYPE to sde; grant CREATE LIBRARY to sde; grant CREATE PUBLIC SYNONYM to sde; grant CREATE OPERATOR to sde; grant CREATE INDEXTYPE to sde; grant DROP PUBLIC SYNONYM to sde; grant UNLIMITED TABLESPACE to sde; grant CREATE VIEW to sde; prompt * SELECT ANY TABLE is required for compressing the database prompt * This privilege needs to be granted whenever a compress is run. grant SELECT ANY TABLE to sde; prompt * ADMINISTER DATABASE TRIGGER can be revoked after install grant ADMINISTER DATABASE TRIGGER to sde; prompt * * * * * * * * * * * prompt * ArcSDE UPGRADE * prompt * * * * * * * * * * * prompt * If upgrading please remove rem from each grant. prompt * Granting the required privileges to the sde user. REM grant ADMINISTER DATABASE TRIGGER to sde; REM grant SELECT ANY TABLE to sde; REM grant SELECT ANY SEQUENCE to sde; REM grant EXECUTE ANY PROCEDURE to sde; REM grant ANALYZE ANY to sde; REM grant ALTER ANY INDEX to sde; REM grant ALTER ANY TABLE to sde; REM grant CREATE ANY SEQUENCE to sde; REM grant CREATE ANY TRIGGER to sde; REM grant CREATE ANY INDEX to sde; REM grant CREATE ANY PROCEDURE to sde; REM grant DROP ANY INDEX to sde; REM grant DROP ANY SEQUENCE to sde; REM grant DROP ANY TABLE to sde; REM grant DROP ANY VIEW to sde; REM grant DROP ANY PROCEDURE to sde;
四:执行操作提示:Error: libclntsh.so.10.1(libclntsh.so.11.1): cannot open shared object file: No such file or directory
上面的区别就是如果使用oracle10g和11g出错的区别,在执行sdesetup提示
[arcsde@RedHat ~]$ sdesetup -o install -d oracle10g -p sde ESRI ArcSDE Server Setup Utility Sat Jan 5 11:40:59 2013 ---------------------------------------------------------------- Install or update ArcSDE, GDB schema objects: Are you sure? (Y/N): y Creating ArcSde schema..... Error: libclntsh.so.10.1: cannot open shared object file: No such file or directory Error: Server library could not be loaded (-324). Error: SDE release install not completed. Check SDEHOME\etc\sde_setup.log for more details.libclntsh.so.10.1位于oracle的安装目录中,arcsde没有读取权限造成的,需将/home/oracle/app/oracle目录的读取权限开放给oinstall组(arcsde隶属该组)。
解决方法
[root@RedHat lib]# pwd /home/oracle/app/p