Mac OS用のスプライトキットに関する非常にシンプルなアプリがあります。(ところで、iOS 用のこのコードは正しく動作しています)。AppDelegate コード:
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のバグですか?