2015-04-22 5 views
1

У меня очень простое приложение для комплекта спрайтов для mac os. (BTW, этот код для iOS работает правильно). AppDelegate код:сделалBeginContact работает абсолютно неправильно swift

import Cocoa 
import SpriteKit 

extension SKNode { 
    class func unarchiveFromFile(file : String) -> SKNode? { 
     if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") { 
     var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)! 
     var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData) 

     archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene") 
     let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene 
     archiver.finishDecoding() 
     return scene 
    } else { 
     return nil 
    } 
} 
} 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 

@IBOutlet weak var window: NSWindow! 
@IBOutlet weak var skView: SKView! 

func applicationDidFinishLaunching(aNotification: NSNotification) { 
    /* Pick a size for the scene */ 
    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene { 
     /* Set the scale mode to scale to fit the window */ 
     scene.scaleMode = .AspectFill 

     self.skView!.presentScene(scene) 

     /* Sprite Kit applies additional optimizations to improve rendering performance */ 
     self.skView!.ignoresSiblingOrder = true 

     self.skView!.showsFPS = true 
     self.skView!.showsNodeCount = true 
    } 
} 

func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool { 
    return true 
} 
} 

И код сцены:

import Foundation 
import SpriteKit 

struct Detection { 
    static var no : UInt32 = 0 
    static var all : UInt32 = UInt32.max 
    static var monster : UInt32 = 0b1 
    static var suric : UInt32 = 0b10 
    static var ninja : UInt32 = 0b100 
} 

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

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


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() 
} 
} 


class GameScene: SKScene, SKPhysicsContactDelegate { 

let player = SKSpriteNode(imageNamed: "player.png") 

override func didMoveToView(view: SKView) { 

    backgroundColor = SKColor.whiteColor() 

    physicsWorld.gravity = CGVectorMake(0.0, 0.0) 
    physicsWorld.contactDelegate = self 
    player.position = CGPoint(x: self.size.width * 0.1, y: self.size.height/2) 
    addChild(player) 


    runAction(SKAction.repeatActionForever(SKAction.sequence([SKAction.runBlock(createMonster), SKAction.waitForDuration(1)]))) 
} 

override func mouseDown(theEvent: NSEvent) { 
    let location = theEvent.locationInNode(self) 

    let suric = SKSpriteNode(imageNamed: "projectile.png") 
    suric.position = player.position 
    suric.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width/2) 
    suric.physicsBody?.categoryBitMask = Detection.suric 
    suric.physicsBody?.collisionBitMask = Detection.no 
    suric.physicsBody?.contactTestBitMask = Detection.monster 
    suric.physicsBody?.usesPreciseCollisionDetection = true 
    suric.physicsBody?.dynamic = true 
    suric.physicsBody?.angularVelocity = -10.0 

    let offset = location - suric.position 

    if offset.x < 0 { 
     return 
    } 

    addChild(suric) 

    let direc = offset.normalized() 
    let shoot = direc * 1000 
    let dest = shoot + suric.position 

    let move = SKAction.moveTo(dest, duration: 2.0) 
    let stop = SKAction.removeFromParent() 
    suric.runAction(SKAction.sequence([move, stop])) 

} 

func suricHit(suric : SKSpriteNode?, monster : SKSpriteNode?) { 
    if suric != nil && monster != nil { 
     suric!.removeFromParent() 
     monster!.removeFromParent() 
    } 
} 

func didBeginContact(contact: SKPhysicsContact) { 
    var first : SKPhysicsBody 
    var second : SKPhysicsBody 
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 
     first = contact.bodyA 
     second = contact.bodyB 
    } 
    else { 
     first = contact.bodyB 
     second = contact.bodyA 
    } 

    if (first.categoryBitMask & Detection.monster != 0) && (second.categoryBitMask & Detection.suric != 0) { 
     suricHit(first.node as? SKSpriteNode, monster: second.node as? SKSpriteNode) 
    } 
} 

func createMonster() { 
    let monster = SKSpriteNode(imageNamed: "monster.png") 

    let y = random(min: monster.size.height/2, size.height - monster.size.height) 
    monster.position = CGPoint(x: self.size.width + monster.size.width/2, y: y) 
    monster.physicsBody = SKPhysicsBody(rectangleOfSize: monster.size, center: CGPoint(x: monster.position.x/2, y: monster.position.y)) 
    monster.physicsBody?.usesPreciseCollisionDetection = true 
    monster.physicsBody?.categoryBitMask = Detection.monster 
    monster.physicsBody?.contactTestBitMask = Detection.suric 
    monster.physicsBody?.collisionBitMask = Detection.no 
    monster.physicsBody?.dynamic = true 
    addChild(monster) 

    let duration = random(min: 2.0, 4.0) 
    let move = SKAction.moveTo(CGPoint(x: -monster.size.width/2, y: y), duration: NSTimeInterval(duration)) 
    let done = SKAction.removeFromParent() 

    monster.runAction(SKAction.sequence([move, done])) 
} 
} 

И функция контакта работает очень странно. Он работает даже без фактического контакта между suric и monster. Я понятия не имею, почему это происходит. Это просто моя ошибка или просто ошибка Xcode?

ответ

1

Ваш физический корпус снаряда слишком велик. Узлы контактируют по физическим телам не с их фактическими размерами.

suric.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width/2) 

размер изменение физического тела к чему-то меньшему

self.size.width/2 

что-то вроде этого

suric.physicsBody = SKPhysicsBody(circleOfRadius: suric.size); 
+0

ой, спасибо, что работал –

+1

при отладке, установите showPhysics = True в вас посмотреть контроллер - он отображает сами физические тела, и вы бы видели, как они касались друг друга. –

Смежные вопросы