定义地图边界并在玩家节点上居中?

我正在使用Spritekit和Swift开发一个sidescroller。 我不明白如何定义比屏幕更大的可播放区域并将相机放在播放器上。 如何才能做到这一点?

这是我目前的代码,我试图创建一个“世界节点”,我可以移动来模拟相机,但它不知何故与它的形状分离,我无法将其置于其中。

override func didMoveToView(view: SKView) { self.anchorPoint = CGPointMake(0.5, 0.5) self.physicsWorld.contactDelegate = self self.size = CGSizeMake(view.bounds.size.width, view.bounds.size.height) // Add world let r : CGRect = CGRectMake(0, 0, 500, 500) world = SKShapeNode(rectOfSize: r.size) world.physicsBody = SKPhysicsBody(edgeLoopFromRect: r) world.strokeColor = SKColor.blackColor() world.position = CGPointMake(0, 0) self.addChild(world) // Add player player = SKShapeNode(rectOfSize: CGSize(width: 50, height: 50)) player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 50, height: 50)) player.fillColor = SKColor.blackColor() player.position = CGPointMake(0, 0) world.addChild(player) // Accelerometer updates motionManager.startAccelerometerUpdates() } 

Apple文档中的示例位于“ 高级场景处理”部分。 Apple建议将“世界” SKNode作为场景的孩子,并将“相机” SKNode作为世界儿童。

他们建议不断移动世界,以便在didSimulatePhysics步骤中以摄像机为中心。 如果您愿意,此方法允许您在相机本身上执行操作或模拟物理。 如果在此步骤之前居中相机,则无法使用物理效果影响相机节点。

如果您只想要左右滚动,只需将移动限制为X轴即可。

编辑:当前的问题是因为你创建了这个世界,而且是一个具有预定位置的Rect的physicsBody。 这会导致你的anchorPoint设置出现问题(正在创建world&physicsBody,其左下角从Scene的锚点开始)。

这可以通过创建World和Player而不使用具有位置集的Rect来解决。 SKShapeNode的shapeNodeWithRectOfSize和SKSpriteNode的spriteNodeWithColor:size: PhysicsBody有点棘手,应该使用bodyWithEdgeLoopFromPath: world.path

编辑:对于未来有兴趣创建侧面卷轴的人,相机始终专注于播放器,这可能是最简单的方法:

 var player = SKShapeNode() var world = SKShapeNode() override func didMoveToView(view: SKView) { self.anchorPoint = CGPointMake(0.5, 0.5) self.size = CGSizeMake(view.bounds.size.width, view.bounds.size.height) // Add world world = SKShapeNode(rectOfSize: CGSizeMake(300, 300)) world.physicsBody = SKPhysicsBody(edgeLoopFromPath: world.path) world.fillColor = SKColor.blackColor() self.addChild(world) // Add player player = SKShapeNode(rectOfSize: CGSize(width: 50, height: 50)) player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 50, height: 50)) player.fillColor = SKColor.blackColor() world.addChild(player) } override func update(currentTime: CFTimeInterval) { world.position.x = -player.position.x world.position.y = -player.position.y } 

我按照Ray Wenderlich的教程编写了一个侧面滚动游戏Super Koalio(或类似的东西)。 该游戏是侧卷轴,其中游戏地图比屏幕侧向更大。 以下代码适用于我的游戏,即垂直滚动游戏。

在update方法中,我调用了一个名为setViewPointCenter的方法。

 -(void)update:(CFTimeInterval)currentTime { // Other things are called too [self setViewPointCenter:self.player.position]; } 

然后在该方法中,您只需更新视图

 - (void)setViewPointCenter:(CGPoint)position { NSInteger x = MAX(position.x, self.size.width / 2); NSInteger y = MAX(position.y, self.size.height /2); x = MIN(x, (self.map.mapSize.width * self.map.tileSize.width) - self.size.width / 2); y = MIN(y, (self.map.mapSize.height * self.map.tileSize.height) - self.size.height / 2); CGPoint actualPostion = CGPointMake(x, y); CGPoint centerOfView = CGPointMake(self.size.width/2, self.size.height/2); CGPoint viewPoint = CGPointSubtract(centerOfView, actualPostion); self.map.position = viewPoint; } 

现在我的角色总是在屏幕的中心。 我确实将一些项目从水平更改为垂直,但至少你有一个想法。 另外,我使用了一个瓦片地图,这就是你看到mapSize和tileSize的原因。 你可能想看一下Ray的教程。 当然你需要将方法转换成Swift !!