使用Sprite Kit创建2D波纹效果

3
我该如何在Sprite Kit中创建一个二维水波纹特效呢?
比如,我有一个场景,其中包含2D静态水面,当点击水面时,会出现小圆圈,逐渐放大并消失,大约有5-6个圆圈同时缩放,形成涟漪的感觉,实际上并不对水面做任何改变,只是在其上创建图像。
我想知道解决这个问题的最佳方法是什么。如何实现这样的效果?有什么好的点子吗?

2
只需添加圆形并将它们放大并淡出,就可以达到效果。在同一点生成圆圈,并在它们之间设置一些时间,应该可以达到效果。 - Dobroćudni Tapir
3个回答

3
在您希望创建涟漪的节点中,只需像这样执行操作:
    NSTimeInterval singleRippleDuration = 1.0f;
    CGFloat ripleEndScale = 3.0f;
    NSTimeInterval timeBetweenRipples = 0.3f;
    NSUInteger numberOfRipples = 5;
    SKAction* scaleUpAction = [SKAction scaleTo:ripleEndScale duration:singleRippleDuration];
    SKAction* fadeOutAction = [SKAction fadeOutWithDuration:singleRippleDuration];

    SKAction* rippleAction = [SKAction group:@[scaleUpAction,fadeOutAction]];

    SKAction* createRipple = [SKAction runBlock:^{
        //Create your ripple node somehow (SKShapeNode or SKSprite will do)
        //set it to a desired position
        [rippleNode setPosition:desiredPosition];
        //Set scale to 0 so it scales from point
        [rippleNode setScale:0.0f];
        [rippleNode runAction:createRipple];
        [self addChild:rippleNode];
    }];

    SKAction* wait = [SKAction waitForDuration:timeBetweenRipples];

    [self runAction:[SKAction repeatAction:[SKAction sequence:@[createRipple,wait]] count:numberOfRipples]];

你好,你的示例代码看起来很不错,但我无法使其正常工作。我使用了这段代码来创建一个圆(未填充),以绘制涟漪效果。+(SKShapeNode *) dibujarCircunferencia:(NSInteger) radio { CGRect box = CGRectMake(0.0f, 0.0f, radio, radio); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddEllipseInRect(path, NULL, box); SKShapeNode *circle = [SKShapeNode node]; circle.path = path; CGPathRelease(path); circle.alpha = 0.5f; circle.lineWidth = 1.0f; circle.strokeColor = [SKColor orangeColor]; return circle; } - Jorge Vega Sánchez
这是gcd块的代码。runBlock:^{ //以某种方式创建你的涟漪节点(可以使用SKShapeNode或SKSprite) SKShapeNode *rippleNode; SKSpriteNode *rn; rippleNode = [punto dibujarCircunferencia:150]; //将其设置到所需位置 rippleNode.position = CGPointMake(0.0f, 0.0f); //将比例设置为0,使其从一个点开始缩放 rippleNode.scale = 0.0f; rippleNode.lineWidth = 0.5f; rn = rippleNode; rn.zPosition = 1.0f; [rippleNode runAction:createRipple]; [self.player addChild:rn]; }]; 我不知道我做错了什么。 - Jorge Vega Sánchez
1
首先,我不确定你在做什么 :)1)检查您的rippleNode是否正确实例化。2)没有必要使用SKSpriteNode * rn,只需在所有地方使用rippleNode即可。 - Dobroćudni Tapir
请发布最终代码,上面的代码会发出警告,因为变量未被使用... - fernandospr
什么是 selfrippleNode?你能提供一个完整的可用示例吗? - Vyachaslav Gerchicov

1

"CreateRipple"方法中有一个打字错误,它在代码块中运行自身,而不是像应该的那样在“rippleAction”中运行。修正后的方法如下:

SKAction* createRipple = [SKAction runBlock:^{
    //Create your ripple node somehow (SKShapeNode or SKSprite will do)
    //set it to a desired position
    [rippleNode setPosition:desiredPosition];
    //Set scale to 0 so it scales from point
    [rippleNode setScale:0.0f];
    [rippleNode runAction:rippleAction];
    [self addChild:rippleNode];
}];

希望有所帮助!

再次提问 - selfrippleNode 分别是什么? - Vyachaslav Gerchicov
我只是在纠正上面的答案,因为我没有评论它的经验,所以只好把它放在另一个答案中(如果这样做是错误的,对不起),有关其他信息,请参见上文。 - steve
代码将位于视图控制器上的任何方法内,例如触摸操作。节点本身可以只是一个圆形/椭圆形精灵,随着它变得越来越大并像涟漪一样消失。 - steve

0

这是一个完整的非常简单的@Dobroćudni Tapir代码示例。如果开发iOS应用程序,您可以尝试在touchesBegan中使用它,而不是mouseDown。

import SpriteKit

class GameScene: SKScene {
    override func mouseDown(theEvent: NSEvent) {
        /* Called when a mouse click occurs */
        let location = theEvent.locationInNode(self)
        let singleRippleDuration = 1.0
        let ripleEndScale = CGFloat(3.0)
        let timeBetweenRipples = 0.3
        let numberOfRipples = 3
        let scaleUpAction = SKAction.scaleTo(ripleEndScale, duration: singleRippleDuration)
        let fadeOutAction = SKAction.fadeOutWithDuration(singleRippleDuration)
        let rippleAction = SKAction.group([scaleUpAction, fadeOutAction])

        let createRipple = SKAction.runBlock({
            let rippleNode = SKShapeNode(circleOfRadius: 200)
            rippleNode.position = location
            rippleNode.setScale(0)
            rippleNode.runAction(rippleAction)
            self.addChild(rippleNode)
        })

        let wait = SKAction.waitForDuration(timeBetweenRipples)
        runAction(SKAction.repeatAction(SKAction.sequence([createRipple, wait]), count: numberOfRipples))
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接