SpriteKit输送带

时间:2014-01-10 09:14:58

标签: ios iphone objective-c ios7 sprite-kit

我正在尝试使用像这样的SpriteKit创建传送带效果

Screenshot

我的第一反应是创建一个比屏幕大的传送带图像,然后通过动作反复移动它。但这似乎不合适,因为它取决于屏幕尺寸。

有没有更好的方法呢?

显然我也想把东西(它会独立移动)放在传送带上,这样节点就是一个带有子精灵节点的SKNode。

更新:我希望传送带“视觉上”移动;因此,线条会朝着给人以运动印象的方向移动。

2 个答案:

答案 0 :(得分:2)

physicsBody应用于您需要在传送带上移动的所有精灵,并将affectedByGravity属性设置为NO。

在这个例子中,我假设表示传送带的spriteNode被称为conveyor。此外,需要移动的所有精灵节点都具有字符串“moveable”作为其name属性。

然后,在你的-update:方法中,

-(void)update:(CFTimeInterval)currentTime
{
    [self enumerateChildNodesWithName:@"moveable" usingBlock:^(SKNode *node, BOOL *stop{ 
        if ([node intersectsNode:conveyor])
        {
            [node.physicsBody applyForce:CGVectorMake(-1, 0)];
            //edit the vector to get the right force. This will be too fast.
        }
    }];
}

在此之后,只需在正确的位置添加所需的精灵,您就会看到它们自行移动。

对于动画,最好使用一个可以在精灵上循环的纹理数组。

或者,您可以添加和删除一系列带有截面图像的小精灵,然后移动它们就像在传送带上行进的精灵一样。

答案 1 :(得分:0)

@akashg指出了一个通过传送带移动物体的解决方案,我正在回答如何使传送带看起来好像在移动

一个建议和我最初的直觉是在场景中放置一个比屏幕更大的矩形并重复移动。经过反思,我认为这不是一个好的解决方案,因为如果我们想在中间放置一条传送带,我们会看到它的两端都是没有额外剪裁蒙版的。

理想的解决方案是将SKTexture平铺在SKSpriteNode上,然后忽略此纹理;但是Sprite Kit似乎没有这个功能(没有瓦片机制)。

所以基本上我正在做的是从纹理创建子纹理,就像这样[tile] [tile](2次可重复的tile),我只是一个接一个地显示这些子纹理来创建动画。

以下是代码:

- (SKSpriteNode *) newConveyor
{
    SKTexture *conveyorTexture = [SKTexture textureWithImageNamed:@"testTextureDouble"];
    SKTexture *halfConveyorTexture = [SKTexture textureWithRect:CGRectMake(0.5, 0.0, 0.5, 1.0) inTexture:conveyorTexture];

    SKSpriteNode *conveyor = [SKSpriteNode spriteNodeWithTexture:halfConveyorTexture size:CGSizeMake(conveyorTexture.size.width/2, conveyorTexture.size.height)];

    NSArray *textureArray = [self horizontalTextureArrayForTxture:conveyorTexture];
    SKAction *moveAction = [SKAction animateWithTextures:textureArray timePerFrame:0.01 resize:NO restore:YES];
    [conveyor runAction:[SKAction repeatActionForever:moveAction]];

    return conveyor;
}

- (NSArray *) horizontalTextureArrayForTxture : (SKTexture *) texture
{
    CGFloat deltaOnePixel = 1.0 / texture.size.width;
    int countSubtextures = texture.size.width / 2;

    NSMutableArray *textureArray = [[NSMutableArray alloc] initWithCapacity:countSubtextures];

    CGFloat offset = 0;
    for (int i = 0; i < countSubtextures; i++)
    {
        offset = i * deltaOnePixel;
        SKTexture *subTexture = [SKTexture textureWithRect:CGRectMake(offset, 0.0, 0.5, 1.0) inTexture:texture];
        [textureArray addObject:subTexture];
    }

    return [NSArray arrayWithArray:textureArray];
}

现在这仍然不理想,因为需要手动制作带有2个图块的图像。我们还可以使用SKTexture转换编辑CIFilter,该转换可能会用于创建包含2个图块的纹理。

除此之外,我认为这个解决方案更好,因为它不依赖于屏幕的大小而且内存效率高;但是为了在整个屏幕上使用它,我必须创建更多SKSpriteNode个共享我使用过的moveAction对象的对象,因为根据这个来源,使用Sprite Kit无法进行平铺: How do you set a texture to tile in Sprite Kit

我将尝试更新代码,以便通过使用多个SKSpriteNode对象进行平铺。