关于 2dx v3.7 UIScale9Sprite的bug
关于 2dx v3.7 UIScale9Sprite的bug刚把引擎从js binding v3.0升级到v3.7,发现了一些bug,这里先说说关于scale9sprite的 1. 关于capInsetshttps://github.com/cocos2d/cocos2d-x/issues/13560
bool Scale9Sprite::updateWithSprite(Sprite* sprite,const Rect& textureRect,bool rotated,const Vec2 &offset,const Size &originalSize,const Rect& capInsets)
{
//...
// Set the given rect's size as original size
_spriteRect = rect;
_offset = offset;
_spriteFrameRotated = rotated;
_originalSize = size;
_preferredSize = size;
// if(!capInsets.equals(Rect::ZERO)) //此处的if判断应该去掉,直接赋值给_capInsetsInternal
{
_capInsetsInternal = capInsets;
}
if (_scale9Enabled)
{
this->createSlicedSprites();
}
//...
}
void Scale9Sprite::setSpriteFrame(SpriteFrame * spriteFrame,const Rect& capInsets)
{
Sprite * sprite = Sprite::createWithTexture(spriteFrame->getTexture());
this->updateWithSprite(sprite,spriteFrame->getRect(),spriteFrame->isRotated(),spriteFrame->getOffset(),spriteFrame->getOriginalSize(),capInsets);
// Reset insets
this->_insetLeft = capInsets.origin.x; // == 0
this->_insetTop = capInsets.origin.y;// == 0
this->_insetRight = _originalSize.width - _insetLeft - capInsets.size.width; //== width
this->_insetBottom = _originalSize.height - _insetTop - capInsets.size.height;// ==height
}
然后cocosbuilder加载scale9sprite时,顺序调用setInsetLeft(0),setInsetTop(0),setInsetRight(0),setInsetBottom(0) void Scale9SpriteLoader::onHandlePropTypeFloat(Node * pNode,Node * pParent,const char * pPropertyName,float pFloat,CCBReader * ccbReader) {
if(strcmp(pPropertyName,PROPERTY_INSETLEFT) == 0) {
((cocos2d::ui::Scale9Sprite *)pNode)->setInsetLeft(pFloat);
} else if(strcmp(pPropertyName,PROPERTY_INSETTOP) == 0) {
((cocos2d::ui::Scale9Sprite *)pNode)->setInsetTop(pFloat);
} else if(strcmp(pPropertyName,PROPERTY_INSETRIGHT) == 0) {
((cocos2d::ui::Scale9Sprite *)pNode)->setInsetRight(pFloat);
} else if(strcmp(pPropertyName,PROPERTY_INSETBOTTOM) == 0) {
((cocos2d::ui::Scale9Sprite *)pNode)->setInsetBottom(pFloat);
} else {
NodeLoader::onHandlePropTypeFloat(pNode,pParent,pPropertyName,pFloat,ccbReader);
}
}
4个函数都会调用updateCapInset,并在其中调用setCapInsets,在setCapInsets中调用updateWithSprite和重新计算_insetRight,_insetBottom的值, void Scale9Sprite::setCapInsets(const Rect& capInsets)
{
Size contentSize = this->_contentSize;
this->updateWithSprite(this->_scale9Image,_spriteRect,_spriteFrameRotated,_offset,_originalSize,capInsets); // 这里传入的capInsets = (0,origin.width,0),此值不等于zero,在updateWithSprite中会赋值给_capInsetsInternal
this->_insetLeft = capInsets.origin.x;
this->_insetTop = capInsets.origin.y;
this->_insetRight = _originalSize.width - _insetLeft - capInsets.size.width;
this->_insetBottom = _originalSize.height - _insetTop - capInsets.size.height;
this->setContentSize(contentSize);
}
然后再在最后一次调用 setInsetBottom(0)时,capInsets==zero,因为有 // If there is no specified center region
if ( _capInsetsInternal.equals(Rect::ZERO) )
{
// log("... cap insets not specified : using default cap insets ...");
_capInsetsInternal = Rect(width /3,height /3,width /3,height /3);
}
当_capInsetsInternal == (0,0)时,默认值也不会被使用,那么九宫格缩放当然是错误的啦。 =======================华丽的分割线======================= 2. 创建的九宫格图片偏移了几个像素https://github.com/cocos2d/cocos2d-x/issues/13564 createSlicedSprites接口中计算offsetPosition时: void Scale9Sprite::createSlicedSprites()
{
float width = _originalSize.width;
float height = _originalSize.height;
Vec2 offsetPosition(ceil(_offset.x + (_originalSize.width - _spriteRect.size.width) / 2),ceil(_offset.y + (_originalSize.height - _spriteRect.size.height) / 2));
//...
}
此处计算偏移时为什么要向上取整,总之我不是很明白,希望有人能解释一下,谢谢。 把ceil换成floor后,发现正常了,如图(texturepacker打开shape outlines): 那么问题来了: =======================华丽的分割线======================= (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |