我的目标:访问SKnode数组中的元素及其在我的两个场景之间的属性,并保存并检索包含具有不同值的成就SKNode的数组。
所以我有两个场景,一个是我的实际游戏场景,第二个是我的成就菜单,其中包含我所有成就的列表。当achievementMenu场景开始时,它会产生27个成就,它们是SKNode的一个子类,叫做“成就”,见下文“
它是在这样的函数中制作的:
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)
}
这是包含所有成就的SKNode的子类属性:
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
然后将它们放入一个名为“Achievements3”的全局数组变量中,其定义如下:
var Achievements3 = [SKNode]()
我正在尝试获取成就数组,以便在游戏“关闭”时保存,并且当它重新打开时,它将替换在AchievementMenu场景中使用现有游戏生成的新节点,以便数据可以写下来,进展仍然存在。除此之外,我还尝试在游戏场景中发生某些事情(例如玩家死亡)时,在数组中包含的某个成就的数量属性中添加一个。我似乎无法找到一种方法来访问数组中的特定元素,然后添加到它的属性,它是从子类生成时给出的。我打算使用NSUserdefaults单独存储所有SKNodes,但存储每个单独的成就太多了。
有些人可以告诉我我做错了什么。如果你想看到我的整个成就菜单场景,可以在下面查看:
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()
}
}