所以我在游戏中对球进行了一些调整,并且为了避免解包可选值错误,我将以下内容进行了修改
//didMoveToView
self.physicsWorld.gravity = CGVectorMake(0, 0)
self.physicsWorld.contactDelegate = self
let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
self.physicsBody = fieldBody
self.physicsBody!.affectedByGravity = false
self.physicsBody!.usesPreciseCollisionDetection = true
self.physicsBody!.dynamic = true
self.physicsBody!.mass = 0
self.physicsBody!.friction = 0
self.physicsBody!.linearDamping = 0
self.physicsBody!.angularDamping = 0
self.physicsBody!.restitution = 1
self.physicsBody!.categoryBitMask = CollisionTypes.Floor.rawValue
self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue
// Prepare the ball - physics engine.
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
ball.physicsBody!.affectedByGravity = true
ball.physicsBody!.restitution = 0.8
ball.physicsBody!.linearDamping = 0
ball.physicsBody!.friction = 0.3
ball.physicsBody!.dynamic = true
ball.physicsBody!.mass = 0.5
ball.physicsBody!.allowsRotation = true
ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
ball.physicsBody!.contactTestBitMask = CollisionTypes.Floor.rawValue
ball.physicsBody!.collisionBitMask = CollisionTypes.Floor.rawValue
}
我做到了,我的游戏开始了,但是只要toucheBegan,就会出现同样的错误。我不知道如何解决所有这些无休止的错误。我是新手,不知道如何调整物理。我的contactBegin看起来像这样:
func didBeginContact(contact: SKPhysicsContact) {
let bitMaskAAndB = contact.bodyA.categoryBitMask == CollisionTypes.Floor.rawValue &&
contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue
let ballAndBoardMask = CollideType.Ball.toMask() | boards.usedCollideMasks
// ball and board, handle it by board delegate
if bitMaskAAndB | ballAndBoardMask == ballAndBoardMask {
let boardNode: SKNode! = contact.bodyA.categoryBitMask == CollideType.Ball.toMask() ? contact.bodyB.node : contact.bodyA.node
let board = boardNode.bind as! BoardDelegate
board.didBeginContact(boardNode, ball: ball, contact: contact, game: self)
}
// ball and ceil => stop game
else if bitMaskAAndB == CollideType.toMask([.Ball, .Ceil]) {
stopGame()
}
// ball and floor => stop game add explosion or fall off screen
else if bitMaskAAndB == CollideType.toMask([.Ball, .Floor]) {
stopGame()
}
}
func didEndContact(contact: SKPhysicsContact) {
let ballAndBoardMask = CollideType.Ball.toMask() | boards.usedCollideMasks
// ball and board, handle it by board delegate
if contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask | ballAndBoardMask == ballAndBoardMask {
let boardNode: SKNode! = contact.bodyA.categoryBitMask == CollideType.Ball.toMask() ? contact.bodyB.node : contact.bodyA.node
let board = boardNode.bind as! BoardDelegate
board.didEndContact(boardNode, ball: ball, contact: contact, game: self)
}
}
编辑:我根据您提出的建议设置了我的物理世界并调整了我的didBeginContact乐趣,但是使用以下代码,我收到了多个错误:无法将bool类型的值转换为UInt32。
PS。谢谢你的帮助和耐心,这是所有新的术语,我尽我所能去理解。 :)
答案 0 :(得分:2)
我不知道您的CollideType
课程或声明,因此下面的代码向您解释如何构建正确的physicsWorld
和physicsBody
以及不具备碰撞期间的问题。
但首先:我们将在这个项目中充分利用 categoryBitMask , contactTestBitMask 和 collisionBitMask 属性,因为我们有非常精确的规则使项目有效:
categoryBitMask 是一个数字,用于定义此对象的类型 考虑碰撞。
collisionBitMask 是一个定义对象类别的数字 节点应该碰撞。
contactTestBitMask 是一个数字,用于定义我们想要的冲突 收到通知。
SpriteKit希望使用UInt32
描述这些三位掩码。您的位掩码应该从1开始,然后每次加倍。
代码:
class GameScene: SKScene, SKPhysicsContactDelegate {
var ball: Ball!
let ballSpeedX = CGFloat(500)
enum CollisionTypes: UInt32 {
case Field = 1
case Ball = 2
}
override func didMoveToView(view: SKView) {
// ball
ball = Ball(imageNamed:"colorBall.png")
ball.position = CGPointMake(self.ball.frame.size.width,self.ball.frame.size.height)
// Prepare the world - physics engine.
self.physicsWorld.gravity = CGVectorMake(0, -6)
self.physicsWorld.contactDelegate = self
let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
self.physicsBody = fieldBody
self.physicsBody!.affectedByGravity = false
self.physicsBody!.usesPreciseCollisionDetection = true
self.physicsBody!.dynamic = true
self.physicsBody!.mass = 0
self.physicsBody!.friction = 0
self.physicsBody!.linearDamping = 0
self.physicsBody!.angularDamping = 0
self.physicsBody!.restitution = 1
self.physicsBody!.categoryBitMask = CollisionTypes.Field.rawValue
self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue
// Prepare the ball - physics engine.
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
ball.physicsBody!.affectedByGravity = true
ball.physicsBody!.restitution = 0.8
ball.physicsBody!.linearDamping = 0
ball.physicsBody!.friction = 0.3
ball.physicsBody!.dynamic = true
ball.physicsBody!.mass = 0.5
ball.physicsBody!.allowsRotation = true
ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
ball.physicsBody!.contactTestBitMask = CollisionTypes.Field.rawValue
ball.physicsBody!.collisionBitMask = CollisionTypes.Field.rawValue
//ball.physicsBody!.categoryBitMask = CollideType.Ball.toMask()
//ball.physicsBody!.collisionBitMask = CollideType.toMask([.Scene, .Ceil, .Floor]) | boards.usedCollideMasks
//ball.physicsBody!.contactTestBitMask = CollideType.toMask([.Scene, .Ceil, .Floor]) | boards.usedCollideMasks
ball.hidden = false
self.addChild(ball)
}
func didBeginContact(contact: SKPhysicsContact) {
if (contact.bodyA.categoryBitMask == CollisionTypes.Field.rawValue &&
contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue) {
print("contact between field and ball")
}
}
}
正如您所看到的,第一件重要的事情是准备physicsWorld(跟踪物理必须工作的边界),为其分配一个类别,所有其他参数需要与其他对象进行交互。然后你构建你的对象的physicsBody,在这种情况下是球。