gpt4 book ai didi

ios - Swift SKPhysicsBody 通过具有匹配位掩码的静态 SKPhysicsBody

转载 作者:行者123 更新时间:2023-11-30 12:26:02 26 4
gpt4 key购买 nike

我正在 Swift 中使用 SpriteKit 制作一款平台游戏,其中涉及一个跳跃的主角。然而,一旦关卡加载,玩家就会立即掉到地上。 You can see it in action here.

我使用 SKTilemapNode 创建地面,并在加载关卡时循环遍历图 block ,以在图 block map 的子节点上创建 SKPhysicsBody。这与 WWDC 2016 上的“SpriteKit 新增功能”视频中演示的内容非常相似:

So, here we've got a little platform that I built. A little guy that can run around. And you can see that I got the parallax scrolling going on in the background. And you'll note that I'm colliding with the tiles here. And I achieve this by leveraging custom user data that we can put on each of our tiles. Here, I'll show you in our tile set. Select one of the variants here. And you can see that we have some user data over here. And I just have a value called edgeTile which is a Boolean, and I set to 1. So, in code, I'm going through the tile map in our platform demo here, and I'm looking for all of these edge tiles. And whenever I find one, I create some physics data to allow the player to collide with it.

我基于 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 的物理体设置为动态,它就可以工作。到目前为止,这就是我让游戏运行的方式,但是,这会在地面上产生很多抖动,因为它会因玩家击中它而移动。所以,至少感谢您阅读到这里,如有任何建议,我们将不胜感激。

最佳答案

编辑。我认为这里的错误不是使用 UInt 32

body.categoryBitMask: UInt32 = 2
body.collisionBitMask: UInt32 = 1
body.contactTestBitMask: UInt32 = 1

和玩家

physics.categoryBitMask: UInt32 = 1
physics.collisionBitMask: UInt32 = 2
physics.contactTestBitMask: UInt32 = 2

这绝对应该有效

也可以对tileMapNode(如下所示)尝试这种方式,而不是创建扩展。这是 dontangg 在苹果开发者论坛上给出的

self.tileMap = self.childNode(withName: "Tile Map") as? SKTileMapNode  
guard let tileMap = self.tileMap else { fatalError("Missing tile map for the level") }

let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height

for col in 0..<tileMap.numberOfColumns {
for row in 0..<tileMap.numberOfRows {
let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
let isEdgeTile = tileDefinition?.userData?["edgeTile"] as? Bool
if (isEdgeTile ?? false) {
let x = CGFloat(col) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight
let rect = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKShapeNode(rect: rect)
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2.0, y: tileSize.height / 2.0))
tileNode.physicsBody?.isDynamic = false
tileNode.physicsBody?.collisionBitMask = playerCollisionMask | wallCollisionMask
tileNode.physicsBody?.categoryBitMask = wallCollisionMask
tileMap.addChild(tileNode)
}
}
}

关于ios - Swift SKPhysicsBody 通过具有匹配位掩码的静态 SKPhysicsBody,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44208131/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com