14

问题:

如何用 Spritekit 实现这个动画?

在此处输入图像描述

我做了什么:

在此处输入图像描述

问题:

1)我可以画出所有四个花瓣,但是一旦我抬起手指来画圆,它仍然会从我抬起手指的前一个点到新的触摸开始点创建一条线。参考下面的gif:

在此处输入图像描述

2)如何逐步从视图中删除橙色实线(我的太突然了)?

3) 需要调整 .sks 文件属性。

4) https://stackoverflow.com/questions/29792443/set-the-initial-state-of-skemitternode

这是我的代码:

#import "GameScene.h"

@interface GameScene()

@property (nonatomic) SKEmitterNode* fireEmmitter;
@property (nonatomic) SKEmitterNode* fireEmmitter2;

@end

@implementation GameScene

NSMutableArray *_wayPoints;
NSTimer* myTimer;

-(void)didMoveToView:(SKView *)view {

_wayPoints = [NSMutableArray array];

//Setup a background
self.backgroundColor = [UIColor blackColor];

//setup a fire emitter
NSString *fireEmmitterPath = [[NSBundle mainBundle] pathForResource:@"magic" ofType:@"sks"];
_fireEmmitter = [NSKeyedUnarchiver unarchiveObjectWithFile:fireEmmitterPath];
_fireEmmitter.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2 - 200);
_fireEmmitter.name = @"fireEmmitter";
_fireEmmitter.zPosition = 1;
_fireEmmitter.targetNode = self;
_fireEmmitter.particleBirthRate = 0;
[self addChild: _fireEmmitter];

//setup another fire emitter
NSString *fireEmmitterPath2 = [[NSBundle mainBundle] pathForResource:@"fireflies" ofType:@"sks"];
_fireEmmitter2 = [NSKeyedUnarchiver unarchiveObjectWithFile:fireEmmitterPath2];
_fireEmmitter2.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
_fireEmmitter2.name = @"fireEmmitter";
_fireEmmitter2.zPosition = 1;
_fireEmmitter2.targetNode = self;
_fireEmmitter2.particleBirthRate = 0;
[self addChild: _fireEmmitter2];


//Setup a LightNode
SKLightNode* light = [[SKLightNode alloc] init];
light.categoryBitMask = 1;
light.falloff = 1;
light.ambientColor = [UIColor whiteColor];
light.lightColor = [[UIColor alloc] initWithRed:1.0 green:1.0 blue:0.0 alpha:0.5];
light.shadowColor = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:0.3];
[_fireEmmitter addChild:light];

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

CGPoint touchPoint = [[touches anyObject] locationInNode:self.scene];

CGMutablePathRef ref = CGPathCreateMutable();

CGPoint p = touchPoint;
p = [self.scene convertPointToView:p];
CGPathMoveToPoint(ref, NULL, p.x, p.y);

_fireEmmitter.position = CGPointMake(touchPoint.x, touchPoint.y);
_fireEmmitter.particleBirthRate = 2000;

}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

CGPoint touchPoint = [[touches anyObject] locationInNode:self.scene];

//On Dragging make the emitter with the attached light follow the position
for (UITouch *touch in touches) {
    [self addPointToMove:touchPoint];

    CGPoint location = [touch locationInNode:self];
    [self childNodeWithName:@"fireEmmitter"].position = CGPointMake(location.x, location.y);
}
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
_fireEmmitter.particleBirthRate = 0;

[self performSelector:@selector(userHasCompletedTheDrawing) withObject:nil afterDelay:3];
}

- (void)userHasCompletedTheDrawing{
CGMutablePathRef path = CGPathCreateMutable();
if (_wayPoints && _wayPoints.count > 0) {
    CGPoint p = [(NSValue *)[_wayPoints objectAtIndex:0] CGPointValue];
    //p = [self.scene convertPointToView:p];
    CGPathMoveToPoint(path, nil, p.x, p.y);

    _fireEmmitter2.position = CGPointMake(p.x,p.y);
    _fireEmmitter2.particleBirthRate = 1000;

    for (int i = 0; i < _wayPoints.count; ++i) {
        p = [(NSValue *)[_wayPoints objectAtIndex:i] CGPointValue];
        CGPathAddLineToPoint(path, nil, p.x, p.y);
    }
    SKAction *followTrack = [SKAction followPath:path asOffset:NO orientToPath:YES duration:1];
    [_fireEmmitter2 runAction:followTrack completion:^{

        _fireEmmitter2.particleBirthRate = 0;

        [_fireEmmitter2 runAction:[SKAction waitForDuration:1] completion:^{
            //_fireEmmitter2.particleBirthRate = 0;
        }];
    }];
}


//myTimer = [NSTimer scheduledTimerWithTimeInterval: 0.01 target: self selector: @selector(removePointToMove) userInfo: nil repeats: YES];
[self performSelector:@selector(removeAllPointToMove) withObject:nil afterDelay:1];

}

- (void)addPointToMove:(CGPoint)point {
[_wayPoints addObject:[NSValue valueWithCGPoint:point]];
}

- (void)removeAllPointToMove{
[_wayPoints removeAllObjects];
}

- (void)removePointToMove{

if ([_wayPoints count]>0) {
    [_wayPoints removeObjectAtIndex:0];
}
}

- (void)drawLines {
//1

NSMutableArray *temp = [NSMutableArray array];
for(CALayer *layer in self.view.layer.sublayers) {
    if([layer.name isEqualToString:@"line"]) {
        [temp addObject:layer];
    }
}

[temp makeObjectsPerformSelector:@selector(removeFromSuperlayer)];

//3
CAShapeLayer *lineLayer = [CAShapeLayer layer];
lineLayer.name = @"line";
lineLayer.strokeColor = [UIColor orangeColor].CGColor;
lineLayer.fillColor = nil;
lineLayer.lineWidth = 3;
lineLayer.lineJoin = kCALineJoinRound; /* The join style used when stroking the path. Options are `miter', `round'
                                        * and `bevel'. Defaults to `miter'. */
lineLayer.zPosition = -1;

//4
CGPathRef path = [self createPathToMove];
lineLayer.path = path;
CGPathRelease(path);
[self.view.layer addSublayer:lineLayer];

}

- (CGPathRef)createPathToMove {
//1
CGMutablePathRef ref = CGPathCreateMutable();

//2
for(int i = 0; i < [_wayPoints count]; ++i) {
    CGPoint p = [_wayPoints[i] CGPointValue];
    p = [self.scene convertPointToView:p];
    //3
    if(i == 0 ) {
        CGPathMoveToPoint(ref, NULL, p.x, p.y);
    } else {
        CGPathAddLineToPoint(ref, NULL, p.x, p.y);
    }
}

return ref;
}

-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */

[self drawLines];

if ([_wayPoints count]==0) {
    [myTimer invalidate];
}

}
@end

这是我的 .sks 文件属性:

在此处输入图像描述 在此处输入图像描述

4

1 回答 1

1

关于您的第一个问题,您需要将 CGPathRef 拆分为多个子路径,以便在花瓣和中心之间不画线。绘制完花瓣后使用该函数,CGPathCloseSubpath以便之后调用。CGPathMoveToPointCGPathAddLineToPoint

于 2015-04-28T01:13:20.760 回答