How do I make a group of functions loop swift SpriteKit - swift

My problem is I am trying to make all the bar6s to move down to the bottom of the screen, similar to flappy bird. I've done most of it, what I've done is make the bars go
down but I want to make it go on forever but only 5 bars go down how can I make it go on forever like regenerate or can you make a completion block in the function while you declare it.
Here is my code:
//
// PlaysScene.swift
// Pocket Rocket3
//
// Created by Lucas Farleigh on 27/11/2014.
// Copyright (c) 2014 Lucas Farleigh. All rights reserved.
//
import spriteKit
class PlayScene:SKScene {
//declaring the node in this scene!
let background = SKSpriteNode(imageNamed: "background")
let bar1 = SKSpriteNode(imageNamed:"bar1")
let bar2 = SKSpriteNode(imageNamed:"bar2")
let bar3 = SKSpriteNode(imageNamed:"bar3")
let bar4 = SKSpriteNode(imageNamed:"bar4")
let bar5 = SKSpriteNode(imageNamed:"bar5")
let bar6a = SKSpriteNode(imageNamed: "bar6")
let bar6b = SKSpriteNode(imageNamed: "bar6")
let bar6c = SKSpriteNode(imageNamed: "bar6")
let bar6d = SKSpriteNode(imageNamed: "bar6")
let bar6e = SKSpriteNode(imageNamed: "bar6")
let bar6f = SKSpriteNode(imageNamed: "bar6")
let bar6g = SKSpriteNode(imageNamed: "bar6")
let bar6h = SKSpriteNode(imageNamed: "bar6")
let bar6i = SKSpriteNode(imageNamed: "bar6")
let bar6j = SKSpriteNode(imageNamed: "bar6")
//making actions
override func didMoveToView(view: SKView) {
var check1 = false
var check2 = false
var check3 = false
var check4 = false
var check5 = false
var delayA = SKAction.waitForDuration(NSTimeInterval(1.5))
var delayB = SKAction.waitForDuration(NSTimeInterval(2))
var delayC = SKAction.waitForDuration(NSTimeInterval(4))
var delayD = SKAction.waitForDuration(NSTimeInterval(6))
var delayE = SKAction.waitForDuration(NSTimeInterval(8))
var actionmove = SKAction.moveToY(0, duration: 15)
var delay = SKAction.waitForDuration(NSTimeInterval(1.5))
var sequence = SKAction.sequence([ delay , actionmove])
var delchild = SKAction.removeFromParent()
func f1 () {
bar6a.position = CGPointMake(800 ,CGRectGetMaxY(self.frame))
bar6b.position = CGPointMake(1600,CGRectGetMaxY(self.frame))
check1 = false
bar6a.runAction(actionmove)
bar6b.runAction(actionmove,completion: {
self.bar6a.position = CGPointMake(800 ,CGRectGetMaxY(self.frame))
self.bar6b.position = CGPointMake(1600,CGRectGetMaxY(self.frame))
check1 = true
self.bar6a.runAction(actionmove)
self.bar6b.runAction(actionmove,completion: {
self.bar6a.removeFromParent()
self.bar6b.removeFromParent()
check1 = true
})
})
actionmove.timingMode = SKActionTimingMode.EaseOut
}
var sequence2 = SKAction.sequence([ delayB ,actionmove])
var sequence3 = SKAction.sequence([ delayC ,actionmove])
var sequence4 = SKAction.sequence([ delayD ,actionmove])
var sequence5 = SKAction.sequence([delayE , actionmove])
bar6a.xScale = 2.5
bar6b.xScale = 2.5
bar6c.xScale = 2.5
bar6d.xScale = 2.5
bar6e.xScale = 2.5
bar6f.xScale = 2.5
bar6g.xScale = 2.5
bar6h.xScale = 2.5
bar6i.xScale = 2.5
bar6j.xScale = 2.5
//making the actions
var num1 = 1
//making different delays
//sequence actions
addChild(bar6a)
addChild(bar6b)
addChild(bar6c)
addChild(bar6d)
addChild(bar6e)
addChild(bar6f)
addChild(bar6g)
addChild(bar6h)
addChild(bar6i)
addChild(bar6j)
//making the functions
func f2 () {
check2 = false
bar6c.position = CGPointMake(400 ,CGRectGetMaxY(self.frame))
bar6d.position = CGPointMake(1200,CGRectGetMaxY(self.frame))
bar6d.runAction(sequence2)
bar6c.runAction(sequence2, completion:{
self.bar6c.removeFromParent()
self.bar6d.removeFromParent()
check2 = true
})
bar6d.runAction(sequence2)
}
func f3 () {
check3 = false
bar6e.position = CGPointMake(600 ,CGRectGetMaxY(self.frame))
bar6f.position = CGPointMake(1400,CGRectGetMaxY(self.frame))
bar6e.runAction(sequence3,completion:{
self.bar6e.removeFromParent()
self.bar6f.removeFromParent()
check3 = true
})
bar6f.runAction(sequence3)
}
func f4 () {
check4 = false
bar6g.position = CGPointMake(700 ,CGRectGetMaxY(self.frame))
bar6h.position = CGPointMake( 1500,CGRectGetMaxY(self.frame))
bar6h.runAction(sequence4)
bar6g.runAction(sequence4,completion:{
self.bar6g.removeFromParent()
self.bar6h.removeFromParent()
check4 = true
})
}
func f5 () {
check5 = false
bar6i.position = CGPointMake(700 ,CGRectGetMaxY(self.frame))
bar6j.position = CGPointMake(1500 ,CGRectGetMaxY(self.frame))
bar6j.runAction(sequence5)
bar6i.runAction(sequence5,completion:{
check5 = true
self.bar6i.removeFromParent()
self.bar6j.removeFromParent()
})
}
f1()
f2()
f3()
f4()
f5()
//making the action repeat forever
var num2 = 1
bar1.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY (self.frame))
bar2.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY (self.frame))
bar3.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY (self.frame))
bar4.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY (self.frame))
bar5.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY (self.frame))
bar1.xScale = 2.5
bar2.xScale = 2.5
bar3.xScale = 2.5
bar4.xScale = 2.5
bar5.xScale = 1.7
/*
bar1.runAction(sequence, completion: {
self.bar2.runAction(sequence, completion: {
self.bar3.runAction(sequence, completion:{
self.bar4.runAction(sequence, completion:{
self.bar5.runAction(sequence)
})
})
})
})*/
background.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))
//doing the background stuff
background.yScale = 2.0
background.xScale = 3.0
addChild(background)
//doing the the bar stuff
if check1 == true{
f1()
}
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
}
}

EDIT: I see that you are trying to do this similar to flappy bird now. I would suggest doing either an SKPhysicsNode with spritekit or attempting to use Cocos2d http://www.cocos2d-x.org/wiki/Physics

Related

SpriteKit enemy sprites skip after contact with player

I have made a game where the basic idea is that a player sprite has to either collide with or avoid falling enemy sprites depending on the letter assigned to the enemy. The problem is that when my player makes contact with a sprite, the surrounding enemies skip forward significantly. This makes the game too hard to play because there isn't enough time for the player to move out of the way of oncoming enemy sprites. This happens on the device and the simulator.
To see what I mean, look at this brief video. You can see the lag at 00:06 and 00:013: https://www.dropbox.com/s/8pp66baxc9uhy26/SimulatorScreenSnapz002.mov?dl=0
Here is my code for player and enemy contact:
class GameplaySceneClass: SKScene, SKPhysicsContactDelegate {
private var player:Player?
private var center = CGFloat()
private var canMove = false, moveLeft = false
private var itemController = ItemController()
private var scoreLabel: SKLabelNode?
private var wordLabel: SKLabelNode?
private var score = 0
private var theWord = ""
private var vowelPressed = false
let correct = SoundSFX("correct.wav")
let wrong = SoundSFX("nomatch.wav")
let explosion = SoundSFX("explosion.wav")
var arrayOfStrings: [String]?
var theCheckedWord = ""
var currentCount = 0
var itemsArray = [String]()
var partialExists = false
var characterScore = 0
var onePointLetters = [12, 14, 18, 19, 20]
var twoPointLetters = [4, 7]
var threePointLetters = [2, 3, 13, 16]
var fourPointLetters = [6, 8, 22, 23, 25]
var fivePointLetters = [11]
var eightPointLetters = [10, 24]
var tenPointLetters = [17, 26]
var letter = 0
var scoreArray = [Int]()
var matchingTerms = [String]()
var gravity:CGFloat = -0.35
var result = CGSize()
let synth = AVSpeechSynthesizer()
var myUtterance = AVSpeechUtterance(string:"")
override func didMove(to view: SKView) {
SoundEngine.shared.backgroundMusicVolume = 1.0
SoundEngine.shared.playBackgroundMusic("Jungle Audio-1.m4a", loop: true)
initializeGame()
}
override func update(_ currentTime: TimeInterval) {
managePlayer()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location (in: self)
if atPoint(location).name == "LetterA" {
print ("Letter A pressed")
vowelPressed = true
theWord = theWord + "A"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterE" {
print ("Letter E pressed")
vowelPressed = true
theWord = theWord + "E"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterI" {
print ("Letter I pressed")
vowelPressed = true
theWord = theWord + "I"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterO" {
print ("Letter O pressed")
vowelPressed = true
theWord = theWord + "O"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "LetterU" {
print ("Letter U pressed")
vowelPressed = true
theWord = theWord + "U"
wordLabel?.text = theWord
if theWord.characters.count >= 3 {
checkWord()
}
vowelPressed = false
}
else if atPoint(location).name == "Pause" {
showPauseAlert()
}
else if atPoint(location).name == "delete" {
theWord = ""
theCheckedWord = ""
wordLabel?.text = theWord
}
else {
if location.x > center && !vowelPressed {
moveLeft = false
}
else if location.x < center && !vowelPressed {
moveLeft = true
}
canMove = true
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
canMove = false
}
func didBegin(_ contact: SKPhysicsContact) {
if !gamePaused {
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
if contact.bodyA.node?.name == "Player" {
firstBody = contact.bodyA
secondBody = contact.bodyB
}
else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.node?.name == "Player" && secondBody.node?.name == "Tile" {
letter = secondBody.node?.userData?.value(forKey:"key") as! Int
print ("The value of letter is \(letter)")
var letterCode = String(describing: letter)
var letterValue = Int(letterCode)
var finalLetterValue = letterValue!+64
var ASCIICode = Character(UnicodeScalar(finalLetterValue)!)
var letterString = String(describing:ASCIICode)
theWord = theWord + letterString
print (theWord)
if onePointLetters.contains(letter) {
characterScore += 1
}
else if twoPointLetters.contains(letter) {
characterScore += 2
}
else if threePointLetters.contains(letter) {
characterScore += 3
}
else if fourPointLetters.contains(letter) {
characterScore += 4
}
else if fivePointLetters.contains(letter) {
characterScore += 5
}
else if eightPointLetters.contains(letter) {
characterScore += 8
}
else if tenPointLetters.contains(letter) {
characterScore += 10
}
wordLabel?.text = theWord
theCheckedWord = theWord.lowercased()
print ("The checked word is \(theCheckedWord)")
checkWord()
secondBody.node?.removeFromParent()
}
if firstBody.node?.name == "Player" && secondBody.node?.name == "Bomb" {
explosion.play()
firstBody.node?.removeFromParent()
secondBody.node?.removeFromParent()
theWord = ""
score = 0
scoreLabel?.text = String(score)
var delayTimer = SKAction.wait(forDuration:1)
run (delayTimer)
restartGame()
}
}
}
private func initializeGame() {
do {
// This solution assumes you've got the file in your bundle
if let path = Bundle.main.path(forResource: "en", ofType: "txt"){
let data = try String(contentsOfFile:path, encoding: String.Encoding.utf8)
arrayOfStrings = data.components(separatedBy: "\n")
}
} catch let err as NSError {
// do something with Error
print(err)
}
physicsWorld.contactDelegate = self
physicsWorld.gravity = CGVector(dx:0,dy:gravity)
player = childNode(withName: "Player") as? Player!
player?.initializePlayer()
player?.position = CGPoint(x:0, y: -420)
scoreLabel = childNode(withName: "ScoreLabel") as? SKLabelNode!
scoreLabel?.text = String(score)
wordLabel = childNode(withName:"WordLabel") as? SKLabelNode!
wordLabel?.text = ""
center = self.frame.size.width/self.frame.size.height
var spawnBlocks = SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration:1),SKAction.run(spawnItems)]))
var removeBlocks = SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration:1),SKAction.run(removeItems)]))
if gamePaused == true {
self.scene?.isPaused = true
}
self.run(spawnBlocks)
self.run(removeBlocks)
}
private func checkWord() {
theCheckedWord = theWord.lowercased()
if (arrayOfStrings?.contains(theCheckedWord))! {
print ("Yes! \(theCheckedWord) is a word")
correct.play()
print ("The current value of score is \(score)")
score += characterScore
print ("Current gravity setting is \(gravity)")
scoreLabel?.text = String(score)
characterScore = 0
matchingTerms = (arrayOfStrings?.filter({$0.hasPrefix(theCheckedWord)
}))!
if matchingTerms.count == 1 {
characterScore = 0
print ("Current gravity setting is \(gravity)")
theWord = ""
theCheckedWord = ""
wordLabel?.text = ""
}
}
else if !(arrayOfStrings?.contains(theCheckedWord))! {
matchingTerms = (arrayOfStrings?.filter({$0.hasPrefix(theCheckedWord)
}))!
if matchingTerms.count == 0 {
wrong.play()
characterScore = 0
if score >= 5 {
score -= 5
}
theWord = ""
theCheckedWord = ""
wordLabel?.text = ""
}
}
}
Here is my code for the enemies:
import SpriteKit
struct ColliderType {
static let PLAYER: UInt32 = 0
static let TILE_AND_BOMB: UInt32 = 1;
}
public var bounds = UIScreen.main.bounds
public var width = bounds.size.width
public var height = bounds.size.height
class ItemController {
private var minX = CGFloat(-(width/2)), maxX = CGFloat(width/2)
private var vowelNumbers = [1, 5, 9, 15, 21]
func spawnItems() -> SKSpriteNode {
let item: SKSpriteNode?
if Int(randomBetweenNumbers(firstNum: 0, secondNum: 10)) > 7 {
item = SKSpriteNode(imageNamed: "Bomb")
item!.name = "Bomb"
item!.setScale(0.6)
item!.physicsBody = SKPhysicsBody(circleOfRadius: item!.size.height / 2)
print ("The value of width is \(width)")
} else {
var num = Int(randomBetweenNumbers(firstNum: 1, secondNum: 26))
if vowelNumbers.contains(num) {
num = num + 1
}
item = SKSpriteNode(imageNamed: "Tile \(num)")
item?.userData = NSMutableDictionary()
item!.name = "Tile"
item!.userData!.setValue(num, forKey:"key")
item!.zRotation = 0
item!.setScale(0.9)
item!.physicsBody = SKPhysicsBody(circleOfRadius: item!.size.height / 2)
if gamePaused == true {
item!.isPaused = true
}
else {
item!.isPaused = false
}
}
item!.physicsBody?.categoryBitMask = ColliderType.TILE_AND_BOMB;
item!.physicsBody?.isDynamic = true
item!.zPosition = 3
item!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
item!.position.x = randomBetweenNumbers(firstNum: minX, secondNum: maxX)
item!.position.y = 600
return item!
}
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum);
}
}
And here is my code for the player:
import SpriteKit
class Player: SKSpriteNode {
private var minX = CGFloat(-300), maxX = CGFloat(300)
func initializePlayer() {
name = "Player"
physicsBody = SKPhysicsBody(circleOfRadius: size.height/2)
physicsBody?.affectedByGravity = false
physicsBody?.isDynamic = false
physicsBody?.categoryBitMask = ColliderType.PLAYER
physicsBody?.contactTestBitMask = ColliderType.TILE_AND_BOMB
}
func move(left:Bool){
if left {
position.x -= 15
if position.x < minX {
position.x = minX
}
}
else {
position.x += 15
if position.x > maxX {
position.x = maxX
}
}
}
}
Consider calling the checkWord() method from an SKAction:
let checkWordsAction = SKAction.run() {
[weak self] in
self?.checkWord()
}
self.run(checkWordsAction)
That way, if your array is too big, the code will not get interrupted because you are walking it to check for your word.
Also I'm not sure of what you are trying to do with the wait action at the end of the didBegin(contact:) method, when you are colliding with bombs. If you are trying to wait for 1 second before restarting the game, then keep in mind that calling the wait action the way you do will not pause your code. Actually it will simply put the scene on idle for 1 second and restart the game in the background. If that is the intended effect, it's ok, but you might be better using the run(_:completion:) method instead and call restartGame() from the completion closure:
let waitAction = SKAction.wait(1)
self.run(waitAction) { [weak self] in
self?.restartGame()
}
Hope this helps!
In didBegin(_ contact: SKPhysicsContact), you create two physics bodies in:
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
Maybe the lag is created because you create two new physics bodies. What if you don't create the physics bodies, but just create references to existing ones? I haven't tested this, but maybe try:
let firstBody: SKPhysicsBody
let secondBody: SKPhysicsBody
if contact.bodyA.node?.name == "Player" {
firstBody = contact.bodyA
secondBody = contact.bodyB
}
else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}

Populating a generator. Is it possible?

I have a generator that generates a circle(SKShapeNode) every 2 seconds from the y-axis. (Moves up). I would like to know if it is possible to populate this generator uniformly(every x number of points.
Here is my code for said generator:
class CircleGen: SKShapeNode {
var circles = [WhiteCircles]()
var circleTracker = [WhiteCircles]()
var generationTimer: NSTimer!
var circ: WhiteCircles!
func generateCircles() {
for var i = 0; i < 4; i++ {
var scale: CGFloat
let rand = arc4random_uniform(10)
if rand == 0 {
scale = -15.0
} else {
scale = 15.0
}
let circle = WhiteCircles()
circle.position.x = lineGen.position.x
circle.physicsBody?.affectedByGravity = false
circle.position.y = 35
self.circles.append(circle)
circleTracker.append(circle)
foregroundNode.addChild(circle)
}
}
func startGeneratingEvery(seconds: NSTimeInterval) {
let callGenerateAction = SKAction.runBlock { () -> Void in
self.generateCircles()
}
let waitOneSecond = SKAction.waitForDuration(seconds)
let sequenceAction = SKAction.sequence([callGenerateAction, waitOneSecond])
let circleGenerateAction = SKAction.repeatActionForever(sequenceAction)
self.runAction(circleGenerateAction, withKey: "generateCircles")
}
}
Will post more code if necessary. Thank you in advance.

How to save highscore swift

I have been trying and searching for something that will help me for a long time but I haven't been able to find a solution yet. I am just trying to save a high score for the game that I am making but it always shows no errors and then gives me weird errors like "Thread 1: signal SIGABRT" when i try and run. Can anyone help me see what I am doing wrong?
import CoreMotion
import SpriteKit
enum CollisionTypes: UInt32{
case Player = 1
case Wall = 2
case Star = 4
case Vortex = 8
case Finish = 16
}
var levelsPassed = 0
var levelName = "level1"
class GameScene: SKScene, SKPhysicsContactDelegate {
var player: SKSpriteNode!
//hack so that we can test on the computer and then use on devises as well
var lastTouchPosition: CGPoint?
//create the motion manager
var motionManager: CMMotionManager!
//score labels
var scoreLabel: SKLabelNode!
var score: Int = 0 {
didSet {
scoreLabel.text = "Score: \(score)"
}
}
var highScoreLabel: SKLabelNode!
var highestScore:Int = 0
var gameOver = false
override func didMoveToView(view: SKView) {
/* Setup your scene here */
UIApplication.sharedApplication().idleTimerDisabled = true
let background = SKSpriteNode(imageNamed: "background.jpg")
background.position = CGPoint(x: 512, y: 384)
background.zPosition = -1
background.blendMode = .Replace
addChild(background)
NSUserDefaults.standardUserDefaults().setObject(highestScore, forKey:"HighestScore")
NSUserDefaults.standardUserDefaults().synchronize()
if (NSUserDefaults.valueForKey("HighestScore") != nil){
var savedScore: Int = NSUserDefaults.standardUserDefaults().objectForKey("HighestScore") as! Int
}
//call the loadLevel funciton
loadLevel(levelName)
createPlayer()
scoreLabel = SKLabelNode(fontNamed: "Chalkduster")
scoreLabel.text = "Score: 0"
scoreLabel.horizontalAlignmentMode = .Left
scoreLabel.position = CGPoint(x:32, y:100)
scoreLabel.zPosition = 2
addChild(scoreLabel)
highScoreLabel = SKLabelNode(fontNamed: "Chalkduster")
highScoreLabel.text = "Highscore: \(highestScore)"
highScoreLabel.horizontalAlignmentMode = .Left
highScoreLabel.position = CGPoint(x:225, y:100)
highScoreLabel.zPosition = 2
addChild(scoreLabel)
//give the game no gravity by default
physicsWorld.gravity = CGVector(dx: 0, dy: 0)
physicsWorld.contactDelegate = self
motionManager = CMMotionManager()
motionManager.startAccelerometerUpdates()
}
Try this code
import SpriteKit
class GameScene: SKScene {
var highScoreLabel: SKLabelNode!
var highestScore:Int = 0
var score = 0
override func didMoveToView(view: SKView) {
highScoreLabel = SKLabelNode(fontNamed: "Chalkduster")
highScoreLabel.text = "Highscore: \(highestScore)"
highScoreLabel.horizontalAlignmentMode = .Left
highScoreLabel.position = CGPoint(x:225, y:100)
highScoreLabel.zPosition = 2
addChild(highScoreLabel)
}
override func update(currentTime: NSTimeInterval) {
var highscore = 1
let userDefaults = NSUserDefaults.standardUserDefaults()
highscore = userDefaults.integerForKey("highscore")
userDefaults.setValue(highscore, forKey: "highscore")
if score > highscore {
userDefaults.setValue(score, forKey: "highscore")
}
highScoreLabel.text = "highscore: \(highscore)"
userDefaults.synchronize()
}
}

Swift MultiTouch objects

This is my first game in Swift. I want to make a more advanced Breakout Game with SpriteKit like in this tutorial
I want to create 4 paddles and move them individually with 4 fingers, I tried to do that but when I move one paddle the second one moves too... What can I do ?
import SpriteKit
import AVFoundation
class GameScene: SKScene {
var fingerIsOnPaddle1 = false
var fingerIsOnPaddle2 = false
var fingerISOnPaddle3 = false
var fingerIsOnPaddle4 = false
let shurikenCategoryName = "shuriken"
let paddleCategoryName = "paddle"
let paddle2CategoryName = "paddle2"
let paddle3CategoryName = "paddle3"
let paddle4CategoryName = "paddle4"
let brickCategoryName = "brick"
let backgroundMusicPlayer = AVAudioPlayer()
override init(size: CGSize){
super.init(size: size)
let bgMusicURL = NSBundle.mainBundle().URLForResource("bgMusicMP3", withExtension: "mp3")
backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: bgMusicURL, error: nil)
backgroundMusicPlayer.numberOfLoops = -1
backgroundMusicPlayer.prepareToPlay()
backgroundMusicPlayer.play()
let backgroundImage = SKSpriteNode(imageNamed: "bg")
backgroundImage.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 3)
self.addChild(backgroundImage)
self.physicsWorld.gravity = CGVectorMake(0, 0)
let worldBorder = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = worldBorder
self.physicsBody?.friction = 0
let shuriken = SKSpriteNode(imageNamed: "shuriken")
shuriken.name = shurikenCategoryName
shuriken.position = CGPointMake(self.frame.size.width/2, self.frame.size.height / 2)
self.addChild(shuriken)
shuriken.physicsBody = SKPhysicsBody(circleOfRadius: shuriken.frame.width / 2)
shuriken.physicsBody?.friction = 0
shuriken.physicsBody?.restitution = 1
shuriken.physicsBody?.linearDamping = 0
shuriken.physicsBody?.applyImpulse(CGVectorMake(2, 2))
shuriken.physicsBody?.allowsRotation = true
let paddle = SKSpriteNode(imageNamed: "paddle")
paddle.name = paddleCategoryName
paddle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)/4)
self.addChild(paddle)
paddle.physicsBody = SKPhysicsBody(rectangleOfSize: paddle.frame.size)
paddle.physicsBody?.friction = 0.4
paddle.physicsBody?.restitution = 0.1
paddle.physicsBody?.dynamic = false
//paddle.position = CGPointMake(CGRectGetMidX(self.frame)/2, CGRectGetMidY(self.frame)/4)
//self.addChild(paddle)
let paddle2 = SKSpriteNode(imageNamed: "paddle")
paddle2.name = paddle2CategoryName
paddle2.position = CGPointMake(CGRectGetMidX(self.frame)/5, CGRectGetMidY(self.frame))
paddle2.zRotation = CGFloat(M_PI_2)
self.addChild(paddle2)
paddle2.physicsBody = SKPhysicsBody(rectangleOfSize: paddle.frame.size)
paddle2.physicsBody?.friction = 0.4
paddle2.physicsBody?.restitution = 0.1
paddle2.physicsBody?.dynamic = false
let paddle3 = SKSpriteNode(imageNamed: "paddle")
paddle3.name = paddle2CategoryName
paddle3.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)/4*7)
self.addChild(paddle3)
let paddle4 = SKSpriteNode(imageNamed: "paddle")
paddle4.name = paddle2CategoryName
paddle4.position = CGPointMake(CGRectGetMidX(self.frame)/5*9, CGRectGetMidY(self.frame))
paddle4.zRotation = CGFloat(M_PI_2)
self.addChild(paddle4)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
let body:SKPhysicsBody? = self.physicsWorld.bodyAtPoint(touchLocation)
if body?.node?.name == paddleCategoryName {
println("Paddle 1 touched")
fingerIsOnPaddle1 = true
}
if body?.node?.name == paddle2CategoryName{
println("Paddle 2 touched")
fingerIsOnPaddle2 = true
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
if fingerIsOnPaddle1{
let touch = touches.anyObject() as UITouch
let touchLoc = touch.locationInNode(self)
let prevTouchLoc = touch.previousLocationInNode(self)
let paddle = self.childNodeWithName(paddleCategoryName) as SKSpriteNode
var newXPos = paddle.position.x + (touchLoc.x - prevTouchLoc.x)
paddle.position = CGPointMake(newXPos, paddle.position.y)
}
if fingerIsOnPaddle2{
let touch2 = touches.anyObject() as UITouch
let touchLoc2 = touch2.locationInNode(self)
let prevTouchLoc2 = touch2.previousLocationInNode(self)
let paddle2 = self.childNodeWithName(paddle2CategoryName) as SKSpriteNode
var newYPos = paddle2.position.y + (touchLoc2.y - prevTouchLoc2.y)
paddle2.position = CGPointMake(paddle2.position.y, newYPos)
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
}
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
}
}
The crux of the issue here is in the touchesBegan function, which takes a Set of touches. It's a very common pattern to just take the first one, using anyObject(), but instead of doing that, you can loop over them, like this:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch in touches as? UITouch {
let touchLocation = touch.locationInNode(self)
let body:SKPhysicsBody? = self.physicsWorld.bodyAtPoint(touchLocation)
if body?.node?.name == paddleCategoryName {
println("Paddle 1 touched")
fingerIsOnPaddle1 = true
}
if body?.node?.name == paddle2CategoryName{
println("Paddle 2 touched")
fingerIsOnPaddle2 = true
}
}
}

How do I Make a run block action Swift SpriteKit

Hi I have been trying to do this for a long time,I am using Swift SpriteKit , my problem is that I need to make a runBlock action for a node how do I make an action which runs a function I have tried this:
var a = SKAction.runBlock({() in self.spawn1()})
For your information The spawn1 is the function.
Thanks in advance!
Heres my code for help of the comment of the first answer:
//
// PlaysScene.swift
// Pocket Rocket3
//
// Created by Lucas Farleigh on 27/11/2014.
// Copyright (c) 2014 Lucas Farleigh. All rights reserved.
//
import spriteKit
class PlayScene:SKScene {
//declaring the node in this scene!
let background = SKSpriteNode(imageNamed: "background")
let bar1 = SKSpriteNode(imageNamed:"bar1")
let bar2 = SKSpriteNode(imageNamed:"bar2")
let bar3 = SKSpriteNode(imageNamed:"bar3")
let bar4 = SKSpriteNode(imageNamed:"bar4")
let bar5 = SKSpriteNode(imageNamed:"bar5")
let bar6a = SKSpriteNode(imageNamed: "bar6")
let bar6b = SKSpriteNode(imageNamed: "bar6")
let bar6c = SKSpriteNode(imageNamed: "bar6")
let bar6d = SKSpriteNode(imageNamed: "bar6")
let bar6e = SKSpriteNode(imageNamed: "bar6")
let bar6f = SKSpriteNode(imageNamed: "bar6")
let bar6g = SKSpriteNode(imageNamed: "bar6")
let bar6h = SKSpriteNode(imageNamed: "bar6")
let bar6i = SKSpriteNode(imageNamed: "bar6")
let bar6j = SKSpriteNode(imageNamed: "bar6")
//making actions
override func didMoveToView(view: SKView) {
var actionmove = SKAction.moveToY(0, duration: 15)
var delay = SKAction.waitForDuration(NSTimeInterval(1.5))
var delchild = SKAction.removeFromParent()
func spawn1(){
bar6a.position = CGPointMake(800 ,CGRectGetMaxY(self.frame))
bar6b.position = CGPointMake(1600,CGRectGetMaxY(self.frame))
addChild(bar6a)
addChild(bar6b)
}
func spawn2 (){
bar6c.position = CGPointMake(400 ,CGRectGetMaxY(self.frame))
bar6d.position = CGPointMake(1200,CGRectGetMaxY(self.frame))
addChild(bar6c)
addChild(bar6d)
}
func spawn3 (){
bar6e.position = CGPointMake(600 ,CGRectGetMaxY(self.frame))
bar6f.position = CGPointMake(1400,CGRectGetMaxY(self.frame))
addChild(bar6e)
addChild(bar6f)
}
func spawn4 (){
bar6g.position = CGPointMake(700 ,CGRectGetMaxY(self.frame))
bar6h.position = CGPointMake(1500,CGRectGetMaxY(self.frame))
addChild(bar6g)
addChild(bar6h)
}
func spawn5 (){
bar6i.position = CGPointMake(700 ,CGRectGetMaxY(self.frame))
bar6j.position = CGPointMake(1500,CGRectGetMaxY(self.frame))
addChild(bar6i)
addChild(bar6j)
}
var a = SKAction.runBlock({ self.spawn1() })
var b = SKAction.runBlock(spawn2)
var c = SKAction.runBlock(spawn3)
var d = SKAction.runBlock(spawn4)
var e = SKAction.runBlock(spawn5)
var delayA = SKAction.waitForDuration(NSTimeInterval(1.5))
var delayB = SKAction.waitForDuration(NSTimeInterval(2))
var delayC = SKAction.waitForDuration(NSTimeInterval(4))
var delayD = SKAction.waitForDuration(NSTimeInterval(6))
var delayE = SKAction.waitForDuration(NSTimeInterval(8))
var sequence1 = SKAction.sequence([delayA,a,actionmove,delchild])
var sequence2 = SKAction.sequence([delayB,b,actionmove,delchild])
var sequence3 = SKAction.sequence([delayC,c,actionmove,delchild])
var sequence4 = SKAction.sequence([delayD,d,actionmove,delchild])
var sequence5 = SKAction.sequence([delayE,e,actionmove,delchild])
var repeat1 = SKAction.repeatActionForever(sequence1)
var repeat2 = SKAction.repeatActionForever(sequence2)
var repeat3 = SKAction.repeatActionForever(sequence3)
var repeat4 = SKAction.repeatActionForever(sequence4)
var repeat5 = SKAction.repeatActionForever(sequence5)
//actionmove: making it smooth
actionmove.timingMode = SKActionTimingMode.EaseOut
//doing stuff with the background
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
background.yScale = 10.0
background.xScale = 10.0
addChild(background)
//running the actions
bar6a.runAction(repeat1)
bar6b.runAction(repeat1)
bar6c.runAction(repeat2)
bar6d.runAction(repeat2)
bar6e.runAction(repeat3)
bar6f.runAction(repeat3)
bar6g.runAction(repeat4)
bar6h.runAction(repeat4)
bar6i.runAction(repeat5)
bar6j.runAction(repeat5)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
}
}
var a = SKAction.runBlock({ self.spawn1() })
yournode.runAction(a)