如何在没有物理的情况下检测碰撞
Posted
技术标签:
【中文标题】如何在没有物理的情况下检测碰撞【英文标题】:How to detect collision without physics 【发布时间】:2015-07-24 07:25:08 【问题描述】:我想在不使用 didBeginContact() 函数的情况下检测两个物体何时接触
我尝试使用 CGRectIntersectsRect() 没有任何效果。
class GameScene: SKScene, SKPhysicsContactDelegate
// Player
var _player = SKNode()
var platform = SKNode()
let heroCategory: UInt32 = 1 << 0
let platformCategory: UInt32 = 1 << 1
override func didMoveToView(view: SKView)
/* Setup your scene here */
// Setup
self.anchorPoint = CGPointMake(0.5, 0.5)
self.physicsWorld.gravity = CGVectorMake(0.0, -2.0);
self.physicsWorld.contactDelegate = self
// Start populating
_player = creatPlayer()
self.addChild(_player)
platform = creatPlatform(1, atPosition: CGPoint(x: 0, y: -200))
self.addChild(platform)
let platformTwo = creatPlatform(2, atPosition: CGPoint(x: 0, y: 200))
self.addChild(platformTwo)
func creatPlatform(type: Int, atPosition: CGPoint) -> PlatformNode
let node = PlatformNode()
node.platformType = type
node.position = atPosition
let sprite = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 200, height: 50))
node.addChild(sprite)
node.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
node.physicsBody?.dynamic = false;
node.physicsBody?.categoryBitMask = platformCategory
node.physicsBody?.contactTestBitMask = heroCategory
node.physicsBody?.collisionBitMask = 0;
return node
func creatPlayer() -> SKNode
let playerNode = SKNode()
let sprite = SKSpriteNode(color: UIColor.whiteColor(), size: CGSize(width: 50, height: 50))
playerNode.addChild(sprite)
playerNode.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
playerNode.physicsBody?.dynamic = false
playerNode.physicsBody?.allowsRotation = false
playerNode.physicsBody?.restitution = 1.0
playerNode.physicsBody?.friction = 0.0
playerNode.physicsBody?.angularDamping = 0.0
playerNode.physicsBody?.linearDamping = 0.0
playerNode.physicsBody?.categoryBitMask = heroCategory
playerNode.physicsBody?.contactTestBitMask = platformCategory
playerNode.physicsBody?.collisionBitMask = 0;
return playerNode
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
/* Called when a touch begins */
_player.physicsBody?.dynamic = true
override func update(currentTime: CFTimeInterval)
/* Called before each frame is rendered */
if(CGRectIntersectsRect(platform.frame, _player.frame))
println("Collision")
也许使用 CGRectIntersectsRect 是一种错误的方法,但我可以用它代替吗?
【问题讨论】:
我刚刚测试了你的代码,它可以工作。我只需要将 PlatformNode 修改为 SKSpriteNode 即可运行它。你确定调试区没有打印“碰撞”? 否,但问题是平台框架为 0 是的,这是因为 SKNode 的 frame 属性。您的播放器节点的框架也是 (0,0,0,0) 我添加了描述此行为的答案。 【参考方案1】:框架属性
frame 属性是父坐标系中的一个矩形 包含节点的内容,忽略节点的子节点。
也来自文档:
如果节点的类绘制内容,则框架非空。
因为SKNode 类不执行任何自己的绘图,并且您的平台可能是 SKNode 的子类,而播放器是 SKNode,所以 frame 属性始终为 (0,0,0,0)。
您可以通过以下几种方式访问框架的实际大小:
您可以将播放器和平台设为SKSpriteNode 的子类。 您可以让它们保持原样并访问其中的子 SKSpriteNode。 您可以保持原样并使用calcualteAccumulatedFrame() 方法。关于文档中的 calcualteAccumulatedFrame():
一个节点的累积帧,通过调用 calculateAccumulatedFrame 方法,是最大的矩形 包括节点的框架及其所有后代的框架。
【讨论】:
以上是关于如何在没有物理的情况下检测碰撞的主要内容,如果未能解决你的问题,请参考以下文章