2015-04-22 21 views
14

Domanda:Come realizzare questa animazione con Spritekit?

Come ottenere questa animazione con Spritekit?

enter image description here

quello che ho fatto:

enter image description here

Problema:

1) posso disegnare tutti e quattro i petali, ma una volta che alzo il dito a Disegna il cerchio, creerà comunque una linea dal punto precedente in cui alzo il dito sul punto di inizio dei nuovi tocchi. fare riferimento a gif di seguito:

enter image description here

2) Come rimuovere la linea arancione solido dal punto di vista in modo incrementale (il mio è troppo brusco)?

3) È necessario ottimizzare le proprietà del file .sks.

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

Questo è il mio codice:

#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 

Questo è il mio .sks file di proprietà:

enter image description here enter image description here

+0

Qual è il tuo problema. 'Non funzionerà' non è una descrizione corretta – Okapi

+0

Stai cercando una duplicazione esatta o un'approssimazione? – sangony

+0

@sangony Duplicazione dell'effetto. – user1872384

risposta

1

Con Per quanto riguarda la prima domanda, è necessario dividere il CGPathRef in più sottotracciati in modo che nessuna linea venga disegnata tra i petali e il centro. Utilizzare la funzione CGPathCloseSubpath al termine del disegno dei petali in modo da poter chiamare in seguito CGPathMoveToPoint e CGPathAddLineToPoint.