覆盖 SpriteKit 中的碰撞

Posted

技术标签:

【中文标题】覆盖 SpriteKit 中的碰撞【英文标题】:Overriding collisions in SpriteKit 【发布时间】:2015-04-21 10:23:06 【问题描述】:

我想。

我的想法是我有一个在场景中弹跳的球。当 didBeginContact 检测到边缘和球之间的接触时,我希望球以随机的方向和速度反弹。

import SpriteKit


class GameScene: SKScene, SKPhysicsContactDelegate 

let kEdgeCollisionCategory:UInt32 = 0x1 << 1
let kSquareCollisionCategory:UInt32 = 0x1 << 2

override func didMoveToView(view: SKView) 
    /* Setup your scene here */

    // Physics world
    self.physicsWorld.gravity = CGVectorMake(0.0, 0.0)
    self.physicsWorld.contactDelegate = self       

    // Edge
    let frameEdges = SKNode()
    frameEdges.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
    frameEdges.physicsBody?.categoryBitMask = kEdgeCollisionCategory
    self.addChild(frameEdges)

// Sprite
    var sprite = SKSpriteNode(imageNamed: "blue")
    sprite.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(sprite.size.width, sprite.size.height))
    sprite.physicsBody?.restitution = 1.0
    sprite.physicsBody?.linearDamping = 0.0
    sprite.physicsBody?.angularDamping = 0.0
    sprite.physicsBody?.friction = 0.0
    sprite.physicsBody?.dynamic = true
    sprite.physicsBody?.categoryBitMask = kSquareCollisionCategory
    sprite.physicsBody?.collisionBitMask = kEdgeCollisionCategory
    sprite.physicsBody?.contactTestBitMask = kEdgeCollisionCategory
    self.addChild(sprite)




func didBeginContact(contact: SKPhysicsContact) 

    var firstBody:SKPhysicsBody?
    var second:SKPhysicsBody?


    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) 
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    
    else 
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    

    var randomX = CGFloat(arc4random_uniform(UInt32(4))))
    var randomY = CGFloat(arc4random_uniform(UInt32(4))))

    if firstBody!.categoryBitMask == kSquareCollisionCategory && secondBody!.categoryBitMask == kEdgeCollisionCategory 
        firstBody!.velocity = (CGVectorMake(firstBody!.velocity.dx * randomX, firstBody!.velocity.dy * randomY))
    


【问题讨论】:

【参考方案1】:

在接触时,您可以根据球的当前矢量向球施加力或冲量。例如,在接触球时,球的矢量是 (30,-20)。此示例向量转换为向右和向下移动的球。然后,您可以应用一个新矢量,使球向左和向上移动 (-20, 25)。您可以使用arc4random 设置新值或设置静态值。

如果需要,请阅读 using vectors 的物理实体。

【讨论】:

【参考方案2】:

你的问题来了,

 if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) 
    firstBody = contact.bodyA
    secondBody = contact.bodyB

else 
    firstBody = contact.bodyB
    secondBody = contact.bodyA

这意味着第一个主体具有 kEdgeCollisionCategory 的 categoryBitMask,第二个主体具有 kSquareCollisionCategory 的 categoryBitMask。所以把它改成,

 if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) 
    firstBody = contact.bodyB
    secondBody = contact.bodyA

else 
    firstBody = contact.bodyA
    secondBody = contact.bodyB

要获得随机数,请使用这个,

int minSpeed = 1;
int maxSpeed = 20;
int randNum = rand() % (max-min) + min;

然后在所需的身体上施加冲动。

【讨论】:

以上是关于覆盖 SpriteKit 中的碰撞的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit 中的碰撞检测

多层中的 SpriteKit 物理实体碰撞

Spritekit 碰撞

带有 Skview 的 ViewController - SpriteKit SKScene

将父类对象分配给SpriteKit中的继承类对象

在 SpriteKit 项目中包含一个 UIKit 小游戏