如何在spriteKit中进行相机移动

时间:2013-12-10 11:10:29

标签: ios objective-c sprite-kit

我为物理体大小为0.0的相机创建了SKSpriteNode,以避免不必要的碰撞和世界节点:

    -(void)createSceneContents {

SKNode *world = [SKNode node];
world.name = @"world";
self.anchorPoint = CGPointMake(0.1, 0);
SKSpriteNode *camera = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(300, 300)];
camera.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(0, 0)];
camera.physicsBody.affectedByGravity = NO;
camera.physicsBody.usesPreciseCollisionDetection = NO;
camera.physicsBody.categoryBitMask = noColisions;
camera.alpha = 0.5;
camera.zPosition = 1;
camera.name = @"cam";
[self addChild:world];
[world addChild:camera];

我已经尝试了一个小教程在spriteKit平台游戏中添加相机,但我甚至无法移动视图,我不知道如何访问移动视图的属性。谁知道我做错了什么? 这是我的代码:

-(void)didSimulatePhysics
{
    //I've tried with @"cam" and @"hero"
    [self centerOnNode: [self childNodeWithName:@"world"]];
}
-(void)centerOnNode:(SKNode *) camera {
    CGPoint cameraPositionInScene = [camera.scene convertPoint:camera.position fromNode:camera.parent];

    [self.parent setPosition:CGPointMake(
        camera.parent.position.x - cameraPositionInScene.x,
        camera.parent.position.y - cameraPositionInScene.y
    )];
}

4 个答案:

答案 0 :(得分:7)

Apple's Documentation的示例中,您所遵循的摄像机节点不是SKSprite,而是 SKNode 。我想这会解决你的问题。

要回答标题中的问题,您实际上要做的是将世界节点附加到场景中。在此节点内,放置了所有精灵。作为世界节点的子节点,您可以为摄像机添加另一个节点。

这为您提供了三种不同的坐标系。想象一下,三张纸,最底部是你的世界,即包含所有精灵的图层。最重要的是一张代表相机的小纸片。最重要的是,你有一个透明的盒子,代表你的观察区域。

设置方式无法移动最透明的观看层。相反,你正在做的是移动位于世界图层顶部的点,然后将世界图层滑动到该点。

现在想象一下,在纸质场景中,这是一个2D滚动世界,你只能左右移动。现在拿相机点并将其一直放在观察区域的最右侧。现在,取世界图层并将其拖动到左侧,直到相机位于不可移动的查看区域的中心。这或多或少,发生了什么。

答案 1 :(得分:2)

在Apple的冒险样本游戏中,他们不会移动相机,而是“世界”SKNode,它是最顶级的。

摘自Apple文档,了解他们是如何做到的:

  

在Adventure中所有与世界相关的节点,包括背景图块,   字符和树叶是世界节点的子节点,而这又是世界节点的子节点   是一个孩子的场景。我们改变了这棵树顶的位置   场景内的世界节点给出了移动摄像机的效果   整个关卡。相比之下,构成HUD的节点是   一个单独节点的子节点,而不是场景的直接子节点   而不是世界节点,因此HUD中的元素不会移动   当我们“移动相机。”

Read about it more here

答案 2 :(得分:1)

要添加以前的答案,您应该以相机为中心,而不是世界......

所以而不是

[self centerOnNode: [self childNodeWithName:@"world"]];

你应该使用

[self centerOnNode: [self childNodeWithName:@"cam"]];

并且不要忘记将相机更改为SKNode而不是SKSprite。

..并进行测试,在相机节点上添加moveTo动作,来回移动以检查相机居中是否有效。我建议把电话放在touchesbegan

示例(将其放在您的相机所在的场景上):

将这些放在@implementation

之前
@interface yourClassNameHere()  // edit this to your own class name
@property SKNode *theWorld;
@property SKNode *theCamera;
@property BOOL cameraRunning;
@end

如上所示,我把节点(世界和相机)放在这个类的属性上,所以我不像你在帖子上那样用节点名称来引用它们。

将其放在“实施”部分

// Process Camera centering

-(void) didSimulatePhysics {
    [self centerOnNode:self.theCamera];
}

-(void) centerOnNode: (SKNode *) node {
    CGPoint pos = [node.scene convertPoint:node.position fromNode:node.parent];
    CGPoint p = node.parent.position;
    node.parent.position = CGPointMake(p.x - pos.x, p.y-pos.y);   
}

// .. Move the camera around when you touch , to see if it works.. 

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (!self.cameraRunning) {
    self.cameraRunning = YES;
    SKAction *moveUp = [SKAction moveByX:0 y:500 duration:3];
    SKAction *moveDown = [SKAction moveByX:0 y:-500 duration:3];
    SKAction *moveLeft = [SKAction moveByX:-500 y:0 duration:3];
    SKAction *moveRight = [SKAction moveByX:500 y:0 duration:3];
    SKAction *sequence = [SKAction sequence:@[moveUp, moveRight,moveDown,moveLeft]];
    [self.theCamera runAction:sequence];

} else {
        self.cameraRunning = NO;
        [self.theCamera removeAllActions];
        self.theCamera.position = CGPointZero;
    }
}

问候

PS:你想要锚点0,0或1,1?检查你的锚点设置

答案 3 :(得分:0)

如果您想移动视图,只需移动相机:

// Center the view at 100, 0
camera.position = CGPointMake(100, 0); 

这里有how to set up a 2D camera system in SpriteKit稍长的例子(在Swift中,不是ObjC,但很容易翻译)。