本文主要是介绍00003 不思议迷宫.0010.1.1.2:csb解析显示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
00003不思议迷宫.0010.1.1.2:csb解析显示
Mac上调试app有点蛋疼,每次运行都要打包来打包去,慢。我对Xcode不熟,不会修改工程文件让它不打包。我决定,换到Windows下,使用VS。
上次用3.3 rc0未能解析出csb,已发现确实是操作错误(还是环境变量冲突)。这次就用3.3 rc0来。
执行创建:cocos new BSYMG -p com.your_company.BSYMG -l lua -d C:\BSYMG
添加读取png补丁,打开CCImage.cpp:
添加全局函数:
//
// tiewen patched
//
staticconstchar*xorEncryptKey="// Dump Ref object memory leaks if(__refAllocationList.empty()) { log([memory] All Ref objects successfullycleaned up (no leaks detected).); } else { log([memory] WARNING: %d Ref objectsstill active in memory., (int)__refAllocationList.size()); for (const auto&ref : __refAllocationList) { CC_ASSERT(ref); const char* type =typeid(*ref).name(); log([memory] LEAK: Ref object %s still active with referencecount %d., (type ? type : ), ref->getReferenceCount()); }}";
staticvoidxorEncrypt(unsignedchar*v,int length)
{
autoxorEncryptKeyLength = strlen(xorEncryptKey);
for(inti = 0; i < length; ++i)
{
v[i]^= (unsignedchar)xorEncryptKey[i% xorEncryptKeyLength];
}
}
staticintxorEncryptingLength(unsignedchar*v,int length)
{
if(length <= 200)return length;
return200;
}
staticboolisEncryptedPng(unsignedchar*v,int length)
{
return(v[0] != 0x89) || (v[1] !='P') ||(v[2] !='N') || (v[3] !='G');
}
staticunsignedchar*ToPlainPng(unsignedchar*v,int length)
{
if(isEncryptedPng(v, length)) xorEncrypt(v, xorEncryptingLength(v, length));
returnv;
}
staticunsignedchar*ToEncodedPng(unsignedchar*v,int length)
{
xorEncrypt(v, xorEncryptingLength(v, length));
returnv;
}
修Image::isPng:
bool Image::isPng(constunsignedchar* data, ssize_t dataLen)
{
if(dataLen <= 8)
{
returnfalse;
}
staticconstunsignedcharPNG_SIGNATURE[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a,0x0a};
//tiewenpatched begin
staticunsignedchardecryptedData[8];
memcpy(decryptedData, data, 8);
if(isEncryptedPng(decryptedData,8))//isEncrypted
{
xorEncrypt(decryptedData, 8);
returnmemcmp(PNG_SIGNATURE, decryptedData,sizeof(PNG_SIGNATURE))== 0;
}
//tiewenpatched end
returnmemcmp(PNG_SIGNATURE, data,sizeof(PNG_SIGNATURE))== 0;
}
修改Image::initWithPngData:
bool Image::initWithPngData(constunsignedchar* data, ssize_t dataLen)
{
data =ToPlainPng((unsignedchar*)data, dataLen);// tiewen patched
……
}
添加读取luac的补丁,打开Cocos2dxLuaLoader.cpp,修改:
intcocos2dx_lua_loader(lua_State *L)
{
……
if(chunk)
{
//tiewen patched begin
int offset = 0;
if (chunk[offset] == 0xef &&chunk[offset + 1] == 0xbb && chunk[offset + 2] == 0xbf) offset += 3;
if (chunk[offset] == 0x11 &&chunk[offset + 1] == 0x12 && chunk[offset + 2] == 0x13) offset += 3;
LuaStack* stack =LuaEngine::getInstance()->getLuaStack();
//stack->luaLoadBuffer(L,(char*)chunk, (int)chunkSize, chunkName.c_str());
stack->luaLoadBuffer(L,(char*)chunk + offset, (int)chunkSize - offset,chunkName.c_str());
//tiewen patched end
……
}
……
}
同时支持普通的lua文件、解密后的luac文件和修改后拥有BOM头的解密luac文件。
用VS打开frameworks\runtime-src\proj.win32下的工程文件,F5,耐心等待后,默认的农场结界就出来了。
下面要解决《不思议迷宫》的csb显示问题。当然,显示不是问题,问题是显示得要和游戏中一样。为此,希望能够直接使用游戏的luac文件。但游戏的luac文件中可能包含了额外的游戏逻辑,这部分代码在我们的环境下无法运行,需要剔除。
首先要修改掉框架默认的分辨率。
打开src/main.lua,修改:
if nil == glview then
glview =cc.GLViewImpl:createWithRect("HelloLua", cc.rect(0,0,540,960))
director:setOpenGLView(glview)
end
glview:setDesignResolutionSize(540,960, cc.ResolutionPolicy.NO_BORDER)
修改为和iPhone 5等比例的分辨率。
然后去除框架默认的界面,修改为我们自己想要显示的:
local sceneGame = cc.Scene:create()
local node =cc.CSLoader:createNode("layout/dungeon/DungeonMain.csb");
sceneGame:addChild(node)
能显示,但和cocos2dx-cpp中的一样,位置不对且不完整,需要调整。/src/game/ui/form/dungeon/UIDungeonMain.luac中的无疑是最正确的,但我们没办法直接使用,里面有很多不知所谓的代码。慢慢来。为了方便以后切换各个场景,我们也把相关的代码包装到类中。由于我们只捣鼓UI,就不像《不思议迷宫》那样地分那么多目录层级了,全部放到my目录下。建立/src/my/UIDungeonMain.luac,打开编辑,内容如下:
require("game/ui/base/util/Node");
require("game/ui/base/TextStyleM");
--每个关卡由6行5列的格子组成
GRID_ROW_NUM= 6;
GRID_COL_NUM= 5;
TOTAL_GRID_NUM= GRID_ROW_NUM * GRID_COL_NUM;
--格子宽、高
GRID_WIDTH = 128;
GRID_HEIGHT= 118;
--格子的纵向偏移量
GRID_OFFSET_Y= 80;
--格子刷怪的延迟
GRID_REFRESH_MONSTER_DELAY = 0.7
--UIDungeonMain继承自Layer
UIDungeonMain= class("UIDungeonMain", function()
return cc.Layer:create();
end);
functionUIDungeonMain.create(levelData, layer)
return UIDungeonMain.new(levelData, layer);
end
--是否持续自动操作
stillOpt= false;
--迷宫界面创建完毕之后的回调
localalreadyCallback = {};
--技能界面
localmagicScrollUI = nil;
--宝物界面
localequipsUI = nil;
localresize;
--构造函数
functionUIDungeonMain:ctor()
self:setName("UIDungeonMain");
self.node =cc.CSLoader:createNode("layout/dungeon/DungeonMain.csb");
self:addChild(self.node);
self.panel = findChildByName(self.node,"CT1/panel");
self.attackLabel =findChildByName(self.node, "CT2/atk_val");
self.magicLabel =findChildByName(self.node, "CT2/magic_val");
self.hpLabel = findChildByName(self.node,"CT2/hp_val");
self.mpLabel = findChildByName(self.node,"CT2/mp_val");
self.specialImage =findChildByName(self.node, "CT2/specil");
self.gainImage = findChildByName(self.node,"CT2/gain");
self.debuffsImage =findChildByName(self.node, "CT2/debuffs");
-- 状态条
self.statusBarNode =findChildByName(self.node, "CT1/status_bar");
self.statusParentNode =findChildByName(self.node, "CT1/status_bar/parent_node");
local function setStyle(textNode,className)
if className ~= nil then
textNode =tolua.cast(textNode, className);
end
TextStyleM.setTextStyle(textNode,TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
textNode:setFontSize(28);
textNode:setTextColor(TextStyleM.TEXT_COLOR_WHITE);
textNode:getVirtualRenderer():setAdditionalKerning(getLocKerning()-2);
local outlineColor =TextStyleM.TEXT_OUTLINE_COLOR_DARK;
textNode:enableOutline(cc.c4b(outlineColor[1], outlineColor[2],outlineColor[3], 255), 2);
textNode:setScaleX(1.2);
end
setStyle(self.attackLabel,"ccui.Text");
setStyle(self.magicLabel,"ccui.Text");
setStyle(self.hpLabel,"ccui.Text");
setStyle(self.mpLabel,"ccui.Text");
resize(self.node);
-- 初始化顶部菜单
--local topNode =findChildByName(self.node, "TOP");
--self.dungeonTopMenu =UIDungeonTopMenu.create(topNode);
-- 初始化BUFF状态条
--self.dungeonStatusBar =UIDungeonStatusBar.create();
-- 记录状态条的初始位置
--self.statusBarInitPos =cc.p(self.statusBarNode:getPosition());
--self.statusParentInitPos =cc.p(self.statusParentNode:getPosition());
return self;
end
--适配
resize= function(node)
require("game/ui/base/AlignM")
local w = AlignM.frameSize.width;
local h = AlignM.frameSize.height;
node:setContentSize(w, h);
local scale;
if h / w > 1.5 then
scale = w / (DESIGN_WIDTH);
else
-- 在宽高比小于等于1.5时(如iphone或ipad),需要略微比预定比例缩小些。所以加了75像素
scale = h / (DESIGN_HEIGHT + 75);
end
local topBg = findChildByName(node,"CT1/top_bg");
local bottomBg = findChildByName(node,"CT1/bottom_bg");
local mask = findChildByName(node,"CT1/mask");
local newWidth = w / scale;
topBg:setScaleX(newWidth/topBg:getContentSize().width);
bottomBg:setScaleX(newWidth/bottomBg:getContentSize().width);
topBg:setScaleY(topBg:getScaleY());
bottomBg:setScaleY(bottomBg:getScaleY());
mask:setScaleX(newWidth/mask:getContentSize().width);
local ct1 = findChildByName(node,"CT1");
ct1:setPosition(w / 2, h / 2);
ct1:setScale(scale);
local scale2;
if h / w >= 1.5 then
scale2 = w / (DESIGN_WIDTH);
else
scale2 = h / (DESIGN_HEIGHT);
end
-- 底部菜单按原来适配规则缩放
local ct2 = findChildByName(node,"CT2");
ct2:setPosition(w / 2, 0);
ct2:setScale(scale2);
local ct3 = findChildByName(node,"CT3");
ct3:setPosition(w / 2, 0);
ct3:setScale(scale);
local talkNode = findChildByName(node,"talk_node");
talkNode:setPosition(w / 2, h / 2);
talkNode:setScale(scale *DUNGEON_AJUST_SCALE);
localeffectNode = findChildByName(node, "effect_node");
effectNode:setPosition(w / 2, h / 2);
effectNode:setScale(scale *DUNGEON_AJUST_SCALE);
local lockNode = findChildByName(node,"lock_panel");
lockNode:setPosition(w / 2, h / 2);
lockNode:setScale(scale *DUNGEON_AJUST_SCALE);
local lockNode2 = findChildByName(node,"lock_panel2");
lockNode2:setPosition(w / 2, h / 2);
lockNode2:setContentSize(w + 10, h + 10);
local slidePanel = findChildByName(node,"slide_touch_panel");
slidePanel:setPosition(w / 2, h / 2);
slidePanel:setScale(scale *DUNGEON_AJUST_SCALE);
local specialEffectNode =findChildByName(node, "effect_ex_node");
specialEffectNode:setPosition(w / 2, h /2);
specialEffectNode:setScale(scale *DUNGEON_AJUST_SCALE);
local bossEffectNode =findChildByName(node, "boss_effect_node");
bossEffectNode:setPosition(w / 2, h / 2);
bossEffectNode:setScale(scale *DUNGEON_AJUST_SCALE);
local selectTargetNode =findChildByName(node, "select_target_node");
selectTargetNode:setPosition(w / 2, h / 2);
selectTargetNode:setScale(scale);
local panel = findChildByName(node,"select_target_node/panel");
panel:setScale(DUNGEON_AJUST_SCALE);
-- 目标选择蒙版拉伸充满整个屏幕
local selectTargetBg =node:getChildByName("select_target_bg")
selectTargetBg:setContentSize(w, h)
selectTargetBg:setPosition(0, 0)
-- 黑色蒙版拉伸充满整个屏幕
local blackMaskBg =node:getChildByName("black_mask");
blackMaskBg:setContentSize(w, h);
blackMaskBg:setPosition(0, 0);
AlignM.alignToTopCenter(node,"TOP");
-- 能量圈和BUFF状态条节点适配,保持与顶部菜单固定距离
local skillEnergyBarNode =findChildByName(node, "CT1/skill_energy_bar");
local statusBarNode = findChildByName(node,"CT1/status_bar");
if h/ w > 1.5 then
local deltaY = (h / w * DESIGN_WIDTH -(DESIGN_HEIGHT + 75)) / 2;
skillEnergyBarNode:setPositionY(skillEnergyBarNode:getPositionY() +deltaY);
statusBarNode:setPositionY(statusBarNode:getPositionY() + deltaY);
end
-- 计算最右边的点的坐标
local pos =skillEnergyBarNode:getParent():convertToNodeSpace(cc.p(w, 0));
-- 能量圈始终紧靠右边
skillEnergyBarNode:setPositionX(pos.x);
end
代码中用到了原版中的一些内容,直接将对应文件拷贝到相应目录即可。其中有一些错误需要自己修正。游戏使用了某种技术,可以自动在lua中将类型向下转换,或者是弄了个超大集合类,反正我是不懂,比如:
self.attackLabel =findChildByName(self.node, "CT2/atk_val");
setStyle(self.attackLabel);
local function setStyle(textNode)
……
textNode:setFontSize(28);
……
end
self.attackLabel是cc.Node,而在setStyle函数中直接调用了某个派生类才有的textNode:setFontSize(28);请问是如何做到的?
另外,self.attackLabel的最终类型是ccui.Text,它并没有一个叫做:setTTFConfig(fontName,fontSize, olColor, olSize)的函数(有个类有这个函数,但不是4个参数),因此TextStyleM. setTextStyle作了一点修正:
-- targetNode:setTTFConfig(fontName,fontSize * smoothScale, olColor, olSize);
targetNode:setFontName(fontName);
targetNode:setFontSize(fontSize *smoothScale);
终于正常显示了:
这篇关于00003 不思议迷宫.0010.1.1.2:csb解析显示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!