cocos2d-iphone – cocos2d中非矩形CCNode的轮廓(笔划)

cocos2d-iphone – cocos2d中非矩形CCNode的轮廓(笔划),第1张

概述我需要动态创建这样的轮廓: 不适用于CCSprite,而是适用于在一个CCNode中合并的多个动画CCSprit.我在考虑: >将CCNode的内容复制到纹理(如AS3中的canvasBitmapData.draw(sourceDisplayObject)) >使用生成的纹理创建CCSprite >将精灵着色为轮廓颜色并稍微缩放 >将精灵放在节点中的其他精灵后面 我不知道如何执行步骤1.也许在步骤 我需要动态创建这样的轮廓:

不适用于CCSprite,而是适用于在一个CCNode中合并的多个动画CCSprit.我在考虑:

>将CCNode的内容复制到纹理(如AS3中的canvasBitmapData.draw(sourcedisplayObject))
>使用生成的纹理创建CCSprite
>将精灵着色为轮廓颜色并稍微缩放
>将精灵放在节点中的其他精灵后面

我不知道如何执行步骤1.也许在步骤3中在纹理的不透明像素周围绘制“true stroke”而不是色调比例更快?

我完全忘记发布这个问题的答案.这是一个非常平滑的笔画的代码.它并不快,但在第一台iPad上为几个大精灵工作得很好.

我们的想法是在精灵周围画出微小的彩色和模糊的球,并将它们放在自己的纹理上.它既可以用于CCNode,也可以用于CCSprite.该代码还会移动锚点,因为生成的精灵将具有更大的宽度和高度.

得到的轮廓(身体和2只手,在iPad1上约0.3秒):

白球示例:

> 5f:http://i.stack.imgur.com/e9kos.png
> 10f:http://i.stack.imgur.com/S5goU.png
> 20f:http://i.stack.imgur.com/qk7GL.png

CCNode类别,适用于Cocos2d-iPhone 2.1:

@implementation CCNode (Outline)- (CCSprite*) outline{    return [self outlineRect:CGRectMake(0,self.contentSize.wIDth,self.contentSize.height)];}- (CCSprite*) outlineRect:(CGRect)rect{    NSInteger gap = dscale(4);    CGPoint positionShift = ccp(gap - rect.origin.x,gap - rect.origin.y);    CGSize canvasSize = CGSizeMake(rect.size.wIDth + gap * 2,rect.size.height + gap * 2);    CCRenderTexture* renderedSpriteTexture = [self renderTextureFrom:self shiftedFor:positionShift onCanvasSized:canvasSize];    CGSize textureSize = renderedSpriteTexture.sprite.contentSize;    CGSize textureSizeInPixels = renderedSpriteTexture.sprite.texture.contentSizeInPixels;    NSInteger bitsPerComponent = 8;    NSInteger bytesPerPixel = (bitsPerComponent * 4) / 8;    NSInteger bytesPerRow = bytesPerPixel * textureSizeInPixels.wIDth;    NSInteger myDataLength = bytesPerRow * textureSizeInPixels.height;    NSMutableData* buffer = [[NSMutableData alloc] initWithCapacity:myDataLength];    Byte* bytes = (Byte*)[buffer mutableBytes];    [renderedSpriteTexture begin];    glreadPixels(0,textureSizeInPixels.wIDth,textureSizeInPixels.height,GL_RGBA,GL_UNSIGNED_BYTE,bytes);    [renderedSpriteTexture end];    //SEE ATTACHMENT TO GET THE fileS    Nsstring* spriteFramename;    if (IS_IPAD) spriteFramename = (CC_CONTENT_SCALE_FACTOR() == 1) ? @"10f.png" : @"20f.png";    else spriteFramename = (CC_CONTENT_SCALE_FACTOR() == 1) ? @"5f.png" : @"10f.png";    CCSprite* circle = [CCSprite spriteWithSpriteFramename:spriteFramename];    circle.anchorPoint = ccp(0.48,0.48);    float retinaScale = (CC_CONTENT_SCALE_FACTOR() == 1) ? 1.0 : 0.5;    CCRenderTexture* strokeTexture = [CCRenderTexture renderTextureWithWIDth:textureSize.wIDth height:textureSize.height pixelFormat:kCCTexture2DPixelFormat_RGBA8888];    [strokeTexture beginWithClear:0 g:0 b:0 a:0];    for (NSInteger x = 0; x < textureSizeInPixels.wIDth; x++)    {        for (NSInteger y = 0; y < textureSizeInPixels.height; y++)        {            NSInteger IDx = y * bytesPerRow + x * bytesPerPixel + 3;            NSInteger w = 1;            if (bytes[IDx] <= 254)            {                BOol shouldBestroked = NO;                for (NSInteger nx = -w; nx <= w; nx++)                {                    for (NSInteger ny = -w; ny <= w; ny++)                    {                        if (x + nx < 0 || y + ny < 0 || x + nx >= textureSizeInPixels.wIDth || y + ny >= textureSizeInPixels.height)                            continue;                        if (bytes[IDx + nx * bytesPerPixel + ny * bytesPerRow] == 255)                        {                            shouldBestroked = YES;                            break;                        }                    }                }                if (shouldBestroked == YES)                {                    circle.position = ccp(x * retinaScale,y * retinaScale);                    [circle visit];                }            }        }    }    [strokeTexture end];    CCSprite* resultSprite = [CCSprite spriteWithTexture:strokeTexture.sprite.texture];    [resultSprite.texture setAntiAliasTexParameters];    resultSprite.flipY = YES;    if ([self isKindOfClass:[CCSprite class]]) {        CGPoint oldAnchorInPixels = ccp(roundf(self.contentSize.wIDth * self.anchorPoint.x),roundf(self.contentSize.height * self.anchorPoint.y));        resultSprite.anchorPoint = ccp((oldAnchorInPixels.x + gap) / resultSprite.contentSize.wIDth,(oldAnchorInPixels.y + gap) / resultSprite.contentSize.height);        resultSprite.position = self.position;    } else { //CCNode        resultSprite.anchorPoint = CGPointZero;        resultSprite.position = ccpAdd(self.position,ccp(rect.origin.x - gap,rect.origin.y - gap));    }    return resultSprite;}- (CCRenderTexture*) renderTextureFrom:(CCNode*)node shiftedFor:(CGPoint)posShift onCanvasSized:(CGSize)size{    SoftAssertion(!CGSizeEqualToSize(size,CGSizeZero),@"node has zero size");    BOol issprite = [node isMemberOfClass:[CCSprite class]];    CGPoint apSave = node.anchorPoint;    CGPoint posSave = node.position;    BOol wasVisible = node.visible;    CCRenderTexture* rtx = [CCRenderTexture renderTextureWithWIDth:size.wIDth                                                            height:size.height                                                       pixelFormat:kCCTexture2DPixelFormat_RGBA8888];    [rtx beginWithClear:0 g:0 b:0 a:0];    node.anchorPoint = CGPointZero;    node.position = posShift;    node.visible = YES;    if (issprite) [node visit];    else [[self cloneCCNode:node] visit];    node.anchorPoint = apSave;    node.position = posSave;    node.visible = wasVisible;    [rtx end];    return rtx;}- (CCNode*) cloneCCNode:(CCNode*)source{    CCNode* clone = [CCNode node];    voID (^copyCCNodePropertIEs)(CCNode*,CCNode*) = ^(CCNode* source,CCNode* clone)    {        clone.visible = source.visible;        clone.rotation = source.rotation;        clone.position = source.position;        clone.anchorPoint = source.anchorPoint;        clone.zOrder = source.zOrder;        clone.tag = source.tag;    };    for (CCNode* srcSubnode in source.children) {        CCNode* subNode;        if ([srcSubnode isMemberOfClass:[CCSprite class]]) {            CCSprite* srcSprite = (CCSprite*)srcSubnode;            subNode = [CCSprite spriteWithTexture:srcSprite.texture];            CCSprite* subSprite = (CCSprite*)subNode;            subSprite.flipX = srcSprite.flipX;            subSprite.flipY = srcSprite.flipY;            subSprite.displayFrame = srcSprite.displayFrame;            subSprite.opacity = srcSprite.opacity;        }        else if ([srcSubnode isMemberOfClass:[cclabelTTF class]]) {            cclabelTTF* srcLabel = (cclabelTTF*)srcSubnode;            subNode = [cclabelTTF labelWithString:srcLabel.string Fontname:srcLabel.Fontname FontSize:srcLabel.FontSize dimensions:srcLabel.dimensions hAlignment:srcLabel.horizontalAlignment vAlignment:srcLabel.verticalAlignment];            CCSprite* subLabel = (CCSprite*)subNode;            subLabel.flipX = srcLabel.flipX;            subLabel.flipY = srcLabel.flipY;            subLabel.color = srcLabel.color;        }        else {            subNode = [self cloneCCNode:srcSubnode];        }        copyCCNodePropertIEs(srcSubnode,subNode);        [clone addChild:subNode];    }    copyCCNodePropertIEs(source,clone);    return clone;}
总结

以上是内存溢出为你收集整理的cocos2d-iphone – cocos2d中非矩形CCNode的轮廓(笔划)全部内容,希望文章能够帮你解决cocos2d-iphone – cocos2d中非矩形CCNode的轮廓(笔划)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1000102.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存