Swift 如何保存用户';我的水平是多少?

Swift 如何保存用户';我的水平是多少?,swift,save,skscene,user-data,Swift,Save,Skscene,User Data,我有一个迷宫游戏,我用swift编码,不保存等级。目前,当用户关闭应用程序时,不会保存任何内容,用户必须再次从1级开始玩游戏。我对每个级别都有不同的.swift和.sks文件,因此我不确定如何跨类/文件保存级别数据 我尝试使用UserDefaults,但是,我不知道如何将“文件路径”保存到我的级别。我知道我需要在AppDelegate中实现一些东西(使用applicationWillTerminate或applicationIdentinterbackground函数),但是,我不确定需要在场景

我有一个迷宫游戏,我用swift编码,不保存等级。目前,当用户关闭应用程序时,不会保存任何内容,用户必须再次从1级开始玩游戏。我对每个级别都有不同的.swift和.sks文件,因此我不确定如何跨类/文件保存级别数据

我尝试使用UserDefaults,但是,我不知道如何将“文件路径”保存到我的级别。我知道我需要在AppDelegate中实现一些东西(使用applicationWillTerminate或applicationIdentinterbackground函数),但是,我不确定需要在场景本身中放置什么代码(如果有)来保存这些数据。我以前没有保存过用户数据,因此非常感谢您的帮助

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

}
导入SpriteKit
导入游戏工具包
导入CoreMotion
导入SceneKit
导入UIKit
类游戏场景:SKScene,SKPhysicContactDelegate{
让GameSecene=SKScene()
var按钮:SKNode!=nil
var playerSprite=SKSpriteNode()
var nextNode=SKSpriteNode()
lazy var countdownLabel:SKLabelNode={
var label=SKLabelNode(名称为“Helvetica”)
label.horizontalAlignmentMode=.center
label.verticalAlignmentMode=.center
label.color=UIColor.red
label.text=“\(计数器)”
退货标签
}()
变量计数器=30
var counterTimer=Timer()
var counterStartValue=30
让motionManager=CMMotionManager()
覆盖func didMove(到视图:SKView){
self.scene?.scaleMode=SKSceneScaleMode.aspectFit
button=SKSpriteNode(图像名为:“Redobtton”)
按钮位置=CGPoint(x:350,y:585);
self.addChild(按钮)
countdownLabel.position=CGPoint(x:0.5,y:0.5)
addChild(倒计时标签)
计数器=计数器起始值
运行计时器()
self.physicsWorld.contactDelegate=self
playerSprite=self.childNode(名称为:“playerSprite”)as!SKSpriteNode
nextNode=self.childNode(名称为“nextNode”)as!SKSpriteNode
motionManager.startAccelerometerUpdates()
motionManager.AccelerometrUpdateInterval=0.1
motionManager.startAccelerometerUpdates(到:OperationQueue.main){
(数据、错误)在
self.physicsWorld.gravity=CGVector(dx:CGFloat((data?.acceleration.x)!)*10,dy:CGFloat((data?.acceleration.y)!)*10)
}
}
func didbegen(uu联系人:skphysiccontact){
让bodyA=contact.bodyA
让bodyB=contact.bodyB
如果bodyA.categoryBitMask==1&&bodyB.categoryBitMask==2 | | | bodyA.categoryBitMask==2&&bodyB.categoryBitMask==1{
playerSprite.removeFromParent()
nextNode.removeFromParent()的
self.removeFromParent()
let transition=SKTransition.fade(持续时间:0.5)
让gameScene2=gameScene2(文件名为:“gameScene2”)
gameScene2!.scaleMode=SKSceneScaleMode.aspectFit
self.view?.presentScene(游戏场景2!,过渡:过渡)
}
}
func运行计时器(){
计数器计时器=Timer.scheduledTimer(时间间隔:1.0,目标:self,选择器:#选择器(递减计数器),用户信息:nil,重复:true)
}
@objc func递减计数器(){
计数器-=1
countdownLabel.text=“\(计数器)”
如果countdownLabel.text!<“0”作为字符串{
countdownLabel.text=“游戏结束”
playerSprite.removeFromParent()
nextNode.removeFromParent()的
}
}
覆盖函数touchesend(touchs:Set,带有事件:UIEvent?){
如果让触摸=先触摸{
如果touch.view==self.button{
打印(“耶!!!”)
}否则{
playerSprite.ishiden=false
nextNode.ishiden=false
让GameSecene=GameSecene(文件名为:“GameSecene”)
游戏场景!.scaleMode=SKSceneScaleMode.aspectFit
let transition=SKTransition.fade(持续时间:0.5)
self.view?.presentScene(游戏场景,过渡:过渡)
}
}
}
覆盖函数更新(uCurrentTime:TimeInterval){
//在渲染每个帧之前调用
}
}用字符串保存它

UserDefaults.standard.set(StateOftheGame, forKey: "levelPass")
然后在应用程序代理上检查游戏开始时用户是否为“passLevel” 在

didFinishLaunchingWithOptions->添加函数passLevel()


在任何人开始回答你的问题之前,我需要一些代码来了解一切是如何实现的。我刚刚编辑了我的问题,并为我的一个游戏场景(第一个)添加了代码。游戏场景的所有代码实际上都是相同的。:)非常感谢你!尽管我如何将“yourviewcontrollerwithsavestate”放在一起?比如“myviewcontroller.StateofGame”?不客气,只需将其设置为其名称本身即可。例如:我有一个Viewcontroller类ConductorPrincipalViewController:UIViewController、CLLocationManagerDelegate、MKMapViewDelegate{所以我将其设置为这样(标识符为:“ConductorPrincipalViewController”)每次您将forKey:“levelPass”设置为不同于“NIL”的值时,它都会被调用。您还可以删除并同步levelPass////UserDefaults.standard.removeObject(forKey:“levelPass”)UserDefaults.standard.synchronize()不要使用
值(forKey:)
来读取级别。使用
字符串(forKey:)
读取
字符串
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()
        }


    }