前言
因为我刚开始学习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!
初步测试正常,后续跟进,毕竟刚开始学这个东西..... 本章结束~:)