美文网首页
SpriteKit学习笔记(子节点随父节点移动)

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

作者: CoderZNB | 来源:发表于2017-05-12 16:45 被阅读0次

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


    飞船移动.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];
            }
        }];
    }
    

    相关文章

      网友评论

          本文标题:SpriteKit学习笔记(子节点随父节点移动)

          本文链接:https://www.haomeiwen.com/subject/dwnfzttx.html