我在使用cocos2d-x framework(c ++)创建的项目。 在我的Player类中,我必须管理动画。 最初我有这个代码没有任何问题:
首先,动画对象是cocos2d类cocos2d::Animation
。请记住,此对象包含cocos2d::Vector<AnimationFrame*> _frames;
成员。
Doc:http://www.cocos2d-x.org/reference/native-cpp/V3.5/d3/dc5/classcocos2d_1_1_animation.html#a0fdc0be158df7e09d04644be353db056
class Player : public cocos2d::Sprite {
private:
cocos2d::Map<std::string, cocos2d::Animation*> animations;
cocos2d::Vector<cocos2d::SpriteFrame*> getAnimation(const char *format, int frameStart, int count);
void update(float delta) override;
bool init() override;
public:
static Player* create();
bool init() override;
//...
};
执行方:
bool Player::init() {
//...
animations.insert("idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1));
//...
}
Vector<SpriteFrame*> Player::getAnimation(const char *format, int frameStart, int count) {
auto spriteCache = SpriteFrameCache::getInstance();
Vector<SpriteFrame*> animFrames;
char str[100] = {0};
for (int i = 1; i <= count; i++)
{
sprintf(str, format, frameStart);
log("%s", str);
animFrames.pushBack(spriteCache->getSpriteFrameByName(str));
frameStart++;
}
return animFrames;
}
//later in the code execution
void Player::manageIdle() {
auto idleAnim = Animate::create(animations[0].anim);
runAction(idleAnim);
}
你可以看到每个动画都包含在cocos2d::Map<std::string, cocos2d::Animation*>
中,正如我之前所说,这段代码完美无缺,没有错误。
但除了名称和对象本身之外我还需要更多信息,所以我决定使用一个结构来存储每个动画的所有信息。我将cocos2d::Map<std::string, cocos2d::Animation*>
替换为std::vector<animData>
并将animData
替换为class Player : public cocos2d::Sprite {
public:
typedef struct animation {
std::string name;
cocos2d::Animation* anim;
//all others info needed, not relevant here, (just several enum type variables)
} animData;
private:
std::vector<animData > animations; //the new container
//rest of code stay unchanged
};
作为结构。我像这样重构了代码:
bool Player::init() {
//...
animations.push_back({"idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1)});
//no problem here...
}
执行方面的变化:
void Player::manageIdle() {
auto idleAnim = Animate::create(animations[0].anim); //SegV here, in Animate::create() funct
runAction(idleAnim);
}
但是现在,当我尝试使用保存在我的容器(矢量)中的动画创建一个新的动画时,我在这一行上获得了一个SegV:
anim
搜索之后,我发现每个结构成员cocos2d::Vector<AnimationFrame*> _frames;
都是cocos2d :: Animation *的类型,现在包含一个空的cocos2d::Vector<AnimationFrame*>
并且存在问题!
好像他们失去了cocos2d::Vector<AnimationFrame*>
ref或类似的东西。
所以我的问题是为什么auto test = animList[0].anim->getFrames();
if (test.empty()) {
log("empty"); //The test output empty
}
会因为我的重构代码变空而不是之前的代码?
我通过这样的测试找到了这个:
animations.back().anim->retain();
init()功能结束时的Debugguer屏幕:
Player :: manageIdle()功能中的Debugguer屏幕:
修改:当我在行后面添加animations.push_back({"idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1)});
animations.back().anim->retain();
以在向量中添加元素时,它解决了问题!
cocos2d::Animation*
因为animations.back().anim->retain();
继承自cocos2d :: Ref,所以它是一个自动释放对象。当在cocos2d容器中使用时,如cocos2d :: Map或cocos2d :: Vector,它由容器本身自动管理。但是我使用了std :: vector,所以我失去了我认为的参考。这样的事情。
现在我需要找到一种方法来摆脱这个额外的代码行,因为这个倍数是我的行数的两倍!
这里有一个新问题:每次在向量中添加新元素时,如何摆脱我必须调用const vue2 = new Vue({
el: '#vue2',
data: function() {
return {
modalShow: false
}
},
methods: {
showModal() {
this.$refs.myModal.show()
}
},
render() {
return(
<div>
<b-btn on-click={this.showModal}>Show Modal</b-btn>
<b-modal ref="myModal">
Hello From My Modal!
</b-modal>
</div>
)
}
的事实?
答案 0 :(得分:0)
你可以在Ref
周围创建一个“保留”所有权的包装器,然后存储这个包装器,排序为std::unique_ptr
,例如。
template<typename T> class RefOwner {
public:
RefOwner(T *t) : ref(t) {
ref->retain();
}
~RefOwner() {
ref->release();
}
T *operator->() { return ref; }
private:
T *ref;
};
然后将其用作
struct animData {
std::string name;
RefOwner<cocos2d::Animation> anim;
//all others info needed, not relevant here, (just several enum type variables)
};