Adding buttons with touchBegan - swift

I playing around with a Swift game from GitHub. I am attempting to add another button to the touchesBegan (newButton). Here is what I got so far:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard !gameOver else {
let gameOverLayer = childNodeWithName(StickHeroGameSceneChildName.GameOverLayerName.rawValue) as SKNode?
let location = touches.first?.locationInNode(gameOverLayer!)
let retry = gameOverLayer!.nodeAtPoint(location!)
if (retry.name == StickHeroGameSceneChildName.RetryButtonName.rawValue) {
print("Retry")
NSNotificationCenter.defaultCenter().postNotificationName("hideBanner", object: nil)
retry.runAction(SKAction.sequence([SKAction.setTexture(SKTexture(imageNamed: "button_retry_down"), resize: false), SKAction.waitForDuration(0.3)]), completion: {[unowned self] () -> Void in
self.restart()
})
}
return
}
guard !gameOver else {
let gameOverLayer2 = childNodeWithName(StickHeroGameSceneChildName.GameOverLayerName.rawValue) as SKNode?
let location2 = touches.first?.locationInNode(gameOverLayer2!)
let games = gameOverLayer2!.nodeAtPoint(location2!)
if (newButton.name == StickHeroGameSceneChildName.GamesButtonName.rawValue) {
print("New Button")
}
}
return
}
Here is the code for the buttons:
let retry = SKSpriteNode(imageNamed: "button_retry_up")
retry.name = StickHeroGameSceneChildName.RetryButtonName.rawValue
retry.position = CGPointMake(0, -180)
node.addChild(retry)
let newButton = SKSpriteNode(imageNamed: "button_games_up")
newButton.name = StickHeroGameSceneChildName.GamesButtonName.rawValue
newButton.position = CGPointMake(0, -360)
node.addChild(newButton)
There is the GitHub: https://github.com/phpmaple/Stick-Hero-Swift
I'm pretty new at Swift and need a little guidance. Thanks.

Related

How do I save the user's level on my game?

I have a maze game that I coded with swift that does not save levels. Currently, when the user closes the app, nothing is saved and the user has to start playing the game from level 1 again. I have a different .swift and .sks file for every level, so I am not sure how to save level data across classes/files.
I have tried to use UserDefaults, however, I am not sure how to save the "file path" to my level. I know that I need to implement something in my AppDelegate (using the applicationWillTerminate or applicationDidEnterBackground func), however, I am not sure what code (if any) I need to put in the scenes themselves to save this data. I have not worked with saving user data before, so help would be greatly appreciated!
import SpriteKit
import GameplayKit
import CoreMotion
import SceneKit
import UIKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let gameScene = SKScene()
var button: SKNode! = nil
var playerSprite = SKSpriteNode()
var nextNode = SKSpriteNode()
lazy var countdownLabel: SKLabelNode = {
var label = SKLabelNode(fontNamed: "Helvetica")
label.horizontalAlignmentMode = .center
label.verticalAlignmentMode = .center
label.color = UIColor.red
label.text = "\(counter)"
return label
}()
var counter = 30
var counterTimer = Timer()
var counterStartValue = 30
let motionManager = CMMotionManager()
override func didMove(to view: SKView) {
self.scene?.scaleMode = SKSceneScaleMode.aspectFit
button = SKSpriteNode(imageNamed: "redoButton")
button.position = CGPoint(x: 350, y: 585);
self.addChild(button)
countdownLabel.position = CGPoint(x: 0.5, y: 0.5)
addChild(countdownLabel)
counter = counterStartValue
runTimer()
self.physicsWorld.contactDelegate = self
playerSprite = self.childNode(withName: "playerSprite") as! SKSpriteNode
nextNode = self.childNode(withName: "nextNode") as! SKSpriteNode
motionManager.startAccelerometerUpdates()
motionManager.accelerometerUpdateInterval = 0.1
motionManager.startAccelerometerUpdates(to: OperationQueue.main) {
(data,error) in
self.physicsWorld.gravity = CGVector(dx: CGFloat((data?.acceleration.x)!) * 10, dy: CGFloat((data?.acceleration.y)!) * 10)
}
}
func didBegin(_ contact: SKPhysicsContact) {
let bodyA = contact.bodyA
let bodyB = contact.bodyB
if bodyA.categoryBitMask == 1 && bodyB.categoryBitMask == 2 || bodyA.categoryBitMask == 2 && bodyB.categoryBitMask == 1{
playerSprite.removeFromParent()
nextNode.removeFromParent()
self.removeFromParent()
let transition = SKTransition.fade(withDuration: 0.5)
let gameScene2 = GameScene2(fileNamed: "GameScene2")
gameScene2!.scaleMode = SKSceneScaleMode.aspectFit
self.view?.presentScene(gameScene2!, transition: transition)
}
}
func runTimer() {
counterTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(decrementCounter), userInfo: nil, repeats: true)
}
#objc func decrementCounter() {
counter -= 1
countdownLabel.text = "\(counter)"
if countdownLabel.text! < "0" as String {
countdownLabel.text = "Game Over"
playerSprite.removeFromParent()
nextNode.removeFromParent()
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
if touch.view == self.button {
print("Yay!!!")
} else {
playerSprite.isHidden = false
nextNode.isHidden = false
let gameScene = GameScene(fileNamed: "GameScene")
gameScene!.scaleMode = SKSceneScaleMode.aspectFit
let transition = SKTransition.fade(withDuration: 0.5)
self.view?.presentScene(gameScene!, transition: transition)
}
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
save it with a string
UserDefaults.standard.set(StateOftheGame, forKey: "levelPass")
then on app delegate check if the user 'passLevel' when the game starts
in
didFinishLaunchingWithOptions -> add function passLevel()
func passLevel() {
if UserDefaults.standard.value(forKey: "levelPass") != nil
{
let VC = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "YOURVIEWCONTROLLERWITHSAVESTATE")
let navVC = UINavigationController(rootViewController: VC)
let share = UIApplication.shared.delegate as? AppDelegate
share?.window?.rootViewController = navVC
share?.window?.makeKeyAndVisible()
}
}

SKSpriteNode and SKAction with animating sprite

Im trying to get the player sprite in my game to animate according to what it is doing, ie.. walking, attacking, resting.
I have the following files AgentNode and GameScene.
The sprite spawns and moves around as I want, just with the initial action that was in place when the sprite was added to the scene.
for example if I add the sprite with the "restingFrames" animation, it spawns correctly but when the sprite is moved, the animation is still using "restingFrames" and not "walkingFrames" as I want. Can't figure it out, please help.
AgentNode.swift
import SpriteKit
import GameplayKit
class AgentNode: SKNode, GKAgentDelegate {
var agent = GKAgent2D()
var triangleShape = SKShapeNode()
var player = SKSpriteNode()
var walkingFrames: [SKTexture] = []
var restingFrames: [SKTexture] = []
var attackingFrames: [SKTexture] = []
var firstFrameTexture: SKTexture = SKTexture()
var playerSpawned = false
override init() {
super.init()
}
init(scene:SKScene, radius: Float, position: CGPoint) {
super.init()
self.position = position
self.zPosition = 10
scene.addChild(self)
agent.radius = radius
agent.position = simd_float2(Float(position.x), Float(position.y))
agent.delegate = self
agent.maxSpeed = 100 * 2
agent.maxAcceleration = 500 * 4
}
func setupPlayer() {
setupRestingPlayerAnimation()
setupWalkingPlayerAnimation()
setupAttackingPlayerAnimation()
}
func setupWalkingPlayerAnimation() {
let walkingPlayerAtlas = SKTextureAtlas(named: "WalkingPlayer")
let numImages = walkingPlayerAtlas.textureNames.count
for i in 1...numImages {
let walkingPlayerTextureName = "walk_front\(i)"
walkingFrames.append(walkingPlayerAtlas.textureNamed(walkingPlayerTextureName))
}
}
func setupRestingPlayerAnimation() {
let restingPlayerAtlas = SKTextureAtlas(named: "RestingPlayer")
let numImages = restingPlayerAtlas.textureNames.count
for i in 1...numImages {
let restingPlayerTextureName = "still_frame\(i)"
restingFrames.append(restingPlayerAtlas.textureNamed(restingPlayerTextureName))
}
}
func setupAttackingPlayerAnimation() {
let attackingPlayerAtlas = SKTextureAtlas(named: "AttackingPlayer")
let numImages = attackingPlayerAtlas.textureNames.count
for i in 1...numImages {
let attackingPlayerTextureName = "attack_frame\(i)"
attackingFrames.append(attackingPlayerAtlas.textureNamed(attackingPlayerTextureName))
}
}
func animatePlayer() {
var restingSequence = SKAction()
var walkingSequence = SKAction()
var attackingSequence = SKAction()
let restingAnimation = SKAction.animate(with: restingFrames, timePerFrame: 0.15)
let walkingAnimation = SKAction.animate(with: walkingFrames, timePerFrame: 0.1)
let attackingAnimation = SKAction.animate(with: attackingFrames, timePerFrame: 0.1)
restingSequence = SKAction.sequence([restingSequence])
walkingSequence = SKAction.sequence([walkingSequence])
attackingSequence = SKAction.sequence([attackingSequence])
if isSeeking && !isAttacking{
firstFrameTexture = walkingFrames[0]
player.run(SKAction.repeatForever(walkingAnimation), withKey: "walkingAction")
print("walking")
} else if isAttacking && !isSeeking {
firstFrameTexture = attackingFrames[0]
player.run(SKAction.repeatForever(attackingAnimation), withKey: "attackingAction")
print("attacking")
} else {
firstFrameTexture = restingFrames[0]
player.run(SKAction.repeatForever(restingAnimation), withKey: "restingAction")
print("resting")
}
}
func addPlayerToScene() {
player = SKSpriteNode(texture: firstFrameTexture)
player.position = CGPoint(x: (frame.midX), y: (frame.midY))
player.setScale(1.5)
player.zRotation = CGFloat(Double.pi / 2.0)
player.zPosition = 10
self.addChild(player)
playerSpawned = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func agentWillUpdate(_ agent: GKAgent) {
}
func agentDidUpdate(_ agent: GKAgent) {
if playerSpawned == false {
print("player has not spawned")
setupPlayer()
animatePlayer()
addPlayerToScene()
playerSpawned = true
} else {
print("player has spawned")
animatePlayer()
}
print("player isSeeking \(isSeeking)")
print("player isAttacking \(isAttacking)")
guard let agent2D = agent as? GKAgent2D else {
return
}
self.position = CGPoint(x: CGFloat(agent2D.position.x), y: CGFloat(agent2D.position.y))
self.zRotation = CGFloat(agent2D.rotation)
}
}
GameScene.swift
import SpriteKit
import GameplayKit
var isSeeking: Bool = false
var isAttacking: Bool = false
class GameScene: SKScene {
let trackingAgent = GKAgent2D()
var player = AgentNode()
var seekGoal : GKGoal = GKGoal()
let stopGoal = GKGoal(toReachTargetSpeed: 0.0)
var seeking : Bool = false {
willSet {
if newValue {
self.player.agent.behavior?.setWeight(5, for: seekGoal)
self.player.agent.behavior?.setWeight(0, for: stopGoal)
} else {
self.player.agent.behavior?.setWeight(0, for: seekGoal)
self.player.agent.behavior?.setWeight(5, for: stopGoal)
}
}
}
var agentSystem = GKComponentSystem()
var lastUpdateTime: TimeInterval = 0
override func didMove(to view: SKView) {
super.didMove(to: view)
self.trackingAgent.position = simd_float2(Float(self.frame.midX), Float(self.frame.midY))
self.agentSystem = GKComponentSystem(componentClass: GKAgent2D.self)
self.player = AgentNode(scene: self, radius: Float(20.0), position: CGPoint(x: self.frame.midX, y: self.frame.midY))
self.player.agent.behavior = GKBehavior()
self.agentSystem.addComponent(self.player.agent)
self.seekGoal = GKGoal(toSeekAgent: self.trackingAgent)
}
override func update(_ currentTime: CFTimeInterval) {
isSeeking = self.seeking
if lastUpdateTime == 0 {
lastUpdateTime = currentTime
}
let delta = currentTime - lastUpdateTime
lastUpdateTime = currentTime
self.agentSystem.update(deltaTime: delta)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = true
handleTouch(touches: touches)
}
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
self.seeking = false
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = false
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouch(touches: touches)
}
func handleTouch(touches:Set<UITouch>) {
guard let touch = touches.first
else {
return
}
let location = touch.location(in: self)
self.trackingAgent.position = simd_float2(Float(location.x), Float(location.y))
}
}
Well I figured it out. I updated the code as follows and everything is working great.
AgentNode.swift
import SpriteKit
import GameplayKit
class AgentNode: SKNode, GKAgentDelegate {
var agent = GKAgent2D()
var triangleShape = SKShapeNode()
var player = SKSpriteNode()
var walkingFrames: [SKTexture] = []
var restingFrames: [SKTexture] = []
var attackingFrames: [SKTexture] = []
var playerSpawned = false
override init() {
super.init()
}
init(scene:SKScene, radius: Float, position: CGPoint) {
super.init()
self.position = position
self.zPosition = 10
scene.addChild(self)
agent.radius = radius
agent.position = simd_float2(Float(position.x), Float(position.y))
agent.delegate = self
agent.maxSpeed = 100 * 2
agent.maxAcceleration = 500 * 4
}
func setupPlayer() {
setupRestingPlayerAnimation()
setupWalkingPlayerAnimation()
setupAttackingPlayerAnimation()
}
func setupWalkingPlayerAnimation() {
let walkingPlayerAtlas = SKTextureAtlas(named: "WalkingPlayer")
let numImages = walkingPlayerAtlas.textureNames.count
for i in 1...numImages {
let walkingPlayerTextureName = "walk_front\(i)"
walkingFrames.append(walkingPlayerAtlas.textureNamed(walkingPlayerTextureName))
}
}
func setupRestingPlayerAnimation() {
let restingPlayerAtlas = SKTextureAtlas(named: "RestingPlayer")
let numImages = restingPlayerAtlas.textureNames.count
for i in 1...numImages {
let restingPlayerTextureName = "still_frame\(i)"
restingFrames.append(restingPlayerAtlas.textureNamed(restingPlayerTextureName))
}
}
func setupAttackingPlayerAnimation() {
let attackingPlayerAtlas = SKTextureAtlas(named: "AttackingPlayer")
let numImages = attackingPlayerAtlas.textureNames.count
for i in 1...numImages {
let attackingPlayerTextureName = "attack_frame\(i)"
attackingFrames.append(attackingPlayerAtlas.textureNamed(attackingPlayerTextureName))
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func agentWillUpdate(_ agent: GKAgent) {
}
func agentDidUpdate(_ agent: GKAgent) {
guard let agent2D = agent as? GKAgent2D else {
return
}
self.position = CGPoint(x: CGFloat(agent2D.position.x), y: CGFloat(agent2D.position.y))
self.zRotation = CGFloat(agent2D.rotation)
}
}
GameScene.swift
import SpriteKit
import GameplayKit
var isSeeking: Bool = false
var isAttacking: Bool = false
class GameScene: SKScene {
let trackingAgent = GKAgent2D()
var player = AgentNode()
var seekGoal : GKGoal = GKGoal()
let stopGoal = GKGoal(toReachTargetSpeed: 0.0)
var seeking : Bool = false {
willSet {
if newValue {
self.player.agent.behavior?.setWeight(5, for: seekGoal)
self.player.agent.behavior?.setWeight(0, for: stopGoal)
} else {
self.player.agent.behavior?.setWeight(0, for: seekGoal)
self.player.agent.behavior?.setWeight(5, for: stopGoal)
}
}
}
var agentSystem = GKComponentSystem()
var lastUpdateTime: TimeInterval = 0
override func didMove(to view: SKView) {
super.didMove(to: view)
self.trackingAgent.position = simd_float2(Float(self.frame.midX), Float(self.frame.midY))
self.agentSystem = GKComponentSystem(componentClass: GKAgent2D.self)
self.player = AgentNode(scene: self, radius: Float(20.0), position: CGPoint(x: self.frame.midX, y: self.frame.midY))
self.player.agent.behavior = GKBehavior()
self.agentSystem.addComponent(self.player.agent)
self.seekGoal = GKGoal(toSeekAgent: self.trackingAgent)
player.setupPlayer()
//player.animatePlayer()
player.player = SKSpriteNode(imageNamed: "default_pose")
player.player.position = CGPoint(x: (frame.midX), y: (frame.midY))
player.player.setScale(1.5)
player.player.zRotation = CGFloat(Double.pi / 2.0)
player.player.zPosition = 10
player.player.run(SKAction.repeatForever(SKAction.animate(with: player.restingFrames, timePerFrame: 0.2)))
player.addChild(player.player)
}
override func update(_ currentTime: CFTimeInterval) {
isSeeking = self.seeking
if lastUpdateTime == 0 {
lastUpdateTime = currentTime
}
let delta = currentTime - lastUpdateTime
lastUpdateTime = currentTime
self.agentSystem.update(deltaTime: delta)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = true
player.player.run(SKAction.repeatForever(SKAction.animate(with: player.walkingFrames, timePerFrame: 0.1)))
handleTouch(touches: touches)
}
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
self.seeking = false
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.seeking = false
player.player.removeAllActions()
player.player.run(SKAction.repeatForever(SKAction.animate(with: player.attackingFrames, timePerFrame: 0.1)))
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
handleTouch(touches: touches)
}
func handleTouch(touches:Set<UITouch>) {
guard let touch = touches.first
else {
return
}
let location = touch.location(in: self)
self.trackingAgent.position = simd_float2(Float(location.x), Float(location.y))
}
}

Spawning different nodes randomly

I'm currently in the process of creating a new game that will feature two different balls/bubbles (a player and a enemy). I'm trying to get both of these to spawn randomly at different times kinda like this (ex. player, enemy, player, player, etc.(not in any order)) but random as the game goes on and after the player restarts the game. I'm having trouble trying to find a solution. I've tried a switch case but only either the player or enemy will spawn per game. Does anyone have a solution? If any other code is needed, I will provide it.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
if (gamestarted == false) {
gamestarted = true
/*Player and Enemy random spawner*/
ballSwitchCase()
/*Tap to start*/
tts.removeFromParent()
} else {
/*removed unnecessary code for question*/
}
func mainBallSpawner() {
/*Main ball*/
let spawn = SKAction.runBlock({
()in
self.creatingTheBall()
})
let delay = SKAction.waitForDuration(3.0)
let spawnDelay = SKAction.sequence([spawn, delay])
let spawnDelayForever = SKAction.repeatActionForever(spawnDelay)
self.runAction(spawnDelayForever, withKey: "spawnDelayForever")
let distance = CGFloat(self.frame.height + 170 + gameBall.frame.width)
let moveBalls = SKAction.moveToY(-distance, duration: NSTimeInterval(0.008 * distance))
let removeBalls = SKAction.removeFromParent()
moveAndRemoveBalls = SKAction.sequence([moveBalls, removeBalls])
}
func enemySpawner() {
/*Enemy*/
let spawnEnemy = SKAction.runBlock({
()in
self.creatingEnemyBall()
})
let delayEnemy = SKAction.waitForDuration(3.0)
let spawnDelayEnemy = SKAction.sequence([spawnEnemy, delayEnemy])
let spawnDelayEnemyForever = SKAction.repeatActionForever(spawnDelayEnemy)
self.runAction(spawnDelayEnemyForever, withKey: "spawnDelayEnemyForever")
let enemyDistance = CGFloat(self.frame.height + 170 + enemyBall.frame.width)
let moveEnemy = SKAction.moveToY(-enemyDistance, duration: NSTimeInterval(0.008 * enemyDistance))
let removeEnemy = SKAction.removeFromParent()
moveAndRemoveEnemy = SKAction.sequence([moveEnemy, removeEnemy])
}
func ballSwitchCase() {
let spawnRandomBall = arc4random_uniform(2)
switch spawnRandomBall {
case 0:
mainBallSpawner()
break
case 1:
enemySpawner()
break
default:
break
}
}
Your code can be much simpler
import SpriteKit
class GameScene: SKScene {
private var gameStarted = false
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard !gameStarted else { return }
gameStarted = true
beginCreatingSprites()
}
private func beginCreatingSprites() {
let addSomething = SKAction.runBlock { [weak self] in
if arc4random_uniform(2) == 0 {
self?.addBall()
} else {
self?.addEnemy()
}
}
let wait = SKAction.waitForDuration(3)
let sequence = SKAction.sequence([addSomething, wait])
let repeatForever = SKAction.repeatActionForever(sequence)
self.runAction(repeatForever)
}
private func addBall() {
let ball = SKSpriteNode(imageNamed: "ball")
// set position etc...
self.addChild(ball)
}
private func addEnemy() {
let enemy = SKSpriteNode(imageNamed: "enemy")
// set position etc...
self.addChild(enemy)
}
}

Swift/Spritekit SKNode not detected on touch

I make a small game with swift and spritekit and I am currently working on the menu and made a custom Buttonclass called SKButtonNode as a Button which is a subclass of SKNode. When I click on the Button on my phone nothing happens though, even when I use "userInteractionEnabled = true". So why can't I see a "test2" when I touch a button but only see it if I hit next to a button?
class SKButtonNode: SKNode {
var defaultButton: SKSpriteNode
var activeButton: SKSpriteNode
var action: () -> Void
init(defaultButtonImage: String, activeButtonImage: String, buttonAction: () -> Void) {
defaultButton = SKSpriteNode(imageNamed: defaultButtonImage)
activeButton = SKSpriteNode(imageNamed: activeButtonImage)
activeButton.hidden = true
action = buttonAction
super.init()
userInteractionEnabled = true
addChild(defaultButton)
addChild(activeButton)
}
class MenuScene: SKScene, SKPhysicsContactDelegate {
var startGameButton: SKButtonNode!
var optionsGameButton: SKButtonNode!
var exitGameButton: SKButtonNode!
// Update time
var lastUpdateTimeInterval: NSTimeInterval = 0
override func didMoveToView(view: SKView) {
// Setup physics world's contact delegate
physicsWorld.contactDelegate = self
let startGameButton = SKButtonNode(defaultButtonImage: "blue_button_up", activeButtonImage: "blue_button_down" , buttonAction: startGame)
startGameButton.position = CGPoint(x: 640, y: 330)
startGameButton.activeButton.size = CGSize(width: 360, height: 95)
startGameButton.defaultButton.size = CGSize(width: 360, height: 95)
startGameButton.name = "startGameButton"
let startOptionsButton = SKButtonNode(defaultButtonImage: "blue_button_up", activeButtonImage: "blue_button_down" , buttonAction: startGame)
startOptionsButton.position = CGPoint(x: 640, y: 210)
startOptionsButton.activeButton.size = CGSize(width: 360, height: 95)
startOptionsButton.defaultButton.size = CGSize(width: 360, height: 95)
startOptionsButton.name = "startOptionsButton"
let exitGameButton = SKButtonNode(defaultButtonImage: "blue_button_up", activeButtonImage: "blue_button_down" , buttonAction: startGame)
exitGameButton.position = CGPoint(x: 640, y: 90)
exitGameButton.activeButton.size = CGSize(width: 360, height: 95)
exitGameButton.defaultButton.size = CGSize(width: 360, height: 95)
exitGameButton.name = "exitGameButton"
addChild(startGameButton)
addChild(startOptionsButton)
addChild(exitGameButton)
}
func exitGame() {
}
func startOptions(){
}
func startGame() {
print("test")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let location = touches.first!.locationInNode(self)
let node = self.nodeAtPoint(location)
print("test2")
if (node.name == "startGameButton") {
let currentNode = node as! SKButtonNode
currentNode.activeButton.hidden = false
currentNode.defaultButton.hidden = true
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let location = touches.first!.locationInNode(self)
let node = self.nodeAtPoint(location)
if (node.name == "startGameButton") {
let currentNode = node as! SKButtonNode
if currentNode.defaultButton.containsPoint(location) {
currentNode.activeButton.hidden = false
currentNode.defaultButton.hidden = true
} else {
currentNode.activeButton.hidden = true
currentNode.defaultButton.hidden = false
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
let location = touches.first!.locationInNode(self)
let node = self.nodeAtPoint(location)
print("test3")
if (node.name == "startGameButton") {
let currentNode = node as! SKButtonNode
if currentNode.defaultButton.containsPoint(location) {
startGame()
}
currentNode.activeButton.hidden = true
currentNode.defaultButton.hidden = false
}
}
It looks like you're never actually running your button's action. All you're doing when the button is pressed in touchesBegan is setting the .hidden property to true or false. Try something like this:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let location = touches.first!.locationInNode(self)
let node = self.nodeAtPoint(location)
print("test2")
if (node.name == "startGameButton") {
let currentNode = node as! SKButtonNode
self.runAction(currentNode.action)
currentNode.activeButton.hidden = false
currentNode.defaultButton.hidden = true
}
}

Adding multiple sprites to a screen

I am new to SpriteKit.
I started working on a game where I want a menu of sprites that I can select from. When I select a particular sprite I want to then be able to tap on the screen and produce copies of them.
Here is a copy of my code I have trying.
class GameScene: SKScene
{
override func didMoveToView(view: SKView)
{
let button1 = SKSpriteNode(imageNamed: "Monster1A.png")
button1.position = CGPointMake(500, 600)
button1.name = "Monster1A"
self.addChild(button1)
let button2 = SKSpriteNode(imageNamed: "Monster2A.png")
button2.position = CGPointMake(300, 600)
button2.name = "Monster2A"
self.addChild(button2)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
let touch = touches
let location = touch.first!.locationInNode(self)
let node = self.nodeAtPoint(location)
if (node.name == "Monster1A")
{
for touch in touches
{
let touchLocation = touch.locationInNode(self)
let sprite = SKSpriteNode(imageNamed:"Monster1A")
sprite.xScale = 0.5
sprite.yScale = 0.5
sprite.position = touchLocation
let action = SKAction.rotateByAngle(CGFloat(M_PI), duration:1)
sprite.runAction(SKAction.repeatActionForever(action))
self.addChild(sprite)
}
}
if (node.name == "Monster2A")
{
for touch in touches
{
let touchLocation = touch.locationInNode(self)
let sprite = SKSpriteNode(imageNamed:"Monster2A")
sprite.xScale = 0.5
sprite.yScale = 0.5
sprite.position = touchLocation
let action = SKAction.rotateByAngle(CGFloat(M_PI), duration:1)
sprite.runAction(SKAction.repeatActionForever(action))
self.addChild(sprite)
}
}
}
}
Try this :)
import SpriteKit
class GameScene: SKScene {
var isDuplicating: Bool = false
var selectedSpriteName: String!
override func didMoveToView(view: SKView) {
let button1 = SKSpriteNode(imageNamed:"Monster1A")
button1.position = CGPointMake(500, 600)
button1.name = "Monster1A"
self.addChild(button1)
let button2 = SKSpriteNode(imageNamed:"Monster2A")
button2.position = CGPointMake(300, 600)
button2.name = "Monster2A"
self.addChild(button2)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
let sprite = self.nodeAtPoint(location)
if sprite.name == "Monster1A" {
if self.isDuplicating == true {
// Deselect
self.isDuplicating = false
return
}
self.selectedSpriteName = "Monster1A"
self.isDuplicating = true
} else if sprite.name == "Monster2A" {
if self.isDuplicating == true {
// Deselect
self.isDuplicating = false
return
}
self.selectedSpriteName = "Monster2A"
self.isDuplicating = true
} else {
if self.isDuplicating == true {
let newsprite = SKSpriteNode(imageNamed: self.selectedSpriteName)
newsprite.position = location
addChild(newsprite)
}
}
}
}
}