前言
紧跟上章,这章设计场景对象的创建管理.
在今天的学习过程中,发现好多cocos2dx操作不便的地方,没有我以前接触的框架做的友好,也可能是我还没有完全了解吧.先列出来,知道的大神可以指点一下:
1. 脚本中的泄露好多,如果打开crtdbg,能发现好一堆....
2. 对打包资源的支持不够灵活,接口分离,比如如果我要将脚本打包读取,那么就有很多的接口重新封装,比如require的调用.
3. 关于精灵的静态创建接口....
问题
请教一个问题:
如果我的场景中有一层Tmxtilemap, 我通过getchildBytag获取到它,怎么能够调用它本身的方法,比如:
1).--local mapLayer = scene:getMapLayer(); // 这个是我自己定义的接口,直接导出TmxTileMap*,是可以的
2).local mapLayer = scene:getChildByTag( ESLT_GROUND ); // 这个是不行的,getMapOrientation找不到.
if mapLayer and mapLayer:getMapOrientation() == CCTMXOrientationIso then .....
设计选择
引擎提供了多个精灵的静态创建方法,并提供了一个userData指针来保存对象的逻辑属性,但是这个需要自己管理属性集合,放在C++中实现比较合适,所以我初步考虑实现CSceneObject类,来封装场景精灵对象.
为了直接更直观,便捷的管理CSceneObject,创建ObjectLayer.
代码片段
1. CObjectLayer
// ------------------------------------------------------- // 文件名: ObjectLayer.h // 描 述: 对象层 // 日 期: 12/3/2013 // 作 者: KevinYuen // 版 权: Copyright (C) 2011 - All Rights Reserved // 备 注: // ------------------------------------------------------- #ifndef _OBJECTLAYER_H_ #define _OBJECTLAYER_H_ #include "cocos2d.h" USING_NS_CC; class CSceneObject; class CObjectLayer : public CCLayer { public: ~CObjectLayer(); public: // 添加对象 CSceneObject* addObject( CCSpriteFrame *pSpriteFrame ); // 删除对象 bool delObject( int tag ); // 查找对象 CSceneObject* getObject( int tag ); public: // 实例创建 CREATE_FUNC( CObjectLayer ); private: CObjectLayer(); int m_ObjectTagTracker; // Tag计数器 }; #endif #include "ObjectLayer.h" #include "SceneObject.h" CObjectLayer::CObjectLayer() : m_ObjectTagTracker(1) { } CObjectLayer::~CObjectLayer() { } // 添加对象 // 返回自动产生的一个当前层唯一的tag CSceneObject* CObjectLayer::addObject( CCSpriteFrame *pSpriteFrame ) { // 创建 CSceneObject* pNew = CSceneObject::create(); if( !pNew || !pNew->initWithSpriteFrame( pSpriteFrame ) ) return NULL; // 加入 addChild( pNew, 0, m_ObjectTagTracker++ ); return pNew; } // 删除对象 bool CObjectLayer::delObject( int tag ) { CCNode* pObject = getChildByTag( tag ); if( !pObject ) return false; this->removeChild( pObject ); return true; } // 查找对象 CSceneObject* CObjectLayer::getObject( int tag ) { return dynamic_cast<CSceneObject*>( getChildByTag( tag ) ); }
2. 场景对象
// ------------------------------------------------------- // 文件名: SceneObject.h // 描 述: 场景对象 // 日 期: 12/3/2013 // 作 者: KevinYuen // 版 权: Copyright (C) 2011 - All Rights Reserved // 备 注: // ------------------------------------------------------- #ifndef _SCENEOBJECT_H_ #define _SCENEOBJECT_H_ #include "cocos2d.h" USING_NS_CC; class CSceneObject : public CCSprite { public: virtual ~CSceneObject(); CREATE_FUNC( CSceneObject ); public: // 后期扩展接口 private: // 后期增加属性集合 }; #endif #include "SceneObject.h" CSceneObject::~CSceneObject() { }
3. 脚本使用
-------------------------------------------------------- --文件名: main.lua --描 述: 主脚本 --日 期: 11/3/2013 --作 者: KevinYuen --版 权: Copyright (C) 2011 - All Rights Reserved --备 注: --------------------------------------------------------- -- 跟踪绑定执行函数发生错误的信息并输出 function __G__TRACKBACK__(msg) print("----------------------------------------") print("LUA ERROR: " .. tostring(msg) .. "\n") print(debug.traceback()) print("----------------------------------------") end -- 主函数 local function main() -- 创建主场景 local scene = CMainScene:create(); if not scene then print( "Create main scene failed!" ); return; end -- 加载测试场景 -- 引擎对CCTMXTiledMap有限制,每一层只能有一个瓦块包,也就是一张纹理 if not scene:loadScene( "TilesMap/Isotile_2.tmx" ) then print( "Load tilemap failed!" ); return; end local mapLayer = scene:getMapLayer(); --local mapLayer = scene:getChildByTag( ESLT_GROUND ); if mapLayer and mapLayer:getMapOrientation() == CCTMXOrientationIso then require( "script/control_iso" ); createControl( scene ); end -- 创建一个精灵帧序列 local frameCache = CCSpriteFrameCache:sharedSpriteFrameCache(); frameCache:addSpriteFramesWithFile( "animations/redRobot-hd.plist" ); -- 这里暂时用这个作为Z排序的算法,保证遮挡顺序 local function getZOrder( posY ) local visibleSize = CCDirector:sharedDirector():getVisibleSize() local y = visibleSize.height - posY; return y; end -- 这里如果使用getChildByTag无法转换为CObjectLayer,谁知道为什么,请教一下 :) local objectLayer = scene:getObjectLayer(); if objectLayer then local sframe = frameCache:spriteFrameByName( "01.png" ); local sprite1 = objectLayer:addObject( sframe ); sprite1:setPosition( 400, 300 ); objectLayer:reorderChild( sprite1, getZOrder( 300 ) ); sframe = frameCache:spriteFrameByName( "03.png" ); local sprite2 = objectLayer:addObject( sframe ); sprite2:setPosition( 400, 300 ); objectLayer:reorderChild( sprite2, getZOrder( 300 ) ); sframe = frameCache:spriteFrameByName( "05.png" ); local sprite3 = objectLayer:addObject( sframe ); sprite3:setPosition( 500, 300 ); objectLayer:reorderChild( sprite3, getZOrder( 300 ) ); -- 计时回调,用于精灵的移动 local function tick() local x, y = sprite2:getPosition(); if y > 400 then y = 160 end y = y + 1; sprite2:setPositionY(y) objectLayer:reorderChild( sprite2, getZOrder( y ) ); end -- 加入日程表,间隔为0代表每帧 CCDirector:sharedDirector():getScheduler():scheduleScriptFunc(tick, 0, false) end -- 设定为当前场景并执行 CCDirector:sharedDirector():runWithScene( scene ); end -- 执行脚本函数并捕获错误信息 -- 函数原型: xpcall( 调用函数, 错误捕获函数 ); xpcall(main, __G__TRACKBACK__)