Sprite 套件中的 SKShapeNode 碰撞检测未检测到碰撞
Posted
技术标签:
【中文标题】Sprite 套件中的 SKShapeNode 碰撞检测未检测到碰撞【英文标题】:SKShapeNode collision detection in Sprite kit not detecting collision 【发布时间】:2019-01-28 20:09:13 【问题描述】:我正在尝试实现SKShapeNode
(圆形节点)和SKShapeNode
(方形节点)之间的碰撞检测,就像应用程序“Snake VS Blocks”一样。
以下是我的节点创建的代码 sn-p
蛇创造
private func addSnake()
snake = SKShapeNode(circleOfRadius: Constants.snakeRadius)
snake.fillColor = Constants.snakeColor
let snakeXPosition = (Helper.getScreenWidth() / 2.0) - Constants.snakeRadius
snake.position = CGPoint(x: snakeXPosition, y: size.height * 0.3)
snake.physicsBody = SKPhysicsBody(rectangleOf: snake.frame.size)
snake.physicsBody?.isDynamic = false
snake.physicsBody?.categoryBitMask = PhysicsCategory.snake
snake.physicsBody?.contactTestBitMask = PhysicsCategory.block
snake.physicsBody?.collisionBitMask = PhysicsCategory.none
snake.name = "Snake"
addChild(snake)
块创建
func addBlocks()
for index in 0...(blockCount-1)
let hasBlock = getRandomBool()
if hasBlock
let block = getBlock(for: index)
block.fillColor = .red
addChild(block)
let actionMove = getBlockMoveAction(for: block, atIndex: index)
let actionMoveDone = SKAction.removeFromParent()
block.run(SKAction.sequence([actionMove, actionMoveDone]))
func getBlockMoveAction(for block: SKShapeNode, atIndex: Int) -> SKAction
return SKAction.move(to: CGPoint(x: CGFloat(atIndex) * width, y: -block.frame.size.height),
duration: TimeInterval(blockMovementDuration))
func getBlock(for index: Int) -> SKShapeNode
let rect = CGRect(x: 0, y: 0, width: width, height: width)
let block = SKShapeNode(rect: rect, cornerRadius: Constants.blockCornerRadius)
block.name = "Block"
block.position = CGPoint(x: CGFloat(index) * width, y: (Helper.getScreenHeight() + width))
block.physicsBody = SKPhysicsBody(rectangleOf: block.frame.size)
block.physicsBody?.isDynamic = false
block.physicsBody?.categoryBitMask = PhysicsCategory.block
block.physicsBody?.contactTestBitMask = PhysicsCategory.snake
block.physicsBody?.collisionBitMask = PhysicsCategory.none
return block
func getRandomBool() -> Bool
return arc4random_uniform(2) == 0
下面是上述代码的结果图片:
我的第一个问题是,我不知道为什么,但是当我启用时,skview 显示物理,
view.showsPhysics = true
我发现我的视图不在正确的框架中
其次,我已经确认联系代表了
physicsWorld.contactDelegate = self
但是我的
didBegin(_ contact: SKPhysicsContact)
没有被触发
碰撞检测代码:
extension GameScene: SKPhysicsContactDelegate
func didBegin(_ contact: SKPhysicsContact)
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask
firstBody = contact.bodyA //snake
secondBody = contact.bodyB //block
else
firstBody = contact.bodyB //block
secondBody = contact.bodyA //snake
if ((firstBody.categoryBitMask & PhysicsCategory.snake != 0) &&
(secondBody.categoryBitMask & PhysicsCategory.block != 0))
if let snake = firstBody.node as? SKShapeNode,
let block = secondBody.node as? SKShapeNode
snakeDidCollideWithBlock(snake: snake, block: block)
func snakeDidCollideWithBlock(snake: SKShapeNode, block: SKShapeNode)
print("Hit")
block.removeFromParent()
我在***中搜索了类似问题的其他问题,但没有找到任何解决方案。
【问题讨论】:
【参考方案1】:“isDynamic”中的一个或两个都应该为真。否则,它们将表现得像一堵墙,从不参与物理模拟。
【讨论】:
这很快..我忘了我把两个身体都设置为动态假。你能告诉我为什么我的块的框架有一些偏移,而不是你在上图中看到的应该是什么。 静止物理体的框架和节点的框架有不同的锚点。一个在节点的中心(0.5,0.5),另一个在一个顶点(0,0)。如果物理体在模拟中,物理世界引擎会修正它的位置以匹配节点,你不会注意到差异。以上是关于Sprite 套件中的 SKShapeNode 碰撞检测未检测到碰撞的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Sprite Kit 中使用圆形(SKShapeNode)作为蒙版?
绕过子类中的Initialization:Swift和SpriteKit