碰撞检测Swift

时间:2016-01-20 23:16:53

标签: xcode swift collision detection

我试图制作一个游戏,让蠕虫在屏幕上移动并在每次触摸时旋转并吃掉苹果。我在编码蠕虫和Apple之间的碰撞检测时遇到了困难。我想要它,以便当蠕虫进入Apple的顶部时,Apple节点随机生成其他地方。

这是我的代码:

//
//  GameScene.swift
//  Final Project
//
//  Created by Adam Hackett on 2015-10-22.
//  Copyright (c) 2015 Adam Hackett. All rights reserved.
//

import SpriteKit
import AVFoundation

var movingDirection = "left"

let worm = SKSpriteNode(imageNamed: "worm")
let apple = SKSpriteNode(imageNamed: "Apple")

// vector helper operations
func + (left: CGPoint, right: CGPoint) -> CGPoint {
    return CGPoint(x: left.x + right.x, y: left.y + right.y)
}

func - (left: CGPoint, right: CGPoint) -> CGPoint {
    return CGPoint(x: left.x - right.x, y: left.y - right.y)
}

func * (point: CGPoint, scalar: CGFloat) -> CGPoint {
    return CGPoint(x: point.x * scalar, y: point.y * scalar)
}

func / (point: CGPoint, scalar: CGFloat) -> CGPoint {
    return CGPoint(x: point.x / scalar, y: point.y / scalar)
}

#if !(arch(x86_64) || arch(arm64))
    func sqrt(a: CGFloat) -> CGFloat {
        return CGFloat(sqrtf(Float(a)))
    }
#endif

extension CGPoint {
    func length() -> CGFloat {
        return sqrt(x*x + y*y)
    }

    func normalized() -> CGPoint {
        return self / length()
    }
}

struct PhysicsCategory {
    static let None      : UInt32 = 0
    static let All       : UInt32 = UInt32.max
    static let Apple   : UInt32 = 0b1       // 1
    static let Worm: UInt32 = 0b10      // 2

}




class GameScene: SKScene, SKPhysicsContactDelegate {



    override func didMoveToView(view: SKView) {

        backgroundColor = SKColor.whiteColor()
        //----------------APPLE START-----------------//
        let sizeX = UInt32(CGRectGetMaxX(self.frame))
        let randomX = CGFloat(arc4random_uniform(sizeX))

        let sizeY = UInt32(CGRectGetMaxY(self.frame))
        let randomY = CGFloat(arc4random_uniform(sizeY))

        apple.position = CGPointMake(randomX, randomY)
        addChild(apple)

        let appleCategory: UInt32 = 0x1 << 0
        //------------APPLE FINISH--------------------//



        //------------------WORM START---------------//
        worm.position = CGPointMake(self.size.width/2, self.size.height/2)
        self.addChild(worm)
        let wormCategory: UInt32 = 0x1 << 1
        //-----------------WORM FINISH---------------//


        //PHYSICS
        physicsWorld.gravity = CGVectorMake(0, 0)
        physicsWorld.contactDelegate = self
        worm.physicsBody = SKPhysicsBody(circleOfRadius: worm.size.width/2)
        worm.physicsBody?.dynamic = true
        worm.physicsBody?.categoryBitMask = PhysicsCategory.Worm
        worm.physicsBody?.contactTestBitMask = PhysicsCategory.Apple
        worm.physicsBody?.collisionBitMask = PhysicsCategory.None
        worm.physicsBody?.usesPreciseCollisionDetection = true
        apple.physicsBody = SKPhysicsBody(rectangleOfSize: apple.size) // 1
        apple.physicsBody?.dynamic = true // 2
        apple.physicsBody?.categoryBitMask = PhysicsCategory.Apple // 3
        apple.physicsBody?.contactTestBitMask = PhysicsCategory.Worm // 4
            apple.physicsBody?.collisionBitMask = PhysicsCategory.None // 5

        func projectileDidCollideWithMonster(worm:SKSpriteNode, apple:SKSpriteNode) {
            print("Hit")
            apple.removeFromParent()




        }

        func didBeginContact(contact: SKPhysicsContact) {

            // 1
            var firstBody: SKPhysicsBody
            var secondBody: SKPhysicsBody
            if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
                firstBody = contact.bodyA
                secondBody = contact.bodyB
            } else {
                firstBody = contact.bodyB
                secondBody = contact.bodyA
            }

            // 2
            if ((firstBody.categoryBitMask & PhysicsCategory.Worm != 0) &&
                (secondBody.categoryBitMask & PhysicsCategory.Apple != 0)) {
                    projectileDidCollideWithMonster(firstBody.node as! SKSpriteNode, apple: secondBody.node as! SKSpriteNode)
            }

        }











    }

    func random() -> CGFloat {
        return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
    }

    func random(min min: CGFloat, max: CGFloat) -> CGFloat {
        return random() * (max - min) + min
    }


    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        /* Called when a touch begins */


        // change the direction the object should move
        if (movingDirection == "left") {
            movingDirection = "down"
        }
        else if (movingDirection == "down") {
            movingDirection = "right"
        }
        else if (movingDirection == "right") {
            movingDirection = "up"
        }
        else if (movingDirection == "up") {
            movingDirection = "left"
        }

        print(movingDirection)
        let rotateWorm = SKAction.rotateByAngle(CGFloat(M_PI_2), duration:0.0)
        worm.runAction(rotateWorm)

    }

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

        // need to set it to something for the sequence below
        // so setting it to a nothing action
        var moveWorm:SKAction = SKAction.moveByX(0.0, y: 0.0, duration: 0.0)

        // change the direction the object should move
        if (movingDirection == "left") {
            moveWorm = SKAction.moveByX(-1.0, y: 0.0, duration: 0.01)
        }
        else if (movingDirection == "down") {
            moveWorm = SKAction.moveByX(0.0, y: -1.0, duration: 0.01)
        }
        else if (movingDirection == "right") {
            moveWorm = SKAction.moveByX(1.0, y: 0.0, duration: 0.01)
        }
        else if (movingDirection == "up") {
            moveWorm = SKAction.moveByX(0.0, y: 1.0, duration: 0.01)
        }

        worm.runAction(moveWorm)
        if (worm.position.x < -worm.size.width/2.0 || worm.position.x > self.size.width+worm.size.width/2.0
            || worm.position.y < -worm.size.height/2.0 || worm.position.y > self.size.height+worm.size.height/2.0)
        {
            let reveal = SKTransition.flipHorizontalWithDuration(0.5)
            let gameOverScene = GameOver(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)

        }
    }


}

1 个答案:

答案 0 :(得分:0)

你究竟有什么问题?你需要给你的蠕虫和苹果一个物理身体,而不是检查接触碰撞。一旦发生碰撞,重新生成蠕虫。

你可以阅读这应该有用的内容 http://www.techotopia.com/index.php/A_Swift_iOS_8_Sprite_Kit_Collision_Handling_Tutorial