未检测到球碰撞和SKSpriteNode(s)碰撞?

时间:2015-07-17 01:03:01

标签: swift sprite-kit

我找不到任何有关我的问题的帮助或解决方案。我有4个SKSpriteNodes:bottomGoalGreen,topGoalGreen,bottomGoalBlue和topGoalBlue。我还有一个名为ball的SKSpriteNode球。我的第一个问题是当我的球碰撞时,例如topGoalGreen或bottomGoalGreen,我希望topGoalGreen被移除以及bottomGoalGreen然后topGoalBlue和bottomGoalBlue出现,反之亦然。我的另一个问题是我的球和碰撞。我有两个SKAction.moveToY,所以球可以在屏幕上上下移动。我想知道SKActions是否是导致碰撞不会发生的原因的罪魁祸首。我希望我改进了我的问题。如果没有,我会再次尝试澄清。

import Foundation
import SpriteKit
import UIKit

struct PhysicsCatagory {

static let bottomGoalGreen : UInt32 = 1
static let topGoalGreen : UInt32 = 2
static let bottomGoalBlue : UInt32 = 4
static let topGoalBlue : UInt32 = 8
static let ball : UInt32 = 16

}

class GamePlayScene: SKScene, SKPhysicsContactDelegate {

var topGoalGreen = SKSpriteNode(imageNamed: "green goal (top).png")
var bottomGoalGreen = SKSpriteNode(imageNamed: "green goal (bottom).png")
var topGoalBlue = SKSpriteNode(imageNamed: "blue goal (top).png")
var bottomGoalBlue = SKSpriteNode(imageNamed: "blue goal (bottom).png")
var ball = SKSpriteNode(imageNamed: "green ball.png")




override func didMoveToView(view: SKView) {
    //setup scene

    physicsWorld.gravity = CGVector.zeroVector
    physicsWorld.gravity = CGVectorMake(0, 0)
    physicsWorld.contactDelegate = self


    self.scene?.backgroundColor = UIColor.blackColor()
    self.scene?.size = CGSize(width: 640, height: 1136)



    //Top goal green code
    topGoalGreen.position = CGPoint (x: self.size.width * 0.5, y: self.size.width * 1.52)
    topGoalGreen.physicsBody = SKPhysicsBody(rectangleOfSize: topGoalGreen.size)
    topGoalGreen.size = CGSize (width: 300, height: 309)

    topGoalGreen.physicsBody?.dynamic = false
    topGoalGreen.physicsBody?.categoryBitMask = PhysicsCatagory.topGoalGreen
    topGoalGreen.physicsBody?.collisionBitMask = 0
    topGoalGreen.physicsBody?.contactTestBitMask = PhysicsCatagory.ball
    self.addChild(topGoalGreen)


    //Bottom goal code
    bottomGoalGreen.position = CGPoint (x: self.size.width * 0.5, y: self.size.width * 0.252)
    bottomGoalGreen.size = CGSize (width: 300, height: 309)

    bottomGoalGreen.physicsBody?.dynamic = false
    bottomGoalGreen.physicsBody?.categoryBitMask = PhysicsCatagory.bottomGoalGreen
    bottomGoalGreen.physicsBody?.contactTestBitMask = PhysicsCatagory.ball

    self.addChild(bottomGoalGreen)


    //Ball code
    ball.position = CGPoint (x: self.size.width * 0.5, y: self.size.width * 0.9)
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.size.width / 2)
    ball.size = CGSize (width: 80, height: 82)

    ball.physicsBody?.dynamic = true
    ball.physicsBody?.categoryBitMask = PhysicsCatagory.ball
    ball.physicsBody?.collisionBitMask = 0
    ball.physicsBody?.contactTestBitMask = PhysicsCatagory.topGoalGreen

    ball.physicsBody?.categoryBitMask = PhysicsCatagory.bottomGoalGreen
    ball.physicsBody?.collisionBitMask = PhysicsCatagory.bottomGoalGreen
    ball.physicsBody?.contactTestBitMask = PhysicsCatagory.bottomGoalGreen

    let moveBallUp = SKAction.moveToY(1040, duration: 2)
    let moveBallDown = SKAction.moveToY(90, duration: 2)
    let moveUpAndDown = SKAction.sequence([moveBallUp, moveBallDown])
    let moveUpAndDownForever = SKAction.repeatActionForever(moveUpAndDown)
    ball.runAction(moveUpAndDownForever)


    self.addChild(ball)


}


func didBeginContact(contact: SKPhysicsContact) {

    var firstBody : SKPhysicsBody = contact.bodyA
    var secondBody : SKPhysicsBody = contact.bodyB

    if (((firstBody.categoryBitMask == PhysicsCatagory.topGoalGreen) && (secondBody.categoryBitMask == PhysicsCatagory.ball)) ||
        ((firstBody.categoryBitMask == PhysicsCatagory.ball) && (secondBody.categoryBitMask == PhysicsCatagory.topGoalGreen))){

            CollisionWithBall(firstBody.node as! SKSpriteNode, ball: secondBody.node as! SKSpriteNode)

            NSLog("Collision!")
    }

}

func CollisionWithBall(topGoalGreen : SKSpriteNode, ball : SKSpriteNode) {


}

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

}

}

2 个答案:

答案 0 :(得分:1)

我弄明白我错过了什么。我错过了SKPhysicsBody的目标和球。感谢其他评论者试图帮助我。

//Top goal green code
    topGoalGreen.position = CGPoint (x: self.size.width * 0.5, y: self.size.width * 1.67)
    topGoalGreen.size = CGSize (width: 400, height: 80)
    topGoalGreen.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize (width: 10, height: 10))
    topGoalGreen.physicsBody?.dynamic = false
    topGoalGreen.physicsBody?.categoryBitMask = PhysicsCatagory.topGoalGreen
    topGoalGreen.physicsBody?.contactTestBitMask = PhysicsCatagory.ball
    self.addChild(topGoalGreen)

答案 1 :(得分:0)

要注册联系人,您应该设置联系代表。

physicsWorld.contactDelegate = self

否则,您无法使用didBeginContact or didEndContact等方法。此外,您必须正确设置类别,接触和碰撞位掩码,以使一切正常工作。所以,接下来的事情就是正确设置类别和联系位掩码。

ball.physicsBody?.categoryBitMask = PhysicsCategory.ball

//Contact will be registered when ball makes a contact with top or bottom goal.
ball.physicsBody?.contactTestBitMask = PhysicsCategory.topGoal |  PhysicsCategory.bottomGoal 

您必须遵循此原则以及顶部和底部目标节点。

rickster查看this great answer以了解在SpriteKit中使用物理引擎时的工作原理。