简体   繁体   English

Cocos2d - 如何使单个粒子跟随层,而不是发射器?

[英]Cocos2d - how to make individual particles follow the layer, not the emitter?

I have a CCSprite and a CCParticleSystemQuad that are both children of the CCLayer. 我有一个CCSprite和一个CCParticleSystemQuad,它们都是CCLayer的子代。 In my update method, I set the emitter's position to that of the sprite, so it tracks the sprite around. 在我的更新方法中,我将发射器的位置设置为精灵的位置,因此它会跟踪精灵。 The smoke puff fall out the bottom of the sprite like you'd expect and even though you move the sprite around, the smoke appears to be part of the background layer. 烟雾就像你期望的那样落在精灵的底部,即使你移动精灵,烟雾似乎也是背景层的一部分。

The problem come if I match up their rotations. 如果我匹配他们的轮换,问题就来了。 Now, for example if my sprite is rocking back and forth, the puffs of smoke swing in an arc and appear attached to the sprite. 现在,例如,如果我的精灵来回摇摆,那烟雾就会以弧形摆动并出现在精灵身上。

How can I make the puffs of smoke continue along the parent layer in a straight line and not rotate with the sprite? 如何使烟雾沿着父层沿直线继续,而不是用精灵旋转? They don't translate with the sprite when I move it, so why do they rotate with it? 我移动时它们不会用精灵转换,那么为什么它们随之旋转呢?

EDIT: adding code... 编辑:添加代码......

- (id)init
{
    if (!(self = [super init])) return nil;

    self.isTouchEnabled = YES;

    CGSize screenSize = [[CCDirector sharedDirector] winSize];

    sprite = [CCSprite spriteWithFile:@"Icon.png"]; // declared in the header
    [sprite setPosition:ccp(screenSize.width/2, screenSize.height/2)];
    [self addChild:sprite];

    id repeatAction = [CCRepeatForever actionWithAction:
                        [CCSequence actions:
                         [CCRotateTo actionWithDuration:0.3f angle:-45.0f],
                         [CCRotateTo actionWithDuration:0.6f angle:45.0f],
                         [CCRotateTo actionWithDuration:0.3f angle:0.0f], 
                         nil]];
    [sprite runAction:repeatAction];

    emitter = [[CCParticleSystemQuad particleWithFile:@"jetpack_smoke.plist"] retain]; // declared in the header - the particle was made in Particle Designer
    [emitter setPosition:sprite.position];
    [emitter setPositionType:kCCPositionTypeFree]; // ...Free and ...Relative seem to behave the same.
    [emitter stopSystem];
    [self addChild:emitter];

    [self scheduleUpdate];

    return self;
}


- (void)update:(ccTime)dt
{
    [emitter setPosition:ccp(sprite.position.x, sprite.position.y-sprite.contentSize.height/2)];
    [emitter setRotation:[sprite rotation]]; // if you comment this out, it works as expected.
}

// there are touches methods to just move the sprite to where the touch is, and to start the emitter when touches began and to stop it when touches end.

I found the answer on a different site - www.raywenderlich.com 我在另一个网站上找到了答案 - www.raywenderlich.com

I don't know why this is true, but it seems that CCParticleSystems don't like to be rotated while you move them around. 我不知道为什么会这样,但似乎CCParticleSystems不喜欢在你移动它们时旋转。 They don't mind changing their angle property. 他们不介意改变他们的角度属性。 Actually, there may be cases where you want that behavior. 实际上,可能存在您想要这种行为的情况。

Anyway I made a method that adjusts the emitter's angle property and it works fine. 无论如何,我做了一个方法来调整发射器的角度属性,它工作正常。 It takes your touch location and scales the y component to be the angle. 它会占用您的触摸位置并将y分量缩放为角度。

- (void)updateAngle:(CGPoint)location
{
    float width = [[CCDirector sharedDirector] winSize].width;
    float angle = location.x / width * 360.0f;
    CCLOG(@"angle = %1.1f", angle);
    [smoke_emitter setAngle:angle]; // I added both smoke and fire!
    [fire_emitter setAngle:angle];
    //    [emitter setRotation:angle]; // this doesn't work
}

CCSprite's anchorPoint is {0.5f, 0.5f), while the emitter descends directly from CCNode, which has an anchorPoint of {0.0f, 0.0f}. CCSprite的anchorPoint是{0.5f,0.5f),而发射器直接从CCNode下降,CCNode的anchorPoint为{0.0f,0.0f}。 Try setting the emitter's anchorPoint to match the CCSprite's. 尝试设置发射器的anchorPoint以匹配CCSprite。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM