这一篇文章主要是讲解一下 cocos2dx 9宫格纹理更新问题

我这里就不说 cocos2dx 9宫格怎么使用了。在网上一搜一大堆。基本内容都是那样。我不想做无谓的叙述了。

问题描述

现在的环境是:
cocos2dx 3.15
VS 2015
使用 lua 写项目

注意这里是说使用 plist 里面的纹理 也就是精灵帧

现在面临的问题是: cocos2dx 对9宫格纹理更新,不能像更新精灵那样使用它提供的函数 setSpriteFrame
虽然9宫格就是对精灵的在次封装。

cocos2dx 九宫格的这个函数(setSpriteFrame)在C++定义的头文件中是长这样的

1
2
3
// UIScale9Sprite.h
virtual void setSpriteFrame(SpriteFrame * spriteFrame, const Rect& capInsets);
//它没有提供直接输入字符串来实现纹理的更换.

这说明我们需要一个精灵帧类型,但是这个类型我用了这么时间,基本没用过。

问题剖析

我上面有说过九宫格是对纹理的再次封装实现的,说以就去查看他的父类Sprite.h这个是怎么初始化的。

追了 它父类的初始化函数 Sprite.h 看到了它是怎么创建出精灵帧的,下面是他初始化它内部的精灵帧的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Sprite::setSpriteFrame(const std::string &spriteFrameName)
{
CCASSERT(!spriteFrameName.empty(), "spriteFrameName must not be empty");
if (spriteFrameName.empty())
{
return;
}

SpriteFrameCache *cache = SpriteFrameCache::getInstance();
// 根据名字在精灵帧缓存中查找相应的精灵帧。
SpriteFrame *spriteFrame = cache->getSpriteFrameByName(spriteFrameName);

CCASSERT(spriteFrame, std::string("Invalid spriteFrameName :").append(spriteFrameName).c_str());
// 设置自己内部的精灵帧对象
setSpriteFrame(spriteFrame);
}

原理是在精灵帧缓存中查找对象
设置精灵的精灵帧

代码实现

这下就好办了。

lua层的代码就是

1
2
3
4
5
local spriteFrameCache = cc.SpriteFrameCache:getInstance()
local frame = spriteFrameCache:getSpriteFrame("xxx.png")
-- xxx.png 就是你 plist文件中对应的文件名字。
-- 这个就是我们需要的精灵帧对象
-- 然后在调用它的 setSpriteFrame

具体的实现代码lua层的
c++层我就不说了。暂时没有用到。做法都一样。
上面的实现在 cocos2dx display的lua文件里面有实现。所以就直接调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- desc: 创建9宫格图片
-- params [ path | pos | capInsets | size | rect ]
-- params.path 可以是精灵帧 ej: params.path = "#xxx.png"
-- params.pos 精灵的位置
-- params.capInsets 是9宫格中间 Rect 的位置和大小
-- params.rect 可以不用填
function T.cp_s9( parentNode, params )
local pos = params.pos
local s = display.newSprite(params.path,pos.x,pos.y,params)
local _ = parentNode and parentNode:addChild(s)
return s
end
-- desc: 9宫格图片纹理的更新
-- path 无效添加报错机制
function T.update_s9( node, path, capInsets, size )
if string.byte(path) == 35 then
local sp = display.newSpriteFrame(path)
node:setSpriteFrame(sp,capInsets)
else
if not cc.FileUtils:getInstance():isFileExist(path) then
error(string.format("invalid path , file isn't exist , path - %s",path))
end
node:setTexture(path)
end
node:setContentSize(size)
end

需要注意的一点就是在九宫格更新纹理后尺寸又变回原来的大小,你需要重新设置大小。

最后更新: 2019年08月14日 11:22

原始链接: https://leng521.top/posts/1e09c0f5/