【问题标题】:Collision detection between sprites won't work精灵之间的碰撞检测不起作用
【发布时间】:2015-04-25 07:00:16
【问题描述】:

我有三个移动精灵。一个是球,一个是线,一个是三角形。当球击中线时,我想做 score++,然后使用 addBall() 函数生成另一个球。当球击中三角形时,我想结束比赛。

下面是我的代码。球直接穿过球和三角形,没有任何碰撞。谁能指出我正确的方向?

import SpriteKit




class GameScene: SKScene, SKPhysicsContactDelegate  {



var center = SKSpriteNode()
var center2 = SKSpriteNode()
var centerLine = SKSpriteNode()
var bg = SKSpriteNode()
var bigCircle = SKSpriteNode()
let counterClockwise = SKAction.rotateByAngle(CGFloat(3.14), duration:1)
let clockwise = SKAction.rotateByAngle(CGFloat(-3.14), duration:1)
var spin = SKAction()
var score = 0
var setCenter = SKAction.rotateByAngle(CGFloat(-1.75), duration:1)
var setCenter2 = SKAction.rotateByAngle(CGFloat(1.75), duration:1)


struct PhysicsCategory {
    static let None       : UInt32 = 0
    static let All        : UInt32 = UInt32.max
    static let ball       : UInt32 = 0x1         // 1
    static let triangle   : UInt32 = 0x1 << 1    // 2
    static let line      : UInt32 = 0x1 << 2    // 4
}









    override func didMoveToView(view: SKView) {

    let value = UIInterfaceOrientation.LandscapeLeft.rawValue
    UIDevice.currentDevice().setValue(value, forKey: "orientation")



//Background
    var bgTexture = SKTexture(imageNamed: "images/bg.png")
    bg = SKSpriteNode(texture:bgTexture)
    bg.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
    bg.zPosition = -4
    self.addChild(center)

//Center Circle
    var bigCircleTexture = SKTexture(imageNamed: "images/bigCircle.png")
    bigCircle = SKSpriteNode(texture:bigCircleTexture)
    bigCircle.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
    self.addChild(bigCircle)
    bigCircle.zPosition = -3
//Center Triangle
    var centerTexture = SKTexture(imageNamed: "center.png")
    center = SKSpriteNode(texture:centerTexture)
    center.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
    center.zPosition = -1
    center.physicsBody = SKPhysicsBody(rectangleOfSize: center.size)
    center.physicsBody?.categoryBitMask = PhysicsCategory.triangle
    self.addChild(center)
    center.runAction(setCenter)
    center.removeAllActions()
    spin = clockwise
    center.runAction(SKAction.repeatActionForever(spin))
//Center Triangle 2
        var centerTexture2 = SKTexture(imageNamed: "center.png")
        center2 = SKSpriteNode(texture:centerTexture)
        center2.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        center2.zPosition = -1
        center2.physicsBody = SKPhysicsBody(rectangleOfSize: center2.size)
        center2.physicsBody?.categoryBitMask = PhysicsCategory.triangle
        self.addChild(center)
        center2.runAction(setCenter2)
        center2.removeAllActions()
        spin = clockwise
        center.runAction(SKAction.repeatActionForever(spin))

//Center Line
        var centerLineTexture = SKTexture(imageNamed: "centerLine.png")
        centerLine = SKSpriteNode(texture:centerLineTexture)
        centerLine.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) + center.size.height)
        centerLine.zPosition = -2
        centerLine.physicsBody = SKPhysicsBody(rectangleOfSize: centerLine.size)
        centerLine.physicsBody?.categoryBitMask = PhysicsCategory.line
        self.addChild(centerLine)
        spin = clockwise
        centerLine.runAction(SKAction.repeatActionForever(spin))

//Create Balls

    //Ball Settings
    func randomCGFloat() -> CGFloat {
            return CGFloat(Double(arc4random())/Double(UInt32.max) )
        }

        var ball = SKSpriteNode(imageNamed: "newBall.png")

        var randomBall = arc4random_uniform(4) + 1
        var moveBall = SKAction.moveTo(CGPointMake(self.size.width/2,self.size.height/2), duration:3.0)
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height / 2)
        ball.physicsBody?.dynamic = false
        ball.physicsBody?.allowsRotation = false
        ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
        ball.physicsBody?.collisionBitMask = PhysicsCategory.triangle
        ball.physicsBody?.contactTestBitMask = PhysicsCategory.triangle
        ball.physicsBody?.collisionBitMask = PhysicsCategory.line

        //Initial Ball
        if score == 0 {
            ball.position = CGPointMake(self.size.width/2, self.size.height)
            self.addChild(ball)
            ball.runAction(moveBall)
        }



        //Spawning and Moving Balls


        func addBall() {


        if randomBall == 1 {
            ball.position = CGPointMake(self.size.width/2, self.size.height)
            self.addChild(ball)
            ball.runAction(moveBall)
        }

        else if randomBall == 2 {
            ball.position = CGPointMake(self.size.width,     self.size.height/2)
            self.addChild(ball)
            ball.runAction(moveBall)
         }

        else if randomBall == 3{
            ball.position = CGPointMake(self.size.width/2, -self.size.height)
            self.addChild(ball)
            ball.runAction(moveBall)
        }

        else if randomBall == 4 {
            ball.position = CGPointMake(self.size.width - self.size.width, self.size.height/2)
            self.addChild(ball)
            ball.runAction(moveBall)
        }

        }



        func didBeginContact(contact: SKPhysicsContact) {
            if contact.bodyA.categoryBitMask == PhysicsCategory.line     {
                score++
                println("\(score)")

            } else if contact.bodyA.categoryBitMask == PhysicsCategory.triangle {
                println("lost")
            }
        }





}







override func touchesBegan(touches: NSSet, withEvent event: UIEvent)     {
    /* Called when a touch begins */
    if spin == clockwise  {
        center.removeAllActions()
        centerLine.removeAllActions()
        spin = counterClockwise



    }

    else {
        center.removeAllActions()
        centerLine.removeAllActions()
        spin  = clockwise

    }
    center.runAction(SKAction.repeatActionForever(spin))
    centerLine.runAction(SKAction.repeatActionForever(spin))
}


override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}
}

【问题讨论】:

    标签: swift sprite collision


    【解决方案1】:

    首先,您需要为每个想要与物理交互的对象(重力、碰撞等)设置一个SKPhysicsBody。您的直线和三角形目前不是这种情况。

    之后,您的(类别位掩码)设置不正确。确实,0 &lt;&lt; 3 是不对的。您可能希望像这样声明您的类别位掩码:

    struct PhysicsCategory {
        static let None       : UInt32 = 0
        static let All        : UInt32 = UInt32.max
        static let Ball       : UInt32 = 0b1       // 1
        static let Triangle   : UInt32 = 0b10      // 2
        static let Line       : UInt32 = 0b100     // 4
    }
    

    或者像这样:

    struct PhysicsCategory {
        static let None       : UInt32 = 0
        static let All        : UInt32 = UInt32.max
        static let Ball       : UInt32 = 0x1         // 1
        static let Triangle   : UInt32 = 0x1 << 1    // 2
        static let Line       : UInt32 = 0x1 << 2    // 4
    }
    

    这是我为another question 制作的表格,它也可能对您的类别位掩码有所帮助: http://goo.gl/7D8EGY

    【讨论】:

    • 感谢您的回复。一切都很有意义,我知道为什么我的代码不起作用,但现在我遇到了一个新问题。当我尝试运行该应用程序时,构建成功但立即失败。我在 AppDeleegate.swift 文件中看到一个黄色图标和一条绿线,突出显示 AppDelegate 类说“信号 SIGBRT”。我的代码如下。我不确定我做错了什么来改变这样的结果。我现在正在尝试自己修复,但感谢其他人的帮助。 pastebin.com/JMb54xJc
    • 您可能希望发布新代码而不是旧代码。 (确保没有错误放置断点)
    • 抱歉 - 在我完成评论之前按了 Enter。我在过去的bin中添加了代码,并且还将更新原始代码
    • 您应该尝试始终保持“干净”的代码。如果您提供的代码是您使用的代码,那么您无缘无故地在函数内部具有函数。 A 试图稍微清理一下(pastebin.com/128j2NQz),但我看不出它是否有任何错误。而且,为什么需要在 UIDevice 上设置方向?
    • 尝试使用我在上面评论中提供的代码(在编译之前可能有一些错误需要清理)。如果它不起作用,我可能稍后再看一下,但如果可能的话,你必须上传项目(这样我才能编译(所有文件、图像……)。
    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多