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

时间:2014-07-15 00:38:30

标签: ios swift sprite-kit

我正在使用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()
}

2 个答案:

答案 0 :(得分:2)

Apple的文档中的示例位于Advanced Scene Processing部分。 Apple建议制作一个" World" SKNode 作为场景的孩子,以及"相机" SKNode 作为世界的孩子。

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

如果您只想要左右滚动,只需将移动限制在X轴上。

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

这可以通过创建World和Player而不使用具有位置设置的Rect来解决。 SKShapeNode的shapeNodeWithRectOfSize和SKSpriteNode的spriteNodeWithColor:size:物理实体一样有用,可能会使用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
}

答案 1 :(得分:0)

我在侧面滚动游戏Super Koalio(或类似的东西)上关注了Ray Wenderlich的教程。该游戏是侧面滚动条,其中游戏地图比屏幕侧向更大。以下代码适用于我的游戏,即垂直滚动游戏。

在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 !!