zoukankan      html  css  js  c++  java
  • Cocos2dx 学习笔记(5) 场景对象的创建与排序

    前言

      紧跟上章,这章设计场景对象的创建管理.

      在今天的学习过程中,发现好多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__)
    

     效果

  • 相关阅读:
    CentOS下Docker安装ping命令
    CentenOS7 安装docker
    C++ preprocessor "/lib/cpp" fails sanity
    安装M4报错Please port gnulib freadahead.c to your platform!
    python的范式.linalg.norm,numpy tolist()的用法
    Unable to correct problems, you have held broken packages.
    tar解压时候出现tar: invalid option
    Ubuntu换源
    apt更新显示以下错误消息Err:1 http://ports.ubuntu.com xenial InRelease Temporary failure resolving ‘ports.ubunt
    Ubuntu软件操作的相关命令
  • 原文地址:https://www.cnblogs.com/KevinYuen/p/2955649.html
Copyright © 2011-2022 走看看