Accessing element in array, saving it and overwriting it

爱⌒轻易说出口 提交于 2019-12-12 04:14:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!