Swift/SpriteKit 碰撞检测
Swift/SpriteKit Collision Detection
我创建了两个物体,一堵墙和一个可以碰撞的玩家。如果它们确实发生碰撞,玩家将无法进入或越过墙壁。如果我设置了 massWall >> massPlayer,玩家有时可以越过墙。如果我没有设置质量,玩家和墙就会朝一个方向移动。我想实现墙是静止不动的,玩家拿不到over/through墙。
我的代码:
func addWall(xPos: CGFloat, yPos: CGFloat){
let wallNode = SKSpriteNode(imageNamed: "wall")
wallNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
wallNode.physicsBody!.affectedByGravity = false
wallNode.physicsBody!.categoryBitMask = ColliderType.Wall.rawValue
wallNode.physicsBody!.contactTestBitMask = ColliderType.Player.rawValue
wallNode.physicsBody!.collisionBitMask = ColliderType.Player.rawValue
wallNode.physicsBody!.mass = 1000000
let wall = Wall(node: wallNode)
Walls.append(wall)
wallNode.position.x = xPos
wallNode.position.y = yPos
wallNode.size = CGSize(width: width, height: width)
addChild(wallNode)
}
func addPlayer(xPos: CGFloat, yPos: CGFloat){
playerNode = SKSpriteNode(imageNamed: "player")
playerNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
playerNode.physicsBody!.affectedByGravity = false
playerNode.physicsBody!.categoryBitMask = ColliderType.Player.rawValue
playerNode.physicsBody!.contactTestBitMask = ColliderType.Wall.rawValue
playerNode.physicsBody!.collisionBitMask = ColliderType.Wall.rawValue
playerNode.physicsBody!.mass = 1
let player = Player(node: playerNode, healthPoints: 100, attack: 10)
playerNode.position.x = xPos
playerNode.position.y = yPos
playerNode.size = CGSize(width: width, height: width)
addChild(playerNode)
}
在 func didBeginContact(){}
中我没有任何代码,因为我现在不知道如何处理它。我无法撤消移动,因为我没有跟踪最后一次移动。
您需要更改两件事。第一个是解决玩家穿墙。这是通过在 playerNode
上启用精确的碰撞检测来解决的(只需将其与 physicsBody
配置的其余部分放在一起):
playerNode.physicsBody!.usesPreciseCollisionDetection = true
接下来你需要让你的墙没有动态物理,这将阻止它在你的 playerNode
撞到它时做出反应。你不需要设置wallNode
的mass
,你不会需要它。所以应该添加这样的东西(只需将其与 physicsBody
配置的其余部分放在一起):
wallNode.physicsBody!.dynamic = false
我创建了两个物体,一堵墙和一个可以碰撞的玩家。如果它们确实发生碰撞,玩家将无法进入或越过墙壁。如果我设置了 massWall >> massPlayer,玩家有时可以越过墙。如果我没有设置质量,玩家和墙就会朝一个方向移动。我想实现墙是静止不动的,玩家拿不到over/through墙。 我的代码:
func addWall(xPos: CGFloat, yPos: CGFloat){
let wallNode = SKSpriteNode(imageNamed: "wall")
wallNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
wallNode.physicsBody!.affectedByGravity = false
wallNode.physicsBody!.categoryBitMask = ColliderType.Wall.rawValue
wallNode.physicsBody!.contactTestBitMask = ColliderType.Player.rawValue
wallNode.physicsBody!.collisionBitMask = ColliderType.Player.rawValue
wallNode.physicsBody!.mass = 1000000
let wall = Wall(node: wallNode)
Walls.append(wall)
wallNode.position.x = xPos
wallNode.position.y = yPos
wallNode.size = CGSize(width: width, height: width)
addChild(wallNode)
}
func addPlayer(xPos: CGFloat, yPos: CGFloat){
playerNode = SKSpriteNode(imageNamed: "player")
playerNode.physicsBody = SKPhysicsBody(circleOfRadius: width/2)
playerNode.physicsBody!.affectedByGravity = false
playerNode.physicsBody!.categoryBitMask = ColliderType.Player.rawValue
playerNode.physicsBody!.contactTestBitMask = ColliderType.Wall.rawValue
playerNode.physicsBody!.collisionBitMask = ColliderType.Wall.rawValue
playerNode.physicsBody!.mass = 1
let player = Player(node: playerNode, healthPoints: 100, attack: 10)
playerNode.position.x = xPos
playerNode.position.y = yPos
playerNode.size = CGSize(width: width, height: width)
addChild(playerNode)
}
在 func didBeginContact(){}
中我没有任何代码,因为我现在不知道如何处理它。我无法撤消移动,因为我没有跟踪最后一次移动。
您需要更改两件事。第一个是解决玩家穿墙。这是通过在 playerNode
上启用精确的碰撞检测来解决的(只需将其与 physicsBody
配置的其余部分放在一起):
playerNode.physicsBody!.usesPreciseCollisionDetection = true
接下来你需要让你的墙没有动态物理,这将阻止它在你的 playerNode
撞到它时做出反应。你不需要设置wallNode
的mass
,你不会需要它。所以应该添加这样的东西(只需将其与 physicsBody
配置的其余部分放在一起):
wallNode.physicsBody!.dynamic = false