问题
My Goal: to access an element in an SKnode array and its property between my two scenes and also save and retrieve it the array that contains my achievement SKNodes that hold different values.
So I have two scenes one that is my actual game scene and the second one being my achievements menu that contains the list of all my achievements. When the achievementMenu scene starts it produces 27 Achievements which are a subclass of SKNode called “Achievements” which is seen below”
It is made in a func like so:
for _ in 0...0 {
let Counter = 0
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
Achievement.zPosition = 100
Achievement.name = "Ach0"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
Here is the Subclass of the SKNode that holds all the achievements Properties:
class Achievements: SKNode {
//Nodes used throughout the SKNode class
var achievementLabel = SKLabelNode()
var achievementTitleLabel = SKLabelNode()
var achievementNode = SKSpriteNode()
//Counter used to determine the Achievements properties
var achCounter = 0
//Amount Variables used as Achievement Properties
var image: String = "locked"
var information: String = ""
var title: String = ""
var amount = 0
var neededAmount = 0
var incrementAmount = 0
var incrementAmount2 = 0
var stage = 0
func createAchievement() {
let tex:SKTexture = SKTexture(imageNamed: image)
achievementNode = SKSpriteNode(texture: tex, color: SKColor.black, size: CGSize(width: 75, height: 75)) //frame.maxX / 20, height: frame.maxY / 20))
achievementNode.zPosition = -10
achievementNode.name = "AchievementNode"
self.addChild(achievementNode)
self.zPosition = -11
createAchievementLabels()
}
func createAchievementLabels() {
achievementTitleLabel = SKLabelNode(fontNamed: "Avenir-Black")
achievementTitleLabel.fontColor = UIColor.black;
achievementTitleLabel.fontSize = 13 //self.frame.maxY/30
achievementTitleLabel.position = CGPoint (x: 0, y: 45)
achievementTitleLabel.text = "\(title)"
achievementTitleLabel.zPosition = -9
addChild(achievementTitleLabel)
achievementTitleLabel.name = "AchievementTitleLabel"
achievementLabel = SKLabelNode(fontNamed: "Avenir-Black")
achievementLabel.fontColor = UIColor.black;
achievementLabel.fontSize = 13 //self.frame.maxY/30
achievementLabel.position = CGPoint (x: 0, y: -50)
achievementLabel.text = ("\(amount) / \(neededAmount)")
achievementLabel.zPosition = -9
addChild(achievementLabel)
achievementLabel.name = "AmountLabel"
}
func UpdateText() {
achievementLabel.text = ("\(amount) / \(neededAmount)")
}
func getAchievementProperties(){
switch achCounter {
case 0:
amount = 0;
neededAmount = 10;
incrementAmount = 100;
incrementAmount2 = 1000;
information = "No. Deaths"
title = "DAILY"
stage = 0
case 1:
amount = 0;
neededAmount = 5;
incrementAmount = 10;
incrementAmount2 = 70;
information = "No. Deaths"
title = "DAILY"
stage = 0
these are then put into a global array variable that is called “Achievements3” that is defined like so:
var Achievements3 = [SKNode]()
I am trying to get the achievements array to save when the game is “switched off” and when it is switched back on for it to replace the new nodes it generates in the AchievementMenu scene with the existing ones so that the data can be written over and the progress is still there. Along with this i am also trying to add one to the amount property of a certain achievement that is contained within the Array when something happens in the game scene such as the player dying for example. I can’t seem to find a way to access a specific element in an array and then add to its property it was given when it was generated from the sub class. I was going to use the NSUserdefaults to store all the SKNodes individually but It is too much just to store each individual achievement.
Can some please tell me what i’m doing wrong. if you would like to see my whole achievement menu scene it can be viewed below:
import Foundation
import SpriteKit
var Achievements3 = [SKNode]()
class AchievementMenu: SKScene {
//Array for Achievement Sprites
//establishing scroll
var startY: CGFloat = 0.0
var lastY: CGFloat = 0.0
var moveableArea = SKNode()
//Universal Buttons
var characterMenu = SKSpriteNode()
var itemShopMenu = SKSpriteNode()
var achievementMenu = SKSpriteNode()
var universalBackButton = SKSpriteNode()
//Labels for Sections of Achievements
var dailySection = SKLabelNode()
var achievementSection = SKLabelNode()
var bossAchievementSection = SKLabelNode()
var exitInfoMenu = SKSpriteNode()
var TEMPBUTTONTOADDSTUFF = SKSpriteNode()
override func didMove(to view: SKView) {
//setting up scrollling
moveableArea.position = CGPoint(x: 0, y: 0)
moveableArea.zPosition = -12
self.addChild(moveableArea)
//Labels for Dividing Sections of the Achievement Menu
dailySection = SKLabelNode(fontNamed: "Avenir-Black"); dailySection.fontColor = UIColor.black; dailySection.fontSize = self.frame.maxY/30
dailySection.position = CGPoint(x:self.frame.midX, y:self.self.frame.midY * 1.27)
dailySection.text = "--------------------------Daily-------------------------"
moveableArea.addChild(dailySection)
achievementSection = SKLabelNode(fontNamed: "Avenir-Black"); achievementSection.fontColor = UIColor.black; achievementSection.fontSize = self.frame.maxY/30
achievementSection.position = CGPoint(x:self.frame.midX, y:self.self.frame.midY * 0.65)
achievementSection.text = "--------------------------Achievements-------------------------"
moveableArea.addChild(achievementSection)
bossAchievementSection = SKLabelNode(fontNamed: "Avenir-Black"); bossAchievementSection.fontColor = UIColor.black; bossAchievementSection.fontSize = self.frame.maxY/30
bossAchievementSection.position = CGPoint(x:self.frame.midX, y:self.self.frame.midY * -1.3)
bossAchievementSection.text = "--------------------------Boss-------------------------"
moveableArea.addChild(bossAchievementSection)
//Buttons For Navigating the Interface
universalBackButton = SKSpriteNode(color: SKColor.orange, size: CGSize(width: 75, height: 50))
universalBackButton.position = CGPoint(x:50, y: 35)
universalBackButton.zPosition = 100001
addChild(universalBackButton)
characterMenu = SKSpriteNode(color: SKColor.orange, size: CGSize(width: 75, height: 50))
characterMenu.position = CGPoint(x:142.5, y: 35)
characterMenu.zPosition = 100001
addChild(characterMenu)
itemShopMenu = SKSpriteNode(color: SKColor.orange, size: CGSize(width: 75, height: 50))
itemShopMenu.position = CGPoint(x:232.5, y: 35)
itemShopMenu.zPosition = 100001
addChild(itemShopMenu)
achievementMenu = SKSpriteNode(color: SKColor.red, size: CGSize(width: 75, height: 50))
achievementMenu.position = CGPoint(x:325, y: 35)
achievementMenu.zPosition = 100001
addChild(achievementMenu)
exitInfoMenu = SKSpriteNode(color: SKColor.darkGray, size: CGSize(width: 75, height: 50))
exitInfoMenu.position = CGPoint(x:frame.midX, y: frame.midY - frame.midY / 2)
exitInfoMenu.zPosition = 100001
exitInfoMenu.isHidden = true
addChild(exitInfoMenu)
TEMPBUTTONTOADDSTUFF = SKSpriteNode(color: SKColor.orange, size: CGSize(width: 75, height: 50))
TEMPBUTTONTOADDSTUFF.position = CGPoint(x:frame.midX, y: 550)
TEMPBUTTONTOADDSTUFF.zPosition = 100
addChild(TEMPBUTTONTOADDSTUFF)
createAchievements()
}
func createAchievements() {
for _ in 0...0 {
//let Achievement = SKSpriteNode(color: SKColor.blue, size: CGSize(width: 100, height: 100))
let Counter = 0
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
Achievement.zPosition = 100
Achievement.name = "Ach0"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
for _ in 0...0 {
let Counter = 1
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX*0.35, y: self.frame.midY)
Achievement.zPosition = 100
moveableArea.addChild(Achievement)
Achievement.name = "Ach1"
Achievements3.append(Achievement)
}
for _ in 0...0 {
let Counter = 2
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX*1.65, y: self.frame.midY)
Achievement.zPosition = 100
Achievement.name = "Ach2"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
for _ in 0...0 {
let Counter = 3
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX, y: self.frame.midY*0.4)
Achievement.zPosition = 100
Achievement.name = "Ach3"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
for _ in 0...0 {
let Counter = 4
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX*0.35, y: self.frame.midY*0.4)
Achievement.zPosition = 100
Achievement.name = "Ach4"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
for _ in 0...0 {
let Counter = 5
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX*1.65, y: self.frame.midY*0.4)
Achievement.zPosition = 100
Achievement.name = "Ach5"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
for _ in 0...0 {
let Counter = 6
let Achievement = Achievements()
Achievement.achCounter = Counter
Achievement.getAchievementProperties()
Achievement.position = CGPoint(x: self.frame.midX, y: self.frame.midY*0.05)
Achievement.zPosition = 100
Achievement.name = "Ach6"
Achievements3.append(Achievement)
moveableArea.addChild(Achievement)
}
}
func BringUpAchievementInfo(achName: String) {
var title = SKLabelNode()
var info = SKLabelNode()
var atexture = SKSpriteNode()
var amountLabel = SKLabelNode()
var stageLabel = SKLabelNode()
let node45 = SKNode()
node45.zPosition = 997
node45.name = "LOL"
addChild(node45)
exitInfoMenu.isHidden = false
universalBackButton.isHidden = true; characterMenu.isHidden = true; itemShopMenu.isHidden = true; achievementMenu.isHidden = true
let backgroundNode = SKSpriteNode(color: SKColor.darkGray, size: CGSize(width: frame.maxX, height: frame.maxY))
backgroundNode.position = CGPoint(x: frame.midX, y: frame.midY)
backgroundNode.alpha = 0.5
backgroundNode.zPosition = 998
node45.addChild(backgroundNode)
let infoNode = SKSpriteNode(color: SKColor.white, size: CGSize(width: frame.size.width, height: frame.size.height / 2))
infoNode.position = CGPoint(x: frame.midX, y: frame.midY + frame.midY / 6)
infoNode.zPosition = 999
node45.addChild(infoNode)
moveableArea.enumerateChildNodes(withName: achName ) {
node, stop in
let achievements = node as! Achievements
if node is Achievements {
title = SKLabelNode(fontNamed: "Avenir-Black"); title.fontColor = UIColor.black; title.fontSize = 25
title.position = CGPoint(x: 0, y: 100)
title.text = "\(achievements.title)"
title.zPosition = 1001
infoNode.addChild(title)
info = SKLabelNode(fontNamed: "Avenir-Black"); info.fontColor = UIColor.black; info.fontSize = 15
info.position = CGPoint(x: 0, y: -80)
info.text = "\(achievements.information)"
info.zPosition = 1001
infoNode.addChild(info)
amountLabel = SKLabelNode(fontNamed: "Avenir-Black"); amountLabel.fontColor = UIColor.black; amountLabel.fontSize = 15
amountLabel.position = CGPoint(x: 0, y: -100)
amountLabel.text = ("\(achievements.amount) / \(achievements.neededAmount)")
amountLabel.zPosition = 1001
infoNode.addChild(amountLabel)
atexture = SKSpriteNode(texture: achievements.achievementNode.texture, color: SKColor.blue, size: CGSize(width: 100, height: 100 ))
atexture.position = CGPoint(x: 0, y: 20)
atexture.zPosition = 1000
infoNode.addChild(atexture)
stageLabel = SKLabelNode(fontNamed: "Avenir-Black"); stageLabel.fontColor = UIColor.black; stageLabel.fontSize = 15
stageLabel.position = CGPoint(x: 0, y: -140)
stageLabel.text = ("Stage: \(achievements.stage)")
stageLabel.zPosition = 1001
infoNode.addChild(stageLabel)
}
}
}
func addOneToAchievementAndUpdateText(name1: String) {
moveableArea.enumerateChildNodes(withName: name1) {
node, stop in
if node is Achievements {
let achievements = node as! Achievements
achievements.amount += 1
achievements.UpdateText()
self.checkForAchievementStageCompletion(name2: name1)
}
}
}
func checkForAchievementStageCompletion(name2: String) {
moveableArea.enumerateChildNodes(withName: name2) {
node, stop in
if node is Achievements {
let achievements = node as! Achievements
if achievements.amount == achievements.neededAmount {
achievements.enumerateChildNodes(withName: "AchievementNode") {
node, stop in
if achievements.stage == 0 {
let changeTexture = SKAction.setTexture(SKTexture(imageNamed: "diamonds1"))
node.run(changeTexture)
achievements.neededAmount = achievements.incrementAmount
achievements.stage = 1
} else if achievements.stage == 1 {
let changeTexture = SKAction.setTexture(SKTexture(imageNamed: "diamonds2"))
node.run(changeTexture)
achievements.neededAmount = achievements.incrementAmount2
achievements.stage = 2
} else if achievements.stage == 2 {
let changeTexture = SKAction.setTexture(SKTexture(imageNamed: "diamondicon"))
node.run(changeTexture)
achievements.stage = 3
}
}
}
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch = touches.first!
let location = touch.location(in: self)
let node = self.atPoint(touch.location(in: self))
startY = location.y
lastY = location.y
switch node {
case universalBackButton:
let scene = GameScene(size: self.view!.bounds.size)
GameState.current = .gameStart
scene.scaleMode = .aspectFill
scene.backgroundColor = UIColor.clear
let transition = SKTransition.crossFade(withDuration: 0.5)
self.scene?.view?.presentScene(scene, transition: transition)
case characterMenu:
let scene = CharacterMenu(size: self.view!.bounds.size)
scene.scaleMode = .aspectFill
scene.backgroundColor = UIColor.white
self.scene?.view?.presentScene(scene)
case itemShopMenu:
let scene = ShopItemMenu(size: self.view!.bounds.size)
scene.scaleMode = .aspectFill
scene.backgroundColor = UIColor.white
self.scene?.view?.presentScene(scene)
case exitInfoMenu:
let node = childNode(withName: "LOL")
node?.removeFromParent()
exitInfoMenu.isHidden = true
universalBackButton.isHidden = false; characterMenu.isHidden = false; itemShopMenu.isHidden = false; achievementMenu.isHidden = false
case TEMPBUTTONTOADDSTUFF:
addOneToAchievementAndUpdateText(name1: "Ach0")
addOneToAchievementAndUpdateText(name1: "Ach1")
addOneToAchievementAndUpdateText(name1: "Ach2")
case Achievements3[0]:
BringUpAchievementInfo(achName: "Ach0")
case Achievements3[1]:
BringUpAchievementInfo(achName: "Ach1")
case Achievements3[2]:
BringUpAchievementInfo(achName: "Ach2")
case Achievements3[3]:
BringUpAchievementInfo(achName: "Ach3")
case Achievements3[4]:
BringUpAchievementInfo(achName: "Ach4")
case Achievements3[5]:
BringUpAchievementInfo(achName: "Ach5")
case Achievements3[6]:
BringUpAchievementInfo(achName: "Ach6")
default: return
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch = touches.first!
let location = touch.location(in: self)
let currentY = location.y
// Set Top and Bottom scroll distances, measured in screenlengths
let topLimit:CGFloat = 0.0
let bottomLimit:CGFloat = 1.33
// Set scrolling speed - Higher number is faster speed
let scrollSpeed:CGFloat = 0.2
// calculate distance moved since last touch registered and add it to current position
let newY = moveableArea.position.y + ((currentY - lastY)*scrollSpeed)
// perform checks to see if new position will be over the limits, otherwise set as new position
if newY < self.size.height*(-topLimit) {
moveableArea.position = CGPoint(x: moveableArea.position.x, y: self.size.height*(-topLimit))
}
else if newY > self.size.height*bottomLimit {
moveableArea.position = CGPoint(x: moveableArea.position.x, y: self.size.height*bottomLimit)
}
else {
moveableArea.position = CGPoint(x: moveableArea.position.x, y: newY)
}
}
}
class Achievements: SKNode {
//Nodes used throughout the SKNode class
var achievementLabel = SKLabelNode()
var achievementTitleLabel = SKLabelNode()
var achievementNode = SKSpriteNode()
//Counter used to determine the Achievements properties
var achCounter = 0
//Amount Variables used as Achievement Properties
var image: String = "locked"
var information: String = ""
var title: String = ""
var amount = 0
var neededAmount = 0
var incrementAmount = 0
var incrementAmount2 = 0
var stage = 0
func createAchievement() {
let tex:SKTexture = SKTexture(imageNamed: image)
achievementNode = SKSpriteNode(texture: tex, color: SKColor.black, size: CGSize(width: 75, height: 75)) //frame.maxX / 20, height: frame.maxY / 20))
achievementNode.zPosition = -10
achievementNode.name = "AchievementNode"
self.addChild(achievementNode)
self.zPosition = -11
createAchievementLabels()
}
func createAchievementLabels() {
achievementTitleLabel = SKLabelNode(fontNamed: "Avenir-Black")
achievementTitleLabel.fontColor = UIColor.black;
achievementTitleLabel.fontSize = 13 //self.frame.maxY/30
achievementTitleLabel.position = CGPoint (x: 0, y: 45)
achievementTitleLabel.text = "\(title)"
achievementTitleLabel.zPosition = -9
addChild(achievementTitleLabel)
achievementTitleLabel.name = "AchievementTitleLabel"
achievementLabel = SKLabelNode(fontNamed: "Avenir-Black")
achievementLabel.fontColor = UIColor.black;
achievementLabel.fontSize = 13 //self.frame.maxY/30
achievementLabel.position = CGPoint (x: 0, y: -50)
achievementLabel.text = ("\(amount) / \(neededAmount)")
achievementLabel.zPosition = -9
addChild(achievementLabel)
achievementLabel.name = "AmountLabel"
}
func UpdateText() {
achievementLabel.text = ("\(amount) / \(neededAmount)")
}
func getAchievementProperties(){
switch achCounter {
case 0:
amount = 0;
neededAmount = 10;
incrementAmount = 100;
incrementAmount2 = 1000;
information = "No. Deaths"
title = "DAILY"
stage = 0
case 1:
amount = 0;
neededAmount = 5;
incrementAmount = 10;
incrementAmount2 = 70;
information = "No. Deaths"
title = "DAILY"
stage = 0
case 2:
amount = 0;
neededAmount = 70;
incrementAmount = 10;
incrementAmount2 = 70;
information = "No. Deaths"
title = "DAILY"
stage = 0
case 3:
amount = 0;
neededAmount = 70;
incrementAmount = 10;
incrementAmount2 = 70;
information = "No. Deaths"
title = "ROOKIE"
stage = 0
case 4:
amount = 0;
neededAmount = 70;
incrementAmount = 10;
incrementAmount2 = 70;
information = "No. Deaths"
title = "PLAYER"
stage = 0
default: return
}
createAchievement()
}
}
来源:https://stackoverflow.com/questions/41038237/accessing-element-in-array-saving-it-and-overwriting-it