【发布时间】:2017-05-26 18:33:50
【问题描述】:
我正在使用 SpriteKit 在 Swift 中制作一个平台游戏,其中包含一个跳跃的主角。但是,一旦关卡加载,玩家就会立即从地面坠落。 You can see it in action here.
我正在使用 SKTilemapNode 创建地面,并在加载关卡时循环通过瓷砖以在瓷砖地图的子节点上创建 SKPhysicsBody。这与 WWDC 2016 的“SpriteKit 中的新功能”视频中演示的内容非常相似:
所以,我们在这里建立了一个小平台。一个可以跑来跑去的小家伙。你可以看到我在后台进行了视差滚动。你会注意到我在这里与瓷砖碰撞。我通过利用我们可以放在每个图块上的自定义用户数据来实现这一点。在这里,我将在我们的瓷砖组中向您展示。在此处选择一种变体。 你可以看到我们这里有一些用户数据。我只有一个名为 edgeTile 的值,它是一个布尔值,我设置为 1。 所以,在代码中,我在这里浏览了我们平台演示中的瓦片图,我正在寻找所有这些边缘瓦片。 每当我找到它时,我都会创建一些物理数据来让玩家与之碰撞。
我基于 SKTilemapNode 创建物理体的功能如下:
extension SKTileMapNode {
//In order for this to work, edge tile definitions must have the "edge" property in user data
func createPhysicsBody() -> SKPhysicsBody {
var physicsBodies = [SKPhysicsBody]()
for row in 0 ..< self.numberOfRows {
for column in 0 ..< self.numberOfColumns {
if self.tileDefinition(atColumn: column, row: row)?.userData?["edge"] != nil {
physicsBodies.append(SKPhysicsBody(rectangleOf: self.tileSize, center: self.centerOfTile(atColumn: column, row: row)))
}
}
}
let body = SKPhysicsBody(bodies: physicsBodies)
body.affectedByGravity = false
body.isDynamic = false
body.allowsRotation = false
body.pinned = true
body.restitution = 0
body.collisionBitMask = 0b1111
body.categoryBitMask = 0b1111
body.contactTestBitMask = 0b1000
return body
}
func initializePhysicsBody() {
let node = SKNode()
node.name = "Tilemap"
node.physicsBody = createPhysicsBody()
addChild(node)
}
}
所以,在我的场景设置中,我所要做的就是调用 tileMap.initializePhysicsBody() 来做我需要的一切。
我的播放器的 SKPhysicsBody 如下:
let rect = CGSize(width: 16 * xScale, height: 24 * yScale)
let physics = SKPhysicsBody(rectangleOf: rect)
physics.isDynamic = true
physics.allowsRotation = false
physics.pinned = false
physics.affectedByGravity = true
physics.friction = 0
physics.restitution = 0
physics.linearDamping = 0
physics.angularDamping = 0
physics.density = 100
physics.categoryBitMask = 0b0001
physics.collisionBitMask = 0b0001
physics.contactTestBitMask = 0b0011
physics.usesPreciseCollisionDetection = true
physicsBody = physics
我不确定问题出在哪里,但是如果我将 SKTilemapNode 的物理主体设置为动态的,它就可以工作。这就是我让游戏一直运行到现在的方式,但是,这会在地面上产生很多抖动,因为玩家击中它会导致地面移动。所以,至少感谢您阅读本文,任何建议都将不胜感激。
【问题讨论】:
-
您是否尝试过将 body.isDynamic 切换为 true?
-
如我所见,玩家与第一帧上的瓷砖相交,在这种情况下没有任何碰撞。你能试着把玩家移动到瓷砖上方吗?也许它会起作用。
-
@PéterKovács 感谢您的回答,但不幸的是我的角色仍然失败了@sicvayne 是的,这在过去对我有用,我只是认为它停止工作没有任何意义一次
body.isDynamic = false。我最终设置了body.isDynamic = false; body.mass = CGFloat(Int.max)来解决这个问题。 -
哎呀,对不起大家,我的意思是
body.isDynamic = true; body.mass = CGFloat(Int.max)让它工作
标签: ios swift sprite-kit