I have this timer and it starts at 3 and it should countdown to 0 but it stops at 2. I don't get why it doesn't go all they way down to 0. Can you please let me know what Im doing wrong with my code. Thank you!
class GameScene: SKScene, SKPhysicsContactDelegate {
var timerToStartGame = 3
var timerCountDownLabel: SKLabelNode! = SKLabelNode()
override func didMoveToView(view: SKView) {
timerCountDownLabel = SKLabelNode(fontNamed: "TimeBurner")
timerCountDownLabel.fontColor = UIColor.whiteColor()
timerCountDownLabel.zPosition = 40
timerCountDownLabel.fontSize = 60
timerCountDownLabel.position = CGPointMake(self.size.width / 2.4, self.size.height / 1.5)
self.addChild(timerCountDownLabel)
var clock = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("countdown"), userInfo: nil, repeats: true)
}
func countdown() {
timerCountDownLabel.text = String(timerToStartGame--)
if timerToStartGame == 0 {
doAction()
}
}
}
The problem occurs because you decrease it after displaying using -- after the var. Move it to the front and start from 4.
timerCountDownLabel.text = String(--timerToStartGame)
Related
I just started learning programming and the instructor asked us to make an egg timer app.
I tried to run her example solution but XCode shows an issue with the code at #selector(updateTimer). The error says Use of local variable 'updateTimer' before its declaration.
This is the code:
class ViewController: UIViewController {
#IBOutlet weak var progress: UILabel!
let eggTimes = ["Soft" :3, "Medium":4, "Hard":6]
var secondsRemaining = 60
var timer = Timer()
#IBAction func hardnessSelected(_ sender: UIButton) {
timer.invalidate()
let hardness = sender.currentTitle!
secondsRemaining = eggTimes[hardness]!
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector:
#selector(updateTimer), userInfo: nil, repeats: true)
func updateTimer() {
if secondsRemaining > 0 {
print("\(secondsRemaining) seconds left to finish")
secondsRemaining -= 1
}
else {
timer.invalidate()
progress.text = "DONE"
}
}
}
}
The issue you're having is that the func updateTimer is declared under the #selector and as such isn't "available yet" to put it simply. What you probably wanted is to move the function outside the hardnessSelected as such:
class ViewController: UIViewController {
#IBOutlet weak var progress: UILabel!
let eggTimes = ["Soft" :3, "Medium":4, "Hard":6]
var secondsRemaining = 60
var timer = Timer()
#IBAction func hardnessSelected(_ sender: UIButton) {
self.timer.invalidate()
let hardness = sender.currentTitle!
self.secondsRemaining = self.eggTimes[hardness]!
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateTimer), userInfo: nil, repeats: true)
}
#objc func updateTimer() {
if self.secondsRemaining > 0 {
print("\(self.secondsRemaining) seconds left to finish")
self.secondsRemaining -= 1
}
else {
self.timer.invalidate()
self.progress.text = "DONE"
}
}
}
You also need to add #objc in front of the function name to expose it to ObjC runtime. You can read more about that here.
I am building a game for iOS for the first time. I am very close, however I got collision detection working early then I changed something and I lost it working. I have tried to get in back but haven't work. This is what I have so far, but nothing working. I am trying different versions of collision detection that I have found online but I am sticking to get this one to work. Just don't understand where I have went wrong.
Thank you in advanced.
import SpriteKit
enum ColliderType: UInt32 {
case Player = 1
case Traffic = 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
createWalls()
self.backgroundColor = SKColor.whiteColor()
self.physicsWorld.gravity = CGVectorMake(0, 0)
player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size)
player.physicsBody?.dynamic = true
player.physicsBody!.categoryBitMask = ColliderType.Player.rawValue
player.physicsBody!.contactTestBitMask = ColliderType.Traffic.rawValue
player.zPosition = 3
player.name = "player"
player.position = CGPoint(x: self.frame.midX, y: (self.frame.midY)/3)
player.setScale(1.0)
self.addChild(player)
_ = NSTimer.scheduledTimerWithTimeInterval(2.5, target: self, selector: #selector(GameScene.makeTraffic), userInfo: nil, repeats: true)
}
func makeTraffic(){
var aNumber = Int(arc4random_uniform(2))
let Pos1 = Int(self.frame.midX/2)+30
let Pos2 = Int((self.frame.size.width)/2)
let Pos3 = Int(self.frame.size.width-300)
let array = [Pos1, Pos2, Pos3]
let randomIndex = Int(arc4random_uniform(UInt32(array.count)))
let randomPOS = CGPoint(x:Int(array[randomIndex]), y:Int(self.frame.height))
if aNumber == 0 {
aNumber = aNumber + 1
}
switch aNumber {
case 1:
let car1 = SKSpriteNode(imageNamed: "Car_Green_Front")
car1.position = randomPOS
car1.zPosition = 3
car1.setScale(1.0)
car1.physicsBody = SKPhysicsBody(rectangleOfSize: car1.size)
car1.physicsBody?.dynamic = true
car1.physicsBody!.categoryBitMask = ColliderType.Player.rawValue
car1.physicsBody!.contactTestBitMask = ColliderType.Traffic.rawValue
self.addChild(car1)
case 2:
let car2 = SKSpriteNode(imageNamed: "Car_Purple_Front")
car2.position = randomPOS
car2.zPosition = 3
car2.setScale(1.0)
car2.physicsBody = SKPhysicsBody(rectangleOfSize: car2.size)
car2.physicsBody?.dynamic = true
car2.physicsBody!.categoryBitMask = ColliderType.Traffic.rawValue
car2.physicsBody!.contactTestBitMask = ColliderType.Player.rawValue
self.addChild(car2)
default:
return
}
}
func createWalls(){
let wallSize = CGSize(width: 5, height: self.frame.size.height)
let rightwall = SKShapeNode(rectOfSize: wallSize)
rightwall.physicsBody = SKPhysicsBody(rectangleOfSize: wallSize)
rightwall.physicsBody!.dynamic = false
rightwall.position = CGPoint(x: self.frame.maxX-300, y: self.frame.size.height/2)
rightwall.fillColor = UIColor.clearColor()
self.addChild(rightwall)
let leftwall = SKShapeNode(rectOfSize: wallSize)
leftwall.physicsBody = SKPhysicsBody(rectangleOfSize: wallSize)
leftwall.physicsBody!.dynamic = false
leftwall.position = CGPoint(x: self.frame.minX+300, y: self.frame.size.height/2)
leftwall.fillColor = UIColor.clearColor()
self.addChild(leftwall)
}
func didBeginContact(contact: SKPhysicsContact) {
print("Contact")
if contact.bodyA.categoryBitMask == ColliderType.Traffic.rawValue && contact.bodyB.categoryBitMask == ColliderType.Player.rawValue {
print("Hi")
} else {
print("Hello") }
}
}
Your code seems alrite, although there is some small changes I would make.
1) I would write my collider types like so
struct ColliderType {
static let player: UInt32 = 0x1 << 0
static let traffic: UInt32 = 0x1 << 1
}
because this way you only need to increment the last number by 1.
Your way if you decide to add more categories the next one would have to be 4, than 8, than 16 etc, which is more confusing (you are dealing with 32 bit integers)
Than use it like so
...categoryBitMask = ColliderType.player
2) It is recommended that you give the sprite the position before adding the physicsBody. You are doing it the other way round which could cause unexpected issues.
3) Change your collision method to this
func didBeginContact(contact: SKPhysicsContact) {
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
}
if (firstBody.categoryBitMask == ColliderType.player) && (secondBody.categoryBitMask == ColliderType.traffic) {
// player hit traffic, do something
}
}
4) Finally the most important part is that you need to set the delegate which I couldn't see in your code.
Call this in DidMoveToView
physicsWorld.contactDelegate = self
otherwise the DidBeginContact method will never fire.
Also it is a good idea if you follow apples naming conventions. So only classes, protocols, enums and structs should start with capital letters.
Hope this helps
A cleaner way to code didBeginContact is:
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
case ColliderType.player | ColliderType.traffic:
// player and traffic have contacted
print("Collision between player and traffic")
default :
//Some other contact has occurred
print("Some other contact")
}
}
You can add as many case ColliderType.object1 | ColliderType.object2: as you like.
I am following a tutorial written in Swift 2 for Xcode 7, part 1 of which (you can navigate to part IV, where my issue has come up) is here: http://www.mav3r1ck.io/spritekit-with-swift/
I am using my own sprites in place of those in the tutorial. When I run my code, an error appears on the first line of the following
let spawnRandomHead = SKAction.runBlock(spawnHead)
let waitTime = SKAction.waitForDuration(1.0)
let sequence = SKAction.sequence([spawnRandomHead,waitTime])
runAction(SKAction.repeatActionForever(sequence))
The full code is here:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
enum bitMask: UInt32 {
case defender = 1
case head = 2
case frame = 4
}
let defender = SKSpriteNode(imageNamed: "Ivanovic is a boss")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
backgroundColor = UIColor.blueColor()
defender.position = CGPoint(x: frame.size.width / 2, y:frame.size.height / 2)
defender.physicsBody = SKPhysicsBody(texture: defender.texture!, size: defender.frame.size)
defender.physicsBody?.dynamic = false
defender.physicsBody?.affectedByGravity = false
defender.physicsBody?.allowsRotation = false
defender.physicsBody?.categoryBitMask = bitMask.head.rawValue
defender.physicsBody?.contactTestBitMask = bitMask.head.rawValue
defender.physicsBody?.collisionBitMask = 0
addChild(defender)
let spawnRandomHead = SKAction.runBlock(spawnHead)
let waitTime = SKAction.waitForDuration(1.0)
let sequence = SKAction.sequence([spawnRandomHead,waitTime])
runAction(SKAction.repeatActionForever(sequence))
physicsWorld.contactDelegate = self
physicsWorld.gravity = CGVectorMake(0.0, -0.9)
defender.physicsBody?.contactTestBitMask = bitMask.frame.rawValue
defender.physicsBody?.collisionBitMask = bitMask.frame.rawValue
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first! as UITouch
let touchLocation = touch.locationInNode(self)
//print(touchLocation)
let moveTo = SKAction.moveTo(touchLocation, duration: 1.0)
defender.runAction(moveTo)
func randomNumber(min min: CGFloat, max: CGFloat) -> CGFloat {
let random = CGFloat(Float(arc4random()) / 0xFFFFFFFF)
return random * (max - min) + min
}
func spawnHead() {
let head = SKSpriteNode(imageNamed: "The Biter Strikes")
head.position = CGPoint(x: frame.size.width * randomNumber(min: 0, max: 1), y: frame.size.height + head.size.height)
head.physicsBody = SKPhysicsBody(texture: head.texture!, size: head.frame.size)
head.physicsBody?.categoryBitMask = bitMask.head.rawValue
head.physicsBody?.contactTestBitMask = bitMask.defender.rawValue
addChild(head)
}
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask) {
case bitMask.defender.rawValue | bitMask.head.rawValue:
let secondNode = contact.bodyB.node
secondNode?.physicsBody?.allowsRotation = true
let firstNode = contact.bodyA.node
firstNode?.physicsBody?.allowsRotation = true
firstNode?.removeFromParent()
default:
return
}
}
}
}
I have tried cleaning & rebuilding, restarting Xcode, and moving sections of the code around, but the error does not go away. I appreciate your support!
Hmm. Tried both. Now on the second line this
let spawnRandomHead = SKAction.runBlock({ [unowned self] () -> Void in
self.spawnHead()
})
let waitTime = SKAction.waitForDuration(1.0)
let sequence = SKAction.sequence([spawnRandomHead,waitTime])
runAction(SKAction.repeatActionForever(sequence))
a new error pops up saying " Value of type 'GameScene' has no member 'spawnHead' ".
The runBlock requires closure as an argument, so replace
let spawnRandomHead = SKAction.runBlock(spawnHead)
with
let spawnRandomHead = SKAction.runBlock({ [unowned self] () -> Void in
self.spawnHead()
})
or simply
let spawnRandomHead = SKAction.runBlock { [unowned self] in
self.spawnHead()
}
I'm trying to make a stopwatch, and I can't seem to understand why I am getting a sigabrt with my application. Sorry I didn't know what to include, so I included everything.
var timer = NSTimer()
var minutes: Int = 0
var seconds: Int = 0
var fractions: Int = 0
var startStopWatch: Bool = true
var StopwatchString: String = ""
#IBOutlet weak var display: UILabel!
#IBAction func start(sender: UIButton) {
if startStopWatch == true {
NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateStopwatch"), userInfo: nil, repeats: true)
startStopWatch = false
} else {
timer.invalidate()
startStopWatch = true
}
}
#IBAction func reset(sender: UIButton) {
}
override func viewDidLoad() {
super.viewDidLoad()
display.text = "00:00.00"
}
func updateStopWatch() {
fractions += 1
if fractions == 100 {
seconds += 1
fractions = 0
}
if seconds == 60 {
minutes += 1
seconds = 0
}
let fractionsString = fractions > 9 ? "\(fractions)" : "0\(fractions)"
let secondsString = seconds > 9 ? "\(seconds)" : "0\(seconds)"
let minutesString = minutes > 9 ? "\(minutes)" : "0\(minutes)"
StopwatchString = "\(minutesString):\(secondsString).\(fractionsString)"
display.text = StopwatchString
}
I cut and pasted your code into a project and when I tapped the start button the first line of the error message said:
-[My.ViewController updateStopwatch]: unrecognized selector sent to instance 0x7fe0034b3520
That tells you all you need to know. You send the updateStopwatch message to your view controller but it doesn't implement that method. I noticed though that your ViewController does implement an updateStopWatch method. Looks like a basic capitalization error to me.
Always, always, always, read at least the first line of the error message.
Here are some fixes:
+I changed the timer variable initially to nil - it will be saved in the start function.
+Your if statement in the start function looked like this:
if startStopWatch == true
But it should be like this:
if (startStopWatch)
Hope this helpes :)
var timer = nil
var minutes = 0
var seconds = 0
var fractions = 0
var startStopWatch = true
var StopwatchString = ""
#IBOutlet weak var display: UILabel!
#IBAction func start(sender: UIButton) {
if (startStopWatch == true) {
timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateStopwatch"), userInfo: nil, repeats: true)
startStopWatch = false
//I added one thing. If the start button is pushed the text will change to stop. You can change this if you like.
sender.setTitle("Stop", forState: .Normal)
//
} else {
timer.invalidate()
startStopWatch = true
}
}
#IBAction func reset(sender: UIButton) {
display.text! = "00:00.00"
}
override func viewDidLoad() {
super.viewDidLoad()
display.text! = "00:00.00"
}
func updateStopWatch() {
fractions++
if (fractions == 100) {
seconds++
fractions = 0
}
if (seconds == 60) {
minutes++
seconds = 0
}
var fractionsString = fractions > 9 ? "\(fractions)" : "0\(fractions)"
var secondsString = seconds > 9 ? "\(seconds)" : "0\(seconds)"
var minutesString = minutes > 9 ? "\(minutes)" : "0\(minutes)"
StopwatchString = "\(minutesString):\(secondsString).\(fractionsString)"
display.text! = StopwatchString
}
I have a restartButton that must appear when two bodies collide and when it happens for the first time, all goes great - bodies collide--> restartButton appears--> I restart level by touching restartButton.
It was a "good, right restart" And here problem starts...
After level been restarted, if I touch at center of the screen(where restartButton must appear when is called) game crashes, saying following:
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: name:'(null)' particleTexture: 'enemyPart.png' (100 x 100) position:{721.33929, 175.39999} accumulatedFrame:{{inf, inf}, {inf, inf}}'
** First throw call stack:
(0x2a0fa137 etc.)
libc++abi.dylib: terminating with uncaught exception of type NSException"
but restartButton is invisible and it couldn't even be there because no bodies have collided.
If after that "good restart" some enemy collide with player, restartButton appears for a moment and player, enemy1, enemy2, enemy3 are fadingOut from scene.
I would appreciate if someone can help
Here is code where you can see all that stuff:
import SpriteKit
import UIKit
let player = SKEmitterNode(fileNamed: "playerPart.sks")
let enemy1 = SKEmitterNode(fileNamed: "ePart.sks")
let enemy2 = SKEmitterNode(fileNamed: "ePart.sks")
let enemy3 = SKEmitterNode(fileNamed: "ePart.sks")
let restartButton = SKSpriteNode(imageNamed: "restartButton")
let playerCat: UInt32 = 0x1 << 0
let enemyCat: UInt32 = 0x1 << 1
class Level2: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
physicsWorld.contactDelegate = self
initWorld()
movements()
player.physicsBody = SKPhysicsBody(circleOfRadius: 50)
player.position = CGPointMake(819.2 , 693.8)
player.zPosition = 1
player.physicsBody?.categoryBitMask = playerCat
player.physicsBody?.contactTestBitMask = enemyCat
player.targetNode = self
self.addChild(player)
enemy1.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(102, 102))
enemy1.position = CGPointMake(819.2, 175.4)
enemy1.zPosition = 1
enemy1.physicsBody?.affectedByGravity = false
enemy1.physicsBody?.dynamic = true
enemy1.physicsBody?.allowsRotation = false
enemy1.physicsBody?.categoryBitMask = enemyCat
enemy1.physicsBody?.contactTestBitMask = playerCat
enemy1.physicsBody?.collisionBitMask = 0x0
enemy1.targetNode = self
enemy1.particleBirthRate = 150
enemy1.particleLifetime = 10
enemy1.particleLifetimeRange = 20
enemy1.particlePositionRange = CGVectorMake(50, 60)
enemy1.emissionAngle = 0
enemy1.emissionAngleRange = 0
enemy1.particleSpeed = 0
enemy1.particleSpeedRange = 0
enemy2.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(102, 102))
enemy2.position = CGPointMake(614.4, 386.6)
enemy2.zPosition = 1
enemy2.physicsBody?.affectedByGravity = false
enemy2.physicsBody?.dynamic = true
enemy2.physicsBody?.allowsRotation = false
enemy2.physicsBody?.categoryBitMask = enemyCat
enemy2.physicsBody?.contactTestBitMask = playerCat
enemy2.physicsBody?.collisionBitMask = 0x0
enemy2.targetNode = self
enemy2.particleBirthRate = 150
enemy2.particleLifetime = 10
enemy2.particleLifetimeRange = 20
enemy2.particlePositionRange = CGVectorMake(50, 60)
enemy2.emissionAngle = 0
enemy2.emissionAngleRange = 0
enemy2.particleSpeed = 0
enemy2.particleSpeedRange = 0
enemy3.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(102, 102))
enemy3.position = CGPointMake(409.6, 181.8)
enemy3.zPosition = 1
enemy3.physicsBody?.affectedByGravity = false
enemy3.physicsBody?.dynamic = true
enemy3.physicsBody?.allowsRotation = false
enemy3.physicsBody?.categoryBitMask = enemyCat
enemy3.physicsBody?.contactTestBitMask = playerCat
enemy3.physicsBody?.collisionBitMask = 0x0
enemy3.targetNode = self
enemy3.particleBirthRate = 150
enemy3.particleLifetime = 10
enemy3.particleLifetimeRange = 20
enemy3.particlePositionRange = CGVectorMake(50, 60)
enemy3.emissionAngle = 0
enemy3.emissionAngleRange = 0
enemy3.particleSpeed = 0
enemy3.particleSpeedRange = 0
func initWorld() {
self.addChild(enemy1)
self.addChild(enemy2)
self.addChild(enemy3)
}
func movements() {
let move11 = SKAction.moveTo(CGPointMake(819.2, 386.6), duration: 1.5)
let move12 = SKAction.moveTo(CGPointMake(614.4, 386.6), duration: 1.5)
let move13 = SKAction.moveTo(CGPointMake(614.4, 175.4), duration: 1.5)
let move14 = SKAction.moveTo(CGPointMake(819.2, 175.4), duration: 1.5)
let enemy1m = SKAction.sequence([move11, move12, move13, move14])
let enemy1move = SKAction.repeatActionForever(enemy1m)
let move21 = SKAction.moveTo(CGPointMake(614.4, 591.4), duration: 1.5)
let move22 = SKAction.moveTo(CGPointMake(409.6, 591.4), duration: 1.5)
let move23 = SKAction.moveTo(CGPointMake(409.6, 386.6), duration: 1.5)
let move24 = SKAction.moveTo(CGPointMake(614.4, 386.6), duration: 1.5)
let enemy2m = SKAction.sequence([move21, move22, move23, move24])
let enemy2move = SKAction.repeatActionForever(enemy2m)
let move31 = SKAction.moveTo(CGPointMake(409.6, 386.6), duration: 1.5)
let move32 = SKAction.moveTo(CGPointMake(204.8, 386.6), duration: 1.5)
let move33 = SKAction.moveTo(CGPointMake(204.8, 181.8), duration: 1.5)
let move34 = SKAction.moveTo(CGPointMake(409.6, 181.8), duration: 1.5)
let enemy3m = SKAction.sequence([move31, move32, move33, move34])
let enemy3move = SKAction.repeatActionForever(enemy3m)
enemy1.runAction(enemy1move)
enemy2.runAction(enemy2move)
enemy3.runAction(enemy3move)
}
func didBeginContact(contact: SKPhysicsContact) {
let collision:UInt32 = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)
if collision == (playerCat | enemyCat) {
self.removeAllActions()
self.runAction(SKAction.waitForDuration(0.1), completion: {
self.runAction(SKAction.waitForDuration(0.2), completion:
{self.removeAllActions()
self.removeChildrenInArray([enemy1, enemy2, enemy3, player])})
restartButton.size = CGSizeMake(200, 200)
restartButton.position = CGPointMake(512, 384)
restartButton.zPosition = 1
self.addChild(restartButton)
})
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if (restartButton .containsPoint(location)) {
restartButton.runAction(fadeAway)
restartButton.removeFromParent()
println(1)
self.runAction(SKAction.waitForDuration(1.5), completion: {
let repeatLevel = SKTransition.fadeWithDuration(2)
let level2 = Level2(fileNamed: "Level2")
self.view?.presentScene(level2, transition: repeatLevel)
})
}
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
Your restartButton is having its size set for the first time when your playerCat and enemyCat first collide, which is fine.
Since the restartButton now has a size. You can check if your touch is within the bounds of the restartButton.
if (restartButton .containsPoint(location)) {
Like you have done so, but at no point do you check wether the restartButton is added to the scene.
A quick fix could possibly be:
if (restartButton.parent != nil && restartButton .containsPoint(location)) {
If dont specifically need to check if it with the bounds of the node. You could directly check using this instead. Which will eliminate the need to check for a parent.
if (self.nodeAtPoint(location) == restartButton) {
Another thing i noticed, in your collision detection, you never check if it has already collided. So you might run the same code multiple times, where you just keep removing all actions and then adding a new one.
You could add a simple have variable to prevent redudancy
var detectionMade = false
and reset at
override func didMoveToView(view: SKView) {
physicsWorld.contactDelegate = self
initWorld()
movements()
detectionMade = false
...
and set to true when first colliding and checking
if collision == (playerCat | enemyCat) && !detectionMade {
detectionMade = true
...
#martinmeincke I've done it! By doing THIS:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if (restartButton .containsPoint(location) && restartButton.parent == nil) {
restartButton.runAction(fadeAway)
println(1)
}
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if (restartButton .containsPoint(location)) {
restartButton.removeFromParent()
self.runAction(SKAction.waitForDuration(1.5), completion: {
let repeatLevel = SKTransition.fadeWithDuration(2)
let level2 = Level2(fileNamed: "Level2")
self.view?.presentScene(level2, transition: repeatLevel)
})
}
}
}