Cocos2dx 学习笔记(2) 自定义类与脚本导出

前言

  因为我刚开始学习Cocos,走在很多前辈披荆斩棘后的坦途上,我能做的就是剩饭回锅,加上我的思考让它更加细致,易懂.

目标

  1 实现一个CCLayer继承类,结构完整.

  2 将这个类导出给脚本

  3 脚本调用并测试通过

  4 以保持引擎代码不变为原则,尽量少代码,清晰易懂为目标

类设计

  为了后期的学习计划,我直接给出地块层的类原型:  

// -------------------------------------------------------
// 文件名: IsometricLayer.h
// 描  述: 等轴视距地形层
// 日  期: 10/3/2013 
// 作  者: KevinYuen
// 版  权: Copyright (C) 2011 - All Rights Reserved
// 备  注: 
// -------------------------------------------------------

#ifndef _ISOMETRICLAYER_H_
#define _ISOMETRICLAYER_H_

#include "cocos2d.h"
#include "Box2D\Box2D.h"

class CIsometricLayer : public cocos2d::CCLayer	
{
public:

	// 析构
	~CIsometricLayer();

	// 初始化
	virtual bool init();

	// 进入(所属场景被设置为当前运行场景时调用)
	virtual void onEnter();

	// 销毁(所属场景被从当前运行场景取下时调用)
	virtual void onExit();

	// 加载地形
	bool loadTileMap( const char * path );

	// 卸载地形
	bool unloadTileMap();

	// 静态create方法实现
	CREATE_FUNC( CIsometricLayer );
};

#endif

// -------------------------------------------------------
// 文件名: IsometricLayer.cpp
// 描  述: 
// 日  期: 10/3/2013 
// 作  者: KevinYuen
// 版  权: Copyright (C) 2011 - All Rights Reserved
// 备  注: 
// -------------------------------------------------------

#include "IsometricLayer.h"

using namespace cocos2d;

// 析构
CIsometricLayer::~CIsometricLayer()
{

}

// 初始化
bool CIsometricLayer::init()
{
	bool ret = CCLayer::init();
	if( !ret ) return false;

	// 代码添加预留

	return true;
}

// 进入(所属场景被设置为当前运行场景时调用)
void CIsometricLayer::onEnter()
{
	CCLayer::onEnter();

	// 代码添加预留
}

// 销毁(所属场景被从当前运行场景取下时调用)
void CIsometricLayer::onExit()
{
	// 代码添加预留

	CCLayer::onExit();
}

// 加载地形
bool CIsometricLayer::loadTileMap( const char * path )
{
	CCLOG( "[CIsometricLayer] Prepare load tilemap from: %s.", path );
	return true;
}

// 卸载地形
bool CIsometricLayer::unloadTileMap()
{
	CCLOG( "[CIsometricLayer] Prepare unload tilemap." );
	return true;
}

 脚本导出设计

  网上说到的方法大概有两种,一种直接修改CPP,太麻烦,娱乐可以,实用不行!另一种可行,实用tolua++,我要说的就是后面这种方法,不过更加详细,一次到位.

  一. 在自己的工程目录建立一个文件夹,专门存放要导出的自定义类脚本:

    

    像这样,将引擎tolua++目录的工具拷贝过来,下面解释这几个文件:

      CustomScript.cpp: 生成的用户自定义脚本导出文件

      CusomScript.pkg: 主文件,编译就用它

      IsometricLayer.pkg: 自定义类的导出定义    

// CustomScript.pkg内容
$#include "LuaCocos2d.h"

$pfile "IsometricLayer.pkg"

// IsometricLayer.pkg内容

$#include "../Scene/IsometricLayer.h"

class CIsometricLayer : public CCLayer	
{
	// 加载地形
	bool loadTileMap( const char * path );

	// 卸载地形
	bool unloadTileMap();

	// 静态create方法实现
	static CIsometricLayer* create();
};

   二. 生成CPP

// 命令行记录

// 切到tolua++所在目录
G:\>cd G:\MyProjects\CocosProject\CocosGame\Classes\GenerateScript
// 生成
G:\MyProjects\CocosProject\CocosGame\Classes\GenerateScript>tolua++.exe -tCocos2
d -o CustomScript.cpp CustomScript.pkg
// 结束
G:\MyProjects\CocosProject\CocosGame\Classes\GenerateScript>

   三.将CPP直接拉入工程,保持位置不变,编译(如果不通过,看看是不是包含路径找不到)

  四. 为了保证代码简洁,我新建了一个CPP用于脚本导出,并没有合并到那个2M大的文件,太吓人了!所以还需要做一些小的修改.

bool CCLuaEngine::init(void)
{
 ...
        // 加一行,因为CCLuaEgine是属于我们工程的,和引擎关系不大,做些改动是必要的   
	tolua_CustomScript_open(m_state);
 ...   
}

//LuaCocos2d.h
// 增加一行自定义脚本导出
TOLUA_API int  tolua_CustomScript_open (lua_State* tolua_S);

   按照这个顺序,我本地测试已经编译通过了.

脚本测试

  下面编写一小段脚本测试一下是否真的导出了:

......
	-- 创建场景将农场层和界面层依次加入场景
    local sceneGame = CCScene:create()
    sceneGame:addChild(createLayerFarm())
    sceneGame:addChild(createLayerMenu())

	-- 测试一下IsometricLayer的导出情况
	local IsoLayer = CIsometricLayer:create();
	local LoadSuc = IsoLayer:loadTileMap( "Test.tmx" );
	if LoadSuc then
		sceneGame:addChild( IsoLayer );
		cclog( "CIsometricLayer is OK!" );
	end

	-- 设定为当前场景并执行
    CCDirector:sharedDirector():runWithScene(sceneGame)

 输出结果:

[CIsometricLayer] Prepare load tilemap from: Test.tmx.
CIsometricLayer is OK!

 初步测试正常,后续跟进,毕竟刚开始学这个东西..... 本章结束~:)

原文地址:https://www.cnblogs.com/KevinYuen/p/2953240.html