SpriteKit学习笔记(子节点随父节点移动)

2017-05-12  本文已影响0人  CoderZNB

需求:现在有一个需求,创建一个飞船,飞船上有一个灯,灯随着飞船的移动而移动


飞船移动.gif
使用节点构建复杂的内容

新的场景还没有任何内容,所以你要准备添加一个飞船到场景,要构建飞船,你需要用到多个SKSpriteNode对象来创造飞船和他表面的灯光.每个精灵节点都执行动作

闪烁的灯光是飞船的一部分!如果飞船移动,灯光应该和他一起移动.解决的办法是使飞船节点成为灯光节点的父节点,同样的场景将是飞船的父节点.光的坐标将要相对于父节点的位置来指定,而父节点是在子精灵图像的中心.

1.添加飞船
 SKSpriteNode *spaceship = [self newSpaceship];
    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:spaceship];
2.实现添加飞船的方法newSpaceship
// 创建飞船节点
- (SKSpriteNode *)newSpaceship {
    
    SKSpriteNode *hull = [[SKSpriteNode alloc] initWithColor:[SKColor grayColor] size:CGSizeMake(200, 150)];
    
    SKAction *hover = [SKAction sequence:@[
                                           [SKAction waitForDuration:1.0],
                                           [SKAction moveByX:100 y:50 duration:1.0],
                                           [SKAction waitForDuration:1.0],
                                           [SKAction moveByX:-100 y:-50 duration:1.0]
                                           ]];
    
    [hull runAction:[SKAction repeatActionForever:hover]];
    
    hull.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:hull.size];
    hull.physicsBody.dynamic = NO;
    
    SKSpriteNode *light1 = [self creatLight];
    light1.position = CGPointMake(-30.0, 6.0);
    [hull addChild:light1];
    
    SKSpriteNode *light2 = [self creatLight];
    light2.position = CGPointMake(30.0, 6.0);
    [hull addChild:light2];
    return hull;
}

此方法创建了一个飞船的船体,并添加了一个简短的动画,运行后你会看到一个矩形

3.创建灯光节点
// 创建灯光节点
- (SKSpriteNode *)creatLight {

    SKSpriteNode *light = [[SKSpriteNode alloc] initWithColor:[SKColor yellowColor] size:CGSizeMake(30, 30)];
    SKAction *blink = [SKAction sequence:@[
                                           [SKAction fadeOutWithDuration:0.25],
                                           [SKAction fadeInWithDuration:0.25]
                                           
                                           ]];
    SKAction *blinkForever = [SKAction repeatActionForever:blink];
    
    [light runAction:blinkForever];
    return light;
}

运行后你会看到一对灯光在飞船上,飞船移动时,灯光随着移动

以上就是核心代码,关于添加的岩石,以及物理系统碰撞在下面的源码之中,这里就不做讲解


@implementation ZNBSceneA
- (instancetype)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {
        
        self.backgroundColor = [SKColor darkGrayColor];
        self.physicsWorld.gravity = CGVectorMake(0.0, -9.0);
    }
    
    return self;
}

- (void)didMoveToView:(SKView *)view {
    [super didMoveToView:view];
    SKSpriteNode *spaceship = [self newSpaceship];
    spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:spaceship];
    
    
    [self makeRock];
    
}

// 创建岩石方法
- (void)makeRock {
    SKAction *makeRocks = [SKAction sequence:@[
                                               [SKAction performSelector:@selector(addRock) onTarget:self],
                                               [SKAction waitForDuration:0.1 withRange:0.15]
                                               ]];
    
    [self runAction:[SKAction repeatActionForever:makeRocks]];
}

// 创建灯光节点
- (SKSpriteNode *)creatLight {

    SKSpriteNode *light = [[SKSpriteNode alloc] initWithColor:[SKColor yellowColor] size:CGSizeMake(30, 30)];
    SKAction *blink = [SKAction sequence:@[
                                           [SKAction fadeOutWithDuration:0.25],
                                           [SKAction fadeInWithDuration:0.25]
                                           
                                           ]];
    SKAction *blinkForever = [SKAction repeatActionForever:blink];
    
    [light runAction:blinkForever];
    return light;
}
// 创建飞船节点
- (SKSpriteNode *)newSpaceship {
    
    SKSpriteNode *hull = [[SKSpriteNode alloc] initWithColor:[SKColor grayColor] size:CGSizeMake(200, 150)];
    
    SKAction *hover = [SKAction sequence:@[
                                           [SKAction waitForDuration:1.0],
                                           [SKAction moveByX:100 y:50 duration:1.0],
                                           [SKAction waitForDuration:1.0],
                                           [SKAction moveByX:-100 y:-50 duration:1.0]
                                           ]];
    
    [hull runAction:[SKAction repeatActionForever:hover]];
    
    hull.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:hull.size];
    hull.physicsBody.dynamic = NO;
    
    SKSpriteNode *light1 = [self creatLight];
    light1.position = CGPointMake(-30.0, 6.0);
    [hull addChild:light1];
    
    SKSpriteNode *light2 = [self creatLight];
    light2.position = CGPointMake(30.0, 6.0);
    [hull addChild:light2];
    return hull;
}

static inline CGFloat skRandf() {
    return rand()/(CGFloat)RAND_MAX;
}
static inline CGFloat skRand(CGFloat low, CGFloat high) {
    return skRandf()*(high - low) + low;
}
- (void)addRock {
    SKSpriteNode *rock = [[SKSpriteNode alloc] initWithColor:[SKColor brownColor] size:CGSizeMake(10, 10)];
    rock.position = CGPointMake(skRand(0, self.size.width), self.size.height-50);
    rock.name = @"rock";
    
    rock.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rock.size];
    rock.physicsBody.usesPreciseCollisionDetection = YES;

    [self addChild:rock];
    
}

-(void)didSimulatePhysics {
    [self enumerateChildNodesWithName:@"rock" usingBlock:^(SKNode * _Nonnull node, BOOL * _Nonnull stop) {
        // 删除不在屏幕的节点,否则节点会越来越多
        if (node.position.y < 0) {
            [node removeFromParent];
        }
    }];
}
上一篇下一篇

猜你喜欢

热点阅读