需求:现在有一个需求,创建一个飞船,飞船上有一个灯,灯随着飞船的移动而移动
使用节点构建复杂的内容
新的场景还没有任何内容,所以你要准备添加一个飞船到场景,要构建飞船,你需要用到多个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];
}
}];
}