如何在我的游戏中保存用户的等级?
Posted
技术标签:
【中文标题】如何在我的游戏中保存用户的等级?【英文标题】:How do I save the user's level on my game? 【发布时间】:2019-01-03 16:43:08 【问题描述】:我有一个我用 swift 编码的迷宫游戏,它不保存关卡。目前,当用户关闭应用程序时,没有保存任何内容,用户必须重新从关卡 1 开始玩游戏。我对每个级别都有不同的 .swift 和 .sks 文件,所以我不确定如何跨类/文件保存级别数据。
我尝试使用 UserDefaults,但是,我不确定如何将“文件路径”保存到我的关卡。我知道我需要在我的 AppDelegate 中实现一些东西(使用 applicationWillTerminate 或 applicationDidEnterBackground 函数),但是,我不确定我需要在场景中放入什么代码(如果有的话)来保存这些数据。我以前没有保存过用户数据,因此我们将不胜感激!
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
【问题讨论】:
需要一些代码来了解一切是如何实现的,然后任何人甚至可以开始回答您的问题 我刚刚编辑了我的问题并为我的一个游戏场景(第一个)添加了代码。游戏场景的所有代码实际上是相同的。 :) 【参考方案1】:用字符串保存
UserDefaults.standard.set(StateOftheGame, forKey: "levelPass")
然后在应用程序委托上检查用户是否在游戏开始时'passLevel' 在
didFinishLaunchingWithOptions -> 添加函数 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()
【讨论】:
非常感谢!虽然我如何放置“yourviewcontrollerwithsavestate”?喜欢“myviewcontroller.stateofthegame”? 不客气,只需像他的名字一样设置它示例:我有这个 Viewcontroller class ConductorPrincipalViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate 所以我这样设置(withIdentifier: "ConductorPrincipalViewController") 每次你设置forKey: "levelPass" 到一个不同于'NIL' 的值时都会被调用你也可以删除和同步levelPass ////// //UserDefaults.standard.removeObject(forKey: "levelPass") UserDefaults.standard.synchronize() 请勿使用value(forKey:)
读取关卡。使用string(forKey:)
读取String
。以上是关于如何在我的游戏中保存用户的等级?的主要内容,如果未能解决你的问题,请参考以下文章