Reputation: 449
I have a title screen on a game I'm trying to learn making and want to add a feature that responds to a user shaking. The function works when put standalone but not on this page. By not working I mean it appears to do nothing (won't even print to the logs).
The function in question is motionEnded func.
import SpriteKit
import AVFoundation
import iAd
class GameScene: SKScene {
//loud soundfiles
var titleMusic = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Loping Sting", ofType: "mp3")!)
var audioPlayer = AVAudioPlayer()
let playButton = SKSpriteNode(imageNamed: "PlayNow")
let titleScreen = SKSpriteNode(imageNamed: "Title")
let titleOrange = SKSpriteNode(imageNamed: "hero")
override func didMoveToView(view: SKView) {
//stop music from game
musicPlayer.stop()
//play sound file
audioPlayer = AVAudioPlayer(contentsOfURL: titleMusic, error: nil)
audioPlayer.prepareToPlay()
audioPlayer.play()
self.titleScreen.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.playButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 100)
self.addChild(self.titleScreen)
self.addChild(self.playButton)
//animate button
let pulseUp = SKAction.scaleTo(1.1, duration: 0.9)
let pulseDown = SKAction.scaleTo(0.7, duration: 0.9)
let pulse = SKAction.sequence([pulseDown, pulseUp])
let repeatPulse = SKAction.repeatActionForever(pulse)
self.playButton.runAction(repeatPulse)
//show hero
titleOrange.position = CGPointMake(CGRectGetMidX(self.frame), 363)
self.addChild(titleOrange)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == self.playButton {
var scene = PlayScene(size: self.size)
let skView = self.view as SKView?
scene.scaleMode = .ResizeFill
scene.size = skView!.bounds.size
skView?.presentScene(scene)
}
}
}
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) {
if motion == .MotionShake {
println("Shake")
}
}
override func update(currentTime: CFTimeInterval) {
}
}
Upvotes: 0
Views: 327
Reputation: 37053
Since you had it working previously, I presume you have applicationSupportsShakeToEdit
set to true
(this is the default anyway).
You then need to ensure that your scene GameScene
becomes the first responder - the first responder will (as the name implies) be the first to be given the opportunity to respond to motion events, and after that it progresses up the responder chain. SKScene
conforms to the UIResponder
protocol, so you just need to allow it to become first responder by overriding a method, and then call a couple of responder methods when the scene appears/disappears:
override func canBecomeFirstResponder() -> Bool {
return true
}
override func didMoveToView(view: SKView) {
// ...
becomeFirstResponder()
}
override func willMoveFromView(view: SKView) {
// ...
resignFirstResponder()
}
Note that making your scene the first responder may affect other event handling code elsewhere in your app, depending on your app's structure.
Upvotes: 1