Terminating app due to uncaught exception while running app - ios

I am making a game in which if I press a button the player (circuloPrincipal) changes to the color to a color determinate by the button.
When I run my game sometimes crashes with the error below. I havent find the error, because I cont know how to interpretate
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: name:'button4' texture:[ 'circuloBoton' (100 x 100)] position:{407, 39} scale:{1.00, 1.00} size:{60, 60} anchor:{0.5, 0.5} rotation:0.00'
circuloPrincipal.size = CGSize(width: 225, height: 225)
circuloPrincipal.position = CGPoint(x: frame.width / 2, y: frame.height / 2)
circuloPrincipal.color = colorAzul
circuloPrincipal.colorBlendFactor = 1.0
circuloPrincipal.physicsBody = SKPhysicsBody(circleOfRadius: circuloPrincipal.size.height / 2)
circuloPrincipal.physicsBody?.contactTestBitMask = physicsCategory.circuloPrincipal
circuloPrincipal.physicsBody?.collisionBitMask = physicsCategory.enemigo
circuloPrincipal.physicsBody?.contactTestBitMask = physicsCategory.enemigo
circuloPrincipal.physicsBody?.affectedByGravity = false
circuloPrincipal.physicsBody?.dynamic = false
circuloPrincipal.name = "circuloPrincipal"
circuloPrincipal.zPosition = 5.0
circuloBlanco.size = CGSize(width: 60, height: 60)
circuloBlanco.position = CGPoint(x: frame.width / 2 - 105 , y: frame.height / 2 - 345)
circuloBlanco.color = colorBlanco
circuloBlanco.colorBlendFactor = 1.0
circuloBlanco.zPosition = 4.0
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
if gameStarted == false {
circuloVerde.removeFromParent()
circuloMorado.removeFromParent()
circuloRojo.removeFromParent()
circuloBlanco.removeFromParent()
circuloPrincipal.color = colorAzul
enemigoTimer = NSTimer.scheduledTimerWithTimeInterval(0.7, target: self, selector: Selector("enemigos"), userInfo: nil, repeats: true)
gameStarted = true
circuloPrincipal.runAction(SKAction.scaleTo(0.44, duration: 0.4))
score = 0
scoreLabel.text = "\(score)"
hits = 0
highscoreLabel.runAction(SKAction.fadeOutWithDuration(0.5))
}
circuloVerde.name = "button"
let touch = touches.first
let positionInScene = touch!.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
if let name = touchedNode.name {
if name == "button" {
circuloPrincipal.color = colorVerde
}
}
circuloAmarillo.name = "button2"
let touch2 = touches.first
let positionInScene2 = touch2!.locationInNode(self)
let touchedNode2 = self.nodeAtPoint(positionInScene2)
if let name = touchedNode2.name {
if name == "button2" {
circuloPrincipal.color = colorAmarillo
}
}
circuloAzul.name = "button3"
let touch3 = touches.first
let positionInScene3 = touch3!.locationInNode(self)
let touchedNode3 = self.nodeAtPoint(positionInScene3)
if let name = touchedNode3.name {
if name == "button3" {
//do my stuff
circuloPrincipal.color = colorAzul
}
}
circuloBlanco.name = "button4"
let touch4 = touches.first
let positionInScene4 = touch4!.locationInNode(self)
let touchedNode4 = self.nodeAtPoint(positionInScene4)
if let name = touchedNode4.name {
if name == "button4" {
circuloPrincipal.color = colorBlanco
}
}
circuloRojo.name = "button5"
let touch5 = touches.first
let positionInScene5 = touch5!.locationInNode(self)
let touchedNode5 = self.nodeAtPoint(positionInScene5)
if let name = touchedNode5.name {
if name == "button5" {
circuloPrincipal.color = colorRojo
}
}
circuloMorado.name = "button6"
let touch6 = touches.first
let positionInScene6 = touch6!.locationInNode(self)
let touchedNode6 = self.nodeAtPoint(positionInScene6)
if let name = touchedNode6.name {
if name == "button6" {
circuloPrincipal.color = colorMorado
}
}
}

you're trying to add a node but it already has a parent. its right there in the error message.
you can check to see if it already has a parent like this
let childNode = SKNode()
let parentNode = SKNode()
if childNode.parent == nil {
parentNode.addChild(childNode)
}

Related

Why am I getting "Exception caught in AudioQueueInternalNotifyRunning - error -66671" when playing audio?

I have three different AVAudio instances. When trying to play my sound that is "audioPlayer3" I get an exception. Can someone take a look for me?" Also when clicking the button "playAgain"
button it plays "audioPlayer3" and I am not sure why. "audioPlayer" and audioPlayer2 work just fine. The issue is only with "audioPlayer3".
import AVFoundation
import SpriteKit
import GameplayKit
import GameKit
class EggCatchScene: SKScene {
var mainMenuButton = SKSpriteNode(imageNamed: "mainmenuButton2")
var isfacingRight = true;
var isfacingLeft = false
var audioPlayer3 : AVAudioPlayer!
var audioPlayer = AVAudioPlayer()
var audioPlayer2 = AVAudioPlayer()
var submitButton = SKSpriteNode(imageNamed: "submitButton.png")
var scoresubmitAlert = SKSpriteNode(imageNamed: "scoresubmittedAlert.png")
var playagainButton2 = SKSpriteNode(imageNamed: "playagainButton")
var levelLabel: SKLabelNode!
var scoreLabel: SKLabelNode!
var gameoverscoreLabel: SKLabelNode!
var birdSprite = SKSpriteNode(imageNamed: "birdAnimation1.png")
var playagainButton = SKSpriteNode(imageNamed: "playagainButton")
var gameoverScreen = SKSpriteNode(imageNamed: "gameoverScreen")
var leftbuttonisPressed = false
var rightbuttonisPressed = false
var score = 0
private var bear = SKSpriteNode()
private var bearWalkingFrames: [SKTexture] = []
var rightButton = SKSpriteNode(imageNamed: "rightButton")
var eggcatchBackground = SKSpriteNode(imageNamed: "eggcatchBackground")
var leftButton = SKSpriteNode(imageNamed: "leftButton")
var eggcatchGround = SKSpriteNode(imageNamed: "eggcatchGround2")
var flyButton = SKSpriteNode(imageNamed: "upButton")
var eggSprite = SKSpriteNode(imageNamed: "eggSprite")
var number = Int.random(in: 20..<620)
override func didMove(to view: SKView) {
let sound = Bundle.main.path(forResource: "bgMusic.mp3", ofType: nil)!
let url = URL(fileURLWithPath: sound)
do{
audioPlayer2 = try AVAudioPlayer(contentsOf: url)
audioPlayer2.play()
audioPlayer2.numberOfLoops = 1
} catch {
print(error)
}
let atlas = SKTextureAtlas(named: "BirdAnimation")
let m1 = atlas.textureNamed("birdAnimation1.png")
let m2 = atlas.textureNamed("birdAnimation2.png")
let m3 = atlas.textureNamed("birdAnimation3.png")
let m4 = atlas.textureNamed("birdAnimation4.png")
let m5 = atlas.textureNamed("birdAnimation5.png")
let textures = [m1, m2, m3, m4, m5]
let meleeAnimation = SKAction.animate(with: textures, timePerFrame: 0.07)
birdSprite.run(SKAction.repeatForever(meleeAnimation))
birdSprite.position = CGPoint(x: frame.midX, y: frame.midY)
birdSprite.zPosition = 2
birdSprite.setScale(1)
self.addChild(birdSprite)
eggcatchBackground.position = CGPoint(x: frame.midX, y: frame.midY)
eggcatchBackground.zPosition = 0
eggcatchBackground.size.height = self.size.height
eggcatchBackground.size.width = self.size.width
self.addChild(eggcatchBackground)
mainMenuButton.isHidden = true
mainMenuButton.position = CGPoint(x: frame.midX, y: frame.midY - 260)
mainMenuButton.zPosition = 5
mainMenuButton.setScale(0.5)
self.addChild(mainMenuButton)
submitButton.isHidden = true
submitButton.position = CGPoint(x: frame.midX, y: frame.midY - 75)
submitButton.zPosition = 5
submitButton.setScale(0.5)
self.addChild(submitButton)
gameoverScreen.isHidden = true
gameoverScreen.position = CGPoint(x: frame.midX, y: frame.midY)
gameoverScreen.zPosition = 5
gameoverScreen.setScale(0.5)
self.addChild(gameoverScreen)
eggSprite.position = CGPoint(x: frame.midX, y: self.size.height)
eggSprite.zPosition = 2
eggSprite.setScale(0.2)
self.addChild(eggSprite)
eggcatchGround.position = CGPoint(x: frame.midX, y: 25)
eggcatchGround.zPosition = 2
eggcatchGround.size.width = self.size.width
self.addChild(eggcatchGround)
scoresubmitAlert.isHidden = true
scoresubmitAlert.position = CGPoint(x: frame.midX, y:frame.midY + 65)
scoresubmitAlert.zPosition = 3
scoresubmitAlert.setScale(0.7)
self.addChild(scoresubmitAlert)
flyButton.position = CGPoint(x: 550, y:150 )
flyButton.zPosition = 3
flyButton.setScale(0.2)
self.addChild(flyButton)
playagainButton.isHidden = true
playagainButton.position = CGPoint(x: frame.midX, y:frame.midY )
playagainButton.zPosition = 3
playagainButton.setScale(0.5)
self.addChild(playagainButton)
playagainButton2.isHidden = true
playagainButton2.position = CGPoint(x: frame.midX, y:frame.midY - 320 )
playagainButton2.zPosition = 3
playagainButton2.setScale(0.5)
self.addChild(playagainButton2)
rightButton.position = CGPoint(x: 240, y:150 )
rightButton.zPosition = 3
rightButton.setScale(0.2)
self.addChild(rightButton)
leftButton.position = CGPoint(x: 85, y:150 )
leftButton.zPosition = 3
leftButton.setScale(0.2)
self.addChild(leftButton)
scoreLabel = SKLabelNode(fontNamed: "Chalkduster")
scoreLabel.zPosition = 2
scoreLabel.fontColor = UIColor.red
scoreLabel.position = CGPoint(x: 100, y: 800)
addChild(scoreLabel)
levelLabel = SKLabelNode(fontNamed: "Chalkduster")
levelLabel.zPosition = 2
levelLabel.fontColor = UIColor.red
levelLabel.position = CGPoint(x: 550, y: 800)
addChild(levelLabel)
}
func checkforCollision(){
if(eggSprite.frame.intersects(eggcatchGround.frame)) || (birdSprite.frame.intersects(eggcatchGround.frame)){
let sound = Bundle.main.path(forResource: "gameoverSound.wav", ofType: nil)!
let url = URL(fileURLWithPath: sound)
do{
audioPlayer3 = try AVAudioPlayer(contentsOf: url)
audioPlayer3.play()
audioPlayer3.numberOfLoops = 0
} catch {
print(error)
}
eggSprite.position.y = 960
submitButton.isHidden = false
playagainButton.isHidden = false
self.birdSprite.removeFromParent()
self.eggSprite.removeFromParent()
self.rightButton.removeFromParent()
self.leftButton.removeFromParent()
self.flyButton.removeFromParent()
print("Game Over")
}
}
override func update(_ currentTime: TimeInterval){
birdSprite.position.y -= 1
checkforCollision()
scoreLabel.text = "Score: \(score)"
if(rightbuttonisPressed == true){
birdSprite.xScale = 1;
birdSprite.position.x += 10
}
if(leftbuttonisPressed == true){
birdSprite.position.x -= 10
birdSprite.xScale = -1;
}
if (score <= 10){
levelLabel.text = "Level 1"
eggSprite.position.y -= 1
}
if (score >= 10){
levelLabel.text = "Level 2"
eggSprite.position.y -= 1.1
}
if (score >= 20){
levelLabel.text = "Level 3"
eggSprite.position.y -= 1.2
}
if (score >= 30){
levelLabel.text = "Level 4"
eggSprite.position.y -= 1.3
}
if (score >= 40){
levelLabel.text = "Level 5"
eggSprite.position.y -= 1.4
}
if (score >= 60){
levelLabel.text = "Level 6"
eggSprite.position.y -= 1.5
}
if (score >= 70){
levelLabel.text = "Level 7"
eggSprite.position.y -= 1.6
}
if (score >= 80){
levelLabel.text = "Level 8"
eggSprite.position.y -= 1.7
}
if (score >= 90){
levelLabel.text = "Level 9"
eggSprite.position.y -= 1.8
}
if (score >= 100){
levelLabel.text = "Level 10"
eggSprite.position.y -= 1.9
}
if (score >= 110){
levelLabel.text = "Level 11"
eggSprite.position.y -= 2
}
if (score >= 120){
levelLabel.text = "Level 12"
eggSprite.position.y -= 2.1
}
if (score >= 130){
levelLabel.text = "Level 13"
eggSprite.position.y -= 2.2
}
if (score >= 140){
levelLabel.text = "Level 14"
eggSprite.position.y -= 2.3
}
if (score >= 150){
levelLabel.text = "Max"
eggSprite.position.y -= 2.4
}
/* if(birdSprite.frame.intersects(eggcatchGround.frame)){
// gameoverScreen.isHidden = false
let sound = Bundle.main.path(forResource: "gameoverSound", ofType: "mp3")!
let url = URL(fileURLWithPath: sound)
do{
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.play()
audioPlayer.numberOfLoops = 0
} catch {
print(error)
}
submitButton.isHidden = false
playagainButton.isHidden = false
self.birdSprite.removeFromParent()
self.eggSprite.removeFromParent()
self.rightButton.removeFromParent()
self.leftButton.removeFromParent()
self.flyButton.removeFromParent()
print("Game Over")
}*/
let xRange = SKRange(lowerLimit:0,upperLimit:size.width)
let yRange = SKRange(lowerLimit:0,upperLimit:size.height)
//sprite.constraints = [SKConstraint.positionX(xRange,Y:yRange)] // iOS 9
birdSprite.constraints = [SKConstraint.positionX(xRange,y:yRange)] // iOS 10
if(eggSprite.frame.intersects(birdSprite.frame)){
let sound = Bundle.main.path(forResource: "itemGet.wav", ofType: nil)!
let url = URL(fileURLWithPath: sound)
do{
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.play()
audioPlayer.numberOfLoops = 0
} catch {
print(error)
}
eggSprite.position.y = self.size.height
//eggSprite.position.x = number
score += 1
}
}
/*func startTimer()
{
countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(decrementCounter), userInfo: nil, repeats: true)
}*/
func decrementTimer(){
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
if submitButton.frame.contains(location) {
//submitButton.isHidden = true
submitButton.removeFromParent()
mainMenuButton.isHidden = false
playagainButton.removeFromParent()
playagainButton2.isHidden = false
scoresubmitAlert.isHidden = false
let score1 = GKScore(leaderboardIdentifier: "birdmemoirsleaderboard")
score1.value = Int64(score)
GKScore.report([score1]) { error in
guard error == nil else {
print(error?.localizedDescription ?? "")
return
}
print("done")
}
print("clicked")
}
if playagainButton.frame.contains(location) {
if let eggcatchScene = EggCatchScene(fileNamed: "EggCatchScene") {
let eggcatchScene = EggCatchScene(size: CGSize(width:640, height: 960))
self.view?.presentScene(eggcatchScene, transition: SKTransition.fade(withDuration: 1))
}
}
if playagainButton2.frame.contains(location) {
if let eggcatchScene = EggCatchScene(fileNamed: "EggCatchScene") {
let eggcatchScene = EggCatchScene(size: CGSize(width:640, height: 960))
self.view?.presentScene(eggcatchScene, transition: SKTransition.fade(withDuration: 1))
}
}
if mainMenuButton.frame.contains(location) {
if let mainmenuScene = GameScene2(fileNamed: "GameScene2") {
let mainmenuScene = GameScene2(size: CGSize(width:640, height: 960))
self.view?.presentScene(mainmenuScene, transition: SKTransition.fade(withDuration: 1))
}
}
if flyButton.frame.contains(location) {
birdSprite.position.y += 50
}
if rightButton.frame.contains(location) {
print("clicked")
rightbuttonisPressed = true
//sprite.position.x += 10
}
if leftButton.frame.contains(location) {
print("clicked")
leftbuttonisPressed = true
birdSprite.xScale = -1; }
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
if leftButton.contains(touch.location(in: self)) {
leftbuttonisPressed = false
}
if rightButton.contains(touch.location(in: self)) {
rightbuttonisPressed = false
}
}
}```

My animated SKSprite nodes atlas won't change during touchBegan

I created a sprite with an animated texture atlas. I then want that animation to change based on the direction the sprite is heading. I try to do so with "self.player!.texture = firstFrametexture(ofatlas)"
Here is where I build the player (put inside didMove but the animation starts without having to move?)
func buildPlayer() {
let playerAnimatedAtlas = SKTextureAtlas(named: "animation")
var walkFrames: [SKTexture] = []
let numImages = playerAnimatedAtlas.textureNames.count
for i in 1...numImages {
let playerTextureName = "player\(i)"
walkFrames.append(playerAnimatedAtlas.textureNamed(playerTextureName))
}
walkingPlayer = walkFrames
let firstFrameTexture = walkingPlayer[0]
player! = SKSpriteNode(texture: firstFrameTexture)
player!.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(player!)
}
Here is where I animate the player
func animatePlayer() {
player!.run(SKAction.repeatForever(
SKAction.animate(with: walkingPlayer,
timePerFrame: 0.5,
resize: false,
restore: true)),
withKey:"walkingInPlacePlayer")
}
Here is where I try to change the animation. Everything works, the if statement are correctly executed. Just nothing changes
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let location = touches.first?.location(in: self) {
let horizontalAction = SKAction.move(to: location, duration: 1.0)
horizontalAction.timingMode = SKActionTimingMode.easeOut
player?.run(horizontalAction)
let playerAnimatedAtlas = SKTextureAtlas(named: "animation")
let lplayerAnimatedAtlas = SKTextureAtlas(named: "animationleft")
var walkFrames: [SKTexture] = []
var lwalkFrames: [SKTexture] = []
let numImages = playerAnimatedAtlas.textureNames.count
for i in 1...numImages {
let playerTextureName = "player\(i)"
let playerLeftTextureName = "lplayer\(i)"
walkFrames.append(playerAnimatedAtlas.textureNamed(playerTextureName))
lwalkFrames.append(lplayerAnimatedAtlas.textureNamed(playerLeftTextureName))
}
walkingPlayer = walkFrames
lwalkingPlayer = lwalkFrames
let firstFrameTexture = walkingPlayer[0]
let leftFrameTexture = lwalkingPlayer[0]
if location.x > player!.position.x {
self.player!.texture = firstFrameTexture
print("rightsuccess")
} else if location.x < player!.position.x {
self.player!.texture = leftFrameTexture
print("leftsuccess")
}
}
}

How can I create an onscreen controller that works in multiple scenes in SpriteKit?

Working on a game in SpriteKit to learn. Its a platformer with an onscreen controller. I have this all working using touchesBegan and touchesEnded to know when the player is pushing the buttons or not. This works fine, however when i want to load the next scene for 'level 2' i need to implement the controller all over again. I could do a lot of copy and pasting but I feel this will lead to a lot of duplication of code. Every tutorial I've ever read said to try to adhere to the DRY principle.
Im sorry if this is simple, but I have <6 months programming experience and am trying to learn and improve. Im assuming I would need to create a separate class for the onscreen controller so it can be reused, but Im a little lost on where to start.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = (touch.location(in: playerCamera))
print("LocationX: \(location.x), LocationY: \(location.y)")
let objects = nodes(at: location)
print("\(objects)")
if rightButton.frame.contains(location) {
rightButtonPressed = true
playerFacingRight = true
playerFacingLeft = false
thePlayer.xScale = 1
let animation = SKAction(named: "running")!
let loopingAnimation = SKAction.repeatForever(animation)
thePlayer.run(loopingAnimation, withKey: "moveRight")
moveRight()
} else if leftButton.frame.contains(location) {
leftButtonPressed = true
playerFacingLeft = true
playerFacingRight = false
thePlayer.xScale = -1
let leftAnimation = SKAction(named: "running")!
let leftLoopingAnimation = SKAction.repeatForever(leftAnimation)
thePlayer.run(leftLoopingAnimation, withKey: "moveLeft")
moveLeft()
} else if upButton.frame.contains(location) {
upButtonPressed = true
print("upButton is pressed")
if playerAndButtonContact == true {
print("contact - player + button + upButtonPressed=true")
print("\(movingPlatform.position)")
button.texture = SKTexture(imageNamed: "switchGreen")
let moveRight = SKAction.moveTo(x: -150, duration: 3)
if movingPlatform.position == CGPoint(x: -355, y: movingPlatform.position.y) {
movingPlatform.run(moveRight)
thePlayer.run(moveRight)
button.run(moveRight)
}
}
if playerAndDoorSwitchContact == true {
let switchPressed = SKAction.run{
self.switchPressedSound()
self.doorSwitch.texture = SKTexture(imageNamed: "switchGreen")
self.door.texture = SKTexture(imageNamed: "DoorUnlocked")
}
let wait = SKAction.wait(forDuration: 2)
let doorOpen = SKAction.run {
let doorOpen = SKSpriteNode(imageNamed: "DoorOpen")
doorOpen.alpha = 0
doorOpen.position = self.door.position
doorOpen.size = self.door.size
doorOpen.size = self.door.size
self.door.zPosition = -2
doorOpen.zPosition = -1
let fadeIn = SKAction.fadeIn(withDuration: 0.5)
let start = SKAction.run {
self.addChild(doorOpen)
doorOpen.run(fadeIn)
}
let sound = SKAction.run {
self.doorOpeningSound()
}
let opening = SKAction.group([sound, start])
self.door.run(opening)
}
let sequence = SKAction.sequence([switchPressed, wait, doorOpen])
self.doorSwitch.run(sequence)
}
if playerAndDoorContact == true {
self.view?.presentScene(level1, transition: transition)
}
} else if downButton.frame.contains(location) {
}
else if shoot.frame.contains(location) {
shoot()
} else if jumpButton.frame.contains(location) {
self.pressed = true
let timerAction = SKAction.wait(forDuration: 0.05)
let update = SKAction.run {
if(self.force < Constants.maximumJumpForce) {
self.force += 2.0
} else {
self.jump(force: Constants.maximumJumpForce)
self.force = Constants.maximumJumpForce
}
}
let sequence = SKAction.sequence([timerAction, update])
let repeat_seq = SKAction.repeatForever(sequence)
self.run(repeat_seq, withKey: "repeatAction")
}
}
}

ios Swift - Group separated sprites with syncronized animation

I am trying to make a synchronized animation (a large video decomposed by frames on separated and smaller puzzle jigsaw parts). This game is a video puzzle. Here is the code I use in three parts by way of example:
func Anim_Puzzle13 (Node13 : SKPuzzle) {
let puzzle13 = SKAction.animateWithTextures(sheet_puzzle13.Puzzle13_(), timePerFrame: 0.066)
NPuzzle13 = Node13
NPuzzle13.runAction(SKAction.repeatActionForever(puzzle13))
NPuzzle13.position = CGPoint(x: 500, y: 400)
NPuzzle13.zPosition = 1
}
func Anim_Puzzle19 (Node19 : SKPuzzle) {
let puzzle19 = SKAction.animateWithTextures(sheet_puzzle19.Puzzle19_(), timePerFrame: 0.066)
NPuzzle19 = Node19
NPuzzle19.runAction(SKAction.repeatActionForever(puzzle19))
NPuzzle19.position = CGPoint(x: 600, y: 500)
NPuzzle19.zPosition = 1
}
func Anim_Puzzle30 (Node30 : SKPuzzle) {
let puzzle30 = SKAction.animateWithTextures(sheet_puzzle30.Puzzle30_(), timePerFrame: 0.066)
NPuzzle30 = Node30
NPuzzle30.runAction(SKAction.repeatActionForever(puzzle30))
NPuzzle30.position = CGPoint(x: 700, y: 600)
NPuzzle30.zPosition = 1
}
It works well but it does not synchronize between the animations and the video has no integrity. I searched for a long time for a solution to make the animations synchronize; I see two possibilities: first is to create a unique SKNode() with all the jigsaw parts inside, but I want to be able to move each jigsaw part independently and have had no success getting a synchronized animation with this method.
The other way seem to be to create a group with all the animations together but this doesn't work, and causes the application to stop.
Here is all the code I use:
import SpriteKit
import UIKit
import AVFoundation
import AVKit
import CoreFoundation
private let kpuzzleNodeName = "puzzle"
private let kdancing = "dancing"
class SKPuzzle: SKSpriteNode {
var name2:String = "";
}
class GameScene: SKScene {
var background = SKVideoNode(videoFileNamed: "Video_Socle.mov")
var selectedNode = SKPuzzle()
var player:AVPlayer?
var videoNode:SKVideoNode?
var NPuzzle13 = SKPuzzle()
var NPuzzle19 = SKPuzzle()
var NPuzzle30 = SKPuzzle()
var NPuzzle11 = SKPuzzle()
var NPuzzle29 = SKPuzzle()
var NPuzzle35 = SKPuzzle()
var puzzle13 = SKAction()
var puzzle19 = SKAction()
var puzzle30 = SKAction()
var puzzle11 = SKAction()
var puzzle29 = SKAction()
var puzzle35 = SKAction()
let sheet_puzzle13 = Puzzle13()
let sheet_puzzle19 = Puzzle19()
let sheet_puzzle30 = Puzzle30()
let sheet_puzzle11 = Puzzle11()
let sheet_puzzle29 = Puzzle29()
let sheet_puzzle35 = Puzzle35()
override init(size: CGSize) {
super.init(size: size)
// 1
self.background.name = kdancing
self.background.anchorPoint = CGPointZero
background.zPosition = 0
self.addChild(background)
// 2
let sheet = Statiques()
let sprite_dancing1 = SKSpriteNode(texture: sheet.Dancing1())
let sprite_dancing2 = SKSpriteNode(texture: sheet.Dancing2())
sprite_dancing1.name = kdancing
sprite_dancing2.name = kdancing
sprite_dancing1.position = CGPoint(x: 837, y: 752)
sprite_dancing1.zPosition = 2
sprite_dancing2.position = CGPoint(x: 1241, y: 752)
sprite_dancing2.zPosition = 2
background.addChild(sprite_dancing1)
background.addChild(sprite_dancing2)
let imageNames = [sheet.Puzzle13() , sheet.Puzzle19(), sheet.Puzzle30(), sheet.Puzzle11(), sheet.Puzzle29(), sheet.Puzzle35() ]
for i in 0..<imageNames.count {
let imageName = imageNames[i]
let sprite = SKPuzzle(texture: imageName)
sprite.name = kpuzzleNodeName
sprite.name2 = "\(i)"
let offsetFraction = (CGFloat(i) + 1.0)/(CGFloat(imageNames.count) + 1.0)
sprite.position = CGPoint(x: size.width * offsetFraction, y: size.height / 2)
sprite.zPosition = 3
background.addChild(sprite)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let positionInScene = touch.locationInNode(self)
selectNodeForTouch(positionInScene)
}
}
override func didMoveToView(view: SKView) {
let urlStr = NSBundle.mainBundle().pathForResource("Video_Socle", ofType: "mov")
let url = NSURL(fileURLWithPath: urlStr!)
player = AVPlayer(URL: url)
NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem, queue: nil)
{ notification in
let t1 = CMTimeMake(5, 100);
self.player!.seekToTime(t1)
self.player!.play()
}
videoNode = SKVideoNode(AVPlayer: player!)
videoNode!.position = CGPointMake(frame.size.width/2, frame.size.height/2)
videoNode!.size = CGSize(width: 2048, height: 1536)
videoNode!.zPosition = 0
background.addChild(videoNode!)
videoNode!.play()
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(GameScene.handlePanFrom(_:)))
self.view!.addGestureRecognizer(gestureRecognizer)
}
func handlePanFrom(recognizer : UIPanGestureRecognizer) {
if recognizer.state == .Began {
var touchLocation = recognizer.locationInView(recognizer.view)
touchLocation = self.convertPointFromView(touchLocation)
self.selectNodeForTouch(touchLocation)
} else if recognizer.state == .Changed {
var translation = recognizer.translationInView(recognizer.view!)
translation = CGPoint(x: translation.x, y: -translation.y)
self.panForTranslation(translation)
recognizer.setTranslation(CGPointZero, inView: recognizer.view)
} else if recognizer.state == .Ended {
}
}
func degToRad(degree: Double) -> CGFloat {
return CGFloat(degree / 180.0 * M_PI)
}
func selectNodeForTouch(touchLocation : CGPoint) {
// 1
let touchedNode = self.nodeAtPoint(touchLocation)
if touchedNode is SKPuzzle {
// 2
if !selectedNode.isEqual(touchedNode) {
selectedNode.runAction(SKAction.rotateToAngle(0.0, duration: 0.1))
selectedNode = touchedNode as! SKPuzzle
// 3
if touchedNode.name! == kpuzzleNodeName {
let sequence = SKAction.sequence([SKAction.rotateByAngle(degToRad(-4.0), duration: 0.1),
SKAction.rotateByAngle(0.0, duration: 0.1),
SKAction.rotateByAngle(degToRad(4.0), duration: 0.1)])
selectedNode.runAction(SKAction.repeatActionForever(sequence))
}
}
}
}
func panForTranslation(translation : CGPoint) {
let position = selectedNode.position
if selectedNode.name! == kpuzzleNodeName {
selectedNode.position = CGPoint(x: position.x + translation.x * 2, y: position.y + translation.y * 2)
print (selectedNode.name)
print (selectedNode.name2)
if selectedNode.name2 == "0" {
Anim_Puzzle13(selectedNode)
}
print (selectedNode.name2)
if selectedNode.name2 == "1" {
Anim_Puzzle19(selectedNode)
}
print (selectedNode.name2)
if selectedNode.name2 == "2" {
Anim_Puzzle30(selectedNode)
}
print (selectedNode.name2)
if selectedNode.name2 == "3" {
Anim_Puzzle11(selectedNode)
}
print (selectedNode.name2)
if selectedNode.name2 == "4" {
Anim_Puzzle29(selectedNode)
}
print (selectedNode.name2)
if selectedNode.name2 == "5" {
Anim_Puzzle35(selectedNode)
}
}
}
func Anim_Puzzle13 (Node13 : SKPuzzle) {
let puzzle13 = SKAction.animateWithTextures(sheet_puzzle13.Puzzle13_(), timePerFrame: 0.066)
NPuzzle13 = Node13
NPuzzle13.runAction(SKAction.repeatActionForever(puzzle13))
NPuzzle13.position = CGPoint(x: 500, y: 400)
NPuzzle13.zPosition = 1
}
func Anim_Puzzle19 (Node19 : SKPuzzle) {
let puzzle19 = SKAction.animateWithTextures(sheet_puzzle19.Puzzle19_(), timePerFrame: 0.066)
NPuzzle19 = Node19
NPuzzle19.runAction(SKAction.repeatActionForever(puzzle19))
NPuzzle19.position = CGPoint(x: 600, y: 500)
NPuzzle19.zPosition = 1
}
func Anim_Puzzle30 (Node30 : SKPuzzle) {
let puzzle30 = SKAction.animateWithTextures(sheet_puzzle30.Puzzle30_(), timePerFrame: 0.066)
NPuzzle30 = Node30
NPuzzle30.runAction(SKAction.repeatActionForever(puzzle30))
NPuzzle30.position = CGPoint(x: 700, y: 600)
NPuzzle30.zPosition = 1
}
func Anim_Puzzle11 (Node11 : SKPuzzle) {
let puzzle11 = SKAction.animateWithTextures(sheet_puzzle11.Puzzle11_(), timePerFrame: 0.066)
NPuzzle11 = Node11
NPuzzle11.runAction(SKAction.repeatActionForever(puzzle11))
NPuzzle11.position = CGPoint(x: 800, y: 700)
NPuzzle11.zPosition = 1
}
func Anim_Puzzle29 (Node29 : SKPuzzle) {
let puzzle29 = SKAction.animateWithTextures(sheet_puzzle29.Puzzle29_(), timePerFrame: 0.066)
NPuzzle29 = Node29
NPuzzle29.runAction(SKAction.repeatActionForever(puzzle29))
NPuzzle29.position = CGPoint(x: 900, y: 800)
NPuzzle29.zPosition = 1
}
func Anim_Puzzle35 (Node35 : SKPuzzle) {
let puzzle35 = SKAction.animateWithTextures(sheet_puzzle35.Puzzle35_(), timePerFrame: 0.066)
NPuzzle35 = Node35
NPuzzle35.runAction(SKAction.repeatActionForever(puzzle35))
NPuzzle35.position = CGPoint(x: 1000, y: 900)
NPuzzle35.zPosition = 1
}
}
I'm not sure if it's possible to synchronize animations like this: with SKAction() in several separated parts, because it's necessary to be able to select them individually.
UPDATE: I've tried to follow the action group way but I have the same animation playing on each sprite instead of a different animation synchronized for each sprite (6 different animations synchronized: 6 different sprites):
let sheet13 = Puzzle13()
let sheet19 = Puzzle19()
let sheet30 = Puzzle30()
let sheet11 = Puzzle11()
let sheet29 = Puzzle29()
let sheet35 = Puzzle35()
let imageAnims = [sheet13.Puzzle13_0000() , sheet19.Puzzle19_0000(), sheet30.Puzzle30_0000(), sheet11.Puzzle11_0000(), sheet29.Puzzle29_0000(), sheet35.Puzzle35_0000() ]
let puzzle13 = SKAction.animateWithTextures(sheet13.Puzzle13_(), timePerFrame: 0.066)
let puzzle19 = SKAction.animateWithTextures(sheet19.Puzzle19_(), timePerFrame: 0.066)
let puzzle30 = SKAction.animateWithTextures(sheet30.Puzzle30_(), timePerFrame: 0.066)
let puzzle11 = SKAction.animateWithTextures(sheet11.Puzzle11_(), timePerFrame: 0.066)
let puzzle29 = SKAction.animateWithTextures(sheet29.Puzzle29_(), timePerFrame: 0.066)
let puzzle35 = SKAction.animateWithTextures(sheet35.Puzzle35_(), timePerFrame: 0.066)
let group = SKAction.group([puzzle13,puzzle19,puzzle30,puzzle11,puzzle29,puzzle35])
for i in 0..<imageAnims.count {
let imageAnim = imageAnims[i]
let spriteAnim = SKPuzzle(texture: imageAnim)
spriteAnim.name = kanimNodeName
spriteAnim.name2 = "\(i)"
let offsetFraction = (CGFloat(i) + 1.0)/(CGFloat(imageAnims.count) + 1.0)
spriteAnim.position = CGPoint(x: ((size.width)*2) * offsetFraction, y: size.height * 1.5)
spriteAnim.zPosition = 3
spriteAnim.runAction(SKAction.repeatActionForever(group))
background.addChild(spriteAnim)
}
First of all I want to list two differents method to create your SKAction:
Starting with parallel actions by using SKAction.group:
let sprite = SKSpriteNode(imageNamed:"Spaceship")
let scale = SKAction.scaleTo(0.1, duration: 0.5)
let fade = SKAction.fadeOutWithDuration(0.5)
let group = SKAction.group([scale, fade])
sprite.runAction(group)
Another useful method can be the completion , so you can know when an SKAction was finished:
extension SKNode
{
func runAction( action: SKAction!, withKey: String!, optionalCompletion: dispatch_block_t? )
{
if let completion = optionalCompletion
{
let completionAction = SKAction.runBlock( completion )
let compositeAction = SKAction.sequence([ action, completionAction ])
runAction( compositeAction, withKey: withKey )
}
else
{
runAction( action, withKey: withKey )
}
}
}
Usage:
node.runAction(move,withKey:"swipeMove",optionalCompletion: {
// here the action is finished, do whatever you want
})
After that, about your project, I've seen many node.runAction.., you can also adopt this strategy to sinchronize your actions:
var myAction30 :SKAction!
var myAction31 :SKAction!
self.myAction30 = SKAction.repeatActionForever(puzzle30)
self.myAction31 = SKAction.repeatActionForever(puzzle31)
let group = SKAction.group([self.myAction30, self.myAction31])
self.runAction(group)
UPDATE: I've seen your update part, when you speak about "synchronize" probably you don't means the "running in parallel" actions.
So, if you want to run an action after another there is also:
self.myAction30 = SKAction.repeatActionForever(puzzle30)
self.myAction31 = SKAction.repeatActionForever(puzzle31)
let sequence = SKAction.sequence([self.myAction30, self.myAction31])
self.runAction(sequence)

How to make objects exempt from SKcameranode movement

I'm currently developing a scrolling platformer game, and I was wondering how I could have the joystick object move along with the screen but still be useable. Ive tried a number of things, but none of them have produced any viable options. At the moment, the joystick is usable but will scroll off the screen with the rest of the map.
Here is my code:
import SpriteKit
import UIKit
var map = SKNode()
var idleFrames = [SKTexture]()
var walkFrames = [SKTexture]()
var idleFrames1 = [SKTexture]()
var walkFrames1 = [SKTexture]()
var attackFrames1 = [SKTexture]()
var idling = 0
var bullets = 0
var bullet = SKSpriteNode()
var leaf = SKEmitterNode()
var hud: SKSpriteNode?
class GameScene: SKScene, SKPhysicsContactDelegate {
var sp33d: CGVector = CGVectorMake(0.0,0.0)
var knock: CGVector = CGVectorMake(-10.0, 0.0)
var knock1: CGVector = CGVectorMake(10.0, 0.0)
var jsp33d: CGFloat = 170
var gameStick: Joystick?
var player: SKSpriteNode?
var ground: SKSpriteNode?
var ground2: SKSpriteNode?
var ground3: SKSpriteNode?
var canJump = false
var specialbutton = SKSpriteNode(imageNamed: "special")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
hud = self.childNodeWithName("hud") as? SKSpriteNode
gameStick = Joystick()
gameStick?.createJoystick(hud!.frame.width/4, nameBack: "joystick", nameMoving: "joystick1")
gameStick!.backPart!.zPosition = 4
gameStick!.movingPart!.zPosition = 5
map.addChild(gameStick!.backPart!)
map.addChild(gameStick!.movingPart!)
self.addChild(map)
player = self.childNodeWithName("player") as? SKSpriteNode
ground = self.childNodeWithName("testGround") as? SKSpriteNode
ground2 = self.childNodeWithName("testGround2") as? SKSpriteNode
player?.physicsBody?.categoryBitMask = category.player
ground?.physicsBody?.categoryBitMask = category.ground
ground2?.physicsBody?.categoryBitMask = category.ground
player?.physicsBody?.collisionBitMask = category.ground
ground?.physicsBody?.collisionBitMask = category.player
player!.position = CGPoint(x: CGRectGetMidX(self.frame), y: 70)
specialbutton.position = CGPointMake(600, 83)
specialbutton.xScale = 0.165
specialbutton.yScale = 0.165
specialbutton.alpha = 0.5
map.addChild(specialbutton)
camera = self.childNodeWithName("camera") as? SKCameraNode
camera?.position = player!.position
if charnumber == 2{
player?.texture = SKTexture(imageNamed:"Sarah")
}
let idleAtlas = SKTextureAtlas(named: "idle.atlas")
var idleframes = [SKTexture]()
for var i=1; i<=4; i++ {
let idleframe = "JohnIdle\(i)"
idleframes.append(idleAtlas.textureNamed(idleframe))
}
idleFrames = idleframes
let walkAtlas = SKTextureAtlas(named: "jrun.atlas")
var walkframes = [SKTexture]()
for var i=1; i<=8; i++ {
let walkframe = "Johnrun\(i)"
walkframes.append(walkAtlas.textureNamed(walkframe))
}
walkFrames = walkframes
let idleAtlas1 = SKTextureAtlas(named: "Sarahidle.atlas")
var idleframes1 = [SKTexture]()
for var i=1; i<=4; i++ {
let idleframe1 = "SarahIdle\(i)"
idleframes1.append(idleAtlas1.textureNamed(idleframe1))
}
idleFrames1 = idleframes1
let walkAtlas1 = SKTextureAtlas(named: "Sarahrun.atlas")
var walkframes1 = [SKTexture]()
for var i=1; i<=8; i++ {
let walkframe1 = "Sarahrun\(i)"
walkframes1.append(walkAtlas1.textureNamed(walkframe1))
}
walkFrames1 = walkframes1
let attackAtlas1 = SKTextureAtlas(named: "sattack.atlas")
var attackframes1 = [SKTexture]()
for var i=1; i<=9; i++ {
let attackframe1 = "sattack\(i)"
attackframes1.append(attackAtlas1.textureNamed(attackframe1))
}
attackFrames1 = attackframes1
self.physicsWorld.gravity = CGVectorMake(0, -10.0)
self.physicsWorld.contactDelegate = self
}
func didBeginContact(contact:SKPhysicsContact) {
if (contact.bodyA.categoryBitMask == category.player) && (contact.bodyB.categoryBitMask == category.ground) {
idling = 0
johnmove()
print("hit")
canJump = true
}else{
}
}
func didEndContact(contact: SKPhysicsContact) {
if (contact.bodyA.categoryBitMask == category.player) && (contact.bodyB.categoryBitMask == category.ground) {
canJump = false
}
}
func bulletfire(){
bullet = SKSpriteNode(imageNamed: "bullet1")
leaf = SKEmitterNode(fileNamed: "leafParticle")!
bullets = bullets + 1
bullet.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(0.1, 0.1))
bullet.physicsBody?.collisionBitMask = category.ground
bullet.xScale = 0.016
bullet.yScale = 0.016
bullet.physicsBody?.affectedByGravity = false
self.addChild(bullet)
self.addChild(leaf)
if player?.xScale == 1{
bullet.xScale = -0.016
bullet.position.x = (player?.position.x)! + 21.5
bullet.position.y = (player?.position.y)! + 15.4
bullet.physicsBody?.velocity = (CGVectorMake(1000.0, 0.0))
}else{
bullet.position.x = (player?.position.x)! - 21.5
bullet.position.y = (player?.position.y)! + 15.4
bullet.physicsBody?.velocity = (CGVectorMake(-1000.0, 0.0))
}
let action = SKAction.sequence([SKAction.waitForDuration(1), SKAction.removeFromParent()])
bullet.runAction(action, completion: {bullets = bullets - 1})
leaf.runAction(action)
}
func move(){
if player?.xScale == 1 {
player?.size = CGSizeMake(80,80)
player?.position.x = (player?.position.x)! - 20
}else{
player?.size = CGSizeMake(80,80)
player?.position.x = (player?.position.x)! + 20
}
}
func johnmove() {
if charnumber == 1 {
if idling == 1 {
player?.size = CGSizeMake(80,80)
player?.removeActionForKey("idle")
player?.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(walkFrames, timePerFrame: 0.12, resize: false, restore: true)),withKey: "walk")
}
else if idling == 0 {
player?.removeActionForKey("walk")
player?.size = CGSizeMake(80,80)
player?.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(idleFrames, timePerFrame: 0.6, resize: false, restore: true)),withKey: "idle")
}else if idling == 2 {
player?.removeActionForKey("walk")
player?.removeActionForKey("idle")
player?.size = CGSizeMake(80,80)
player?.texture = SKTexture(imageNamed: "JohnJump.png")
}
}else{
sarahhmove()
}
}
func sarahhmove() {
if idling == 1 {
player?.removeActionForKey("idle1")
player?.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(walkFrames1, timePerFrame: 0.12, resize: true, restore: true)),withKey: "walk1")
}
else if idling == 0 {
player?.removeActionForKey("walk1")
player?.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(idleFrames1, timePerFrame: 0.6, resize: false, restore: true)),withKey: "idle1")
}else if idling == 2 {
player?.removeActionForKey("wal1k")
player?.removeActionForKey("idle1")
player?.texture = SKTexture(imageNamed: "SarahJump.png")
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in (touches ) {
let location = touch.locationInNode(self)
var nodeTouched = SKNode()
nodeTouched = self.nodeAtPoint(location)
if nodeTouched.name == "joystick1" {
gameStick?.movingPart?.position = location
if location.x > gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2, gameStick!.movingPart!.position.y)
}
if location.y > gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.movingPart!.position.x, gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2)
}
}
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in (touches ) {
let location = touch.locationInNode(self)
var nodeTouched = SKNode()
nodeTouched = self.nodeAtPoint(location)
if nodeTouched.name == "joystick1" {
gameStick?.movingPart?.position = location
if location.x > gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.backPart!.position.x + gameStick!.backPart!.frame.width/2, gameStick!.movingPart!.position.y)
}
if location.y > gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2{
gameStick?.movingPart?.position = CGPointMake(gameStick!.movingPart!.position.x, gameStick!.backPart!.position.y + gameStick!.backPart!.frame.height/2)
}
}else if idling == 0 && charnumber == 2{
player?.size = CGSizeMake(80,80)
player?.removeAllActions()
if player?.xScale == 1 {
player?.size = CGSizeMake(80,80)
player?.position.x = (player?.position.x)! + 20
}else{
player?.size = CGSizeMake(80,80)
player?.position.x = (player?.position.x)! - 20
}
player?.size = CGSizeMake(80,80)
player?.runAction(SKAction.repeatAction(SKAction.animateWithTextures(attackFrames1, timePerFrame: 0.09, resize: true, restore: true),count: 1),completion: {self.move()})
player?.size = CGSizeMake(80,80)
player?.texture = SKTexture(imageNamed: "Sarah")
}else if charnumber == 1 && idling == 0{
player?.removeAllActions()
bulletfire()
let yrand = (arc4random_uniform(100) + 50)
let xrand = (arc4random_uniform(300) + 80)
let cartridge = SKSpriteNode(imageNamed: "casing")
cartridge.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(0.1, 0.1))
cartridge.physicsBody?.collisionBitMask = category.ground
cartridge.xScale = 0.05
cartridge.yScale = 0.05
cartridge.zPosition = 3
cartridge.physicsBody?.restitution = 0.5
let spin = SKAction.rotateByAngle(CGFloat(M_PI), duration:0.6)
cartridge.runAction(SKAction.repeatActionForever(spin))
cartridge.physicsBody?.dynamic = true
let flash = SKEmitterNode(fileNamed: "muzzleFlash")
if player?.xScale == 1{
leaf.xScale = -1
flash?.position.x = (player?.position.x)! + 40
flash?.position.y = (player?.position.y)! + 15.3
cartridge.position.x = (player?.position.x)! + 27
cartridge.position.y = (player?.position.y)! + 15.3
player?.physicsBody?.applyImpulse(knock)
cartridge.physicsBody?.velocity = CGVectorMake(-CGFloat(yrand), CGFloat(xrand))
}else{
flash?.position.x = (player?.position.x)! - 40
flash?.position.y = (player?.position.y)! + 15.3
flash?.xAcceleration = -5000
cartridge.position.x = (player?.position.x)! - 27
cartridge.position.y = (player?.position.y)! + 15.3
player?.physicsBody?.applyImpulse(knock1)
cartridge.physicsBody?.velocity = CGVectorMake(CGFloat(yrand), CGFloat(xrand))
}
flash?.zPosition = 3
flash?.xScale = 0.15
flash?.yScale = 0.15
self.addChild(flash!)
self.addChild(cartridge)
let action = SKAction.sequence([SKAction.waitForDuration(0.15), SKAction.removeFromParent()])
let action1 = SKAction.sequence([SKAction.waitForDuration(1.5), SKAction.removeFromParent()])
flash?.runAction(action)
cartridge.runAction(action1)
johnmove()
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in (touches ) {
let location = touch.locationInNode(self)
var nodeTouched = SKNode()
nodeTouched = self.nodeAtPoint(location)
if nodeTouched.name == "joystick1" {
let act = SKAction.moveTo(gameStick!.backPart!.position, duration: 0.2)
gameStick?.movingPart?.runAction(act)
}
}
}
override func update(currentTime: CFTimeInterval) {
hud!.position = (camera?.position)!
let action = SKAction.moveTo((player?.position)!, duration: 0.01)
camera!.runAction(action)
player?.size = CGSizeMake(80,80)
leaf.position = bullet.position
print(canJump)
if (sp33d.dx > 1.5 || sp33d.dx < -1.5) && idling != 1 && idling != 2 {
idling = 1
johnmove()
}else if sp33d.dx < 0.1 && sp33d.dx > -0.1 && idling != 0 && idling != 2{
idling = 0
johnmove()
}
if sp33d.dx > 0.1 {
player!.xScale = 1
} else if sp33d.dx < -0.1 {
player!.xScale = -1
}
/* Called before each frame is rendered */
let vX = gameStick!.movingPart!.position.x - gameStick!.backPart!.position.x
let vY: CGFloat = gameStick!.movingPart!.position.y
if vY > gameStick!.backPart!.position.y + 20 && canJump == true{
sp33d = CGVectorMake(vX/13, jsp33d)
idling = 2
johnmove()
}else{
sp33d = CGVectorMake(vX/13, 0)
}
player?.physicsBody?.applyImpulse(sp33d)
}
}
This is the class in which the joystick is created:
import Foundation
import UIKit
import SpriteKit
class Joystick: UIView {
var movingPart: SKSpriteNode?
var backPart: SKSpriteNode?
let speed: CGFloat = 0.4
var joyStickCenter: CGPoint?
func createJoystick(dimensions: CGFloat, nameBack: String, nameMoving: String)
{
backPart = SKSpriteNode(imageNamed: "joystick")
backPart?.size = CGSizeMake(dimensions, dimensions)
backPart?.position = CGPoint(x: backPart!.size.width/2, y: backPart!.size.width/2)
backPart?.name = nameBack
backPart?.alpha = 0.4
movingPart = SKSpriteNode(imageNamed: "joystick")
movingPart?.size = CGSizeMake(dimensions*0.5, dimensions*0.5)
movingPart?.position = backPart!.position
movingPart?.name = nameMoving
movingPart?.alpha = 0.8
joyStickCenter = backPart!.position
}
func getDistance(p1: CGPoint, p2: CGPoint) -> Double
{
let firstPow = p2.x-p1.x
let secondPow = p2.y-p1.y
var squaredAdded = pow(firstPow, 2)
squaredAdded += pow(secondPow, 2)
let theSquirt = sqrt(Double(squaredAdded))
return theSquirt
}
func resetMovingPart()
{
movingPart?.runAction(SKAction.moveTo(joyStickCenter!, duration: 0.4))
}
func calcXYDiff(loc: CGPoint) -> CGPoint
{
let oldMovingPartPoint = movingPart?.position
movingPart?.position = loc
if movingPart!.position.x-joyStickCenter!.x > backPart!.frame.width/2
{
movingPart?.position.x = oldMovingPartPoint!.x
}
if movingPart!.position.y-joyStickCenter!.y > backPart!.frame.height/2
{
movingPart?.position.y = oldMovingPartPoint!.y
}
let x = loc.x - joyStickCenter!.x
let y = loc.y - joyStickCenter!.y
return CGPoint(x: x*speed, y: y*speed)
}
Any help would be greaty appreciated.
Thanks in advance!
Try calling the resetMovingPart() in your update() func.

Resources