2016-04-05 25 views
0

我想做一個不同級別的菜單,與遊戲只有三個開放的水平開始。持續存在一個水平的菜單與精靈套件

問題在於節省鉛水平。

我已經設法讓這些關卡顯示他們各自的號碼,如果他們是開放的和掛鎖,如果他們不是。當您完成上一級別時,將打開一個新級別。

我想這樣保存,以便在關閉應用程序時,級別的進度不會被消除。

我嘗試過使用.plist,但他們不讓我在plist中使用數字作爲變量名,所以很難分別獲取各個級別的信息。我展示給你。

我的.plist it'sa字典的矩陣,誰裏邊有其他字典有三個組成部分(光潔度,級別,openclosed)compuse:

<dict> 
<key>Diez5</key> 
<dict> 
    <key>finishEnd</key> 
    <integer>0</integer> 
    <key>level</key> 
    <integer>10</integer> 
    <key>openClosed</key> 
    <integer>0</integer> 
</dict> 
<key>Once5</key> 
<dict> 
    <key>finishEnd</key> 
    <integer>0</integer> 
    <key>level</key> 
    <integer>11</integer> 
    <key>openClosed</key> 
    <integer>0</integer> 
</dict> 
<key>Uno</key> 
<dict> 
    <key>finishEnd</key> 
    <integer>0</integer> 
    <key>level</key> 
    <integer>1</integer> 
    <key>openClosed</key> 
    <integer>1</integer> 
</dict> 
... 
...</dict> 

接下來我有誰與此工作類:

class MenuList { 

var matriz4 = [["Ocho","Nueve","Diez","Once"], ["Cuatro","Cinco","Seis","Siete"], ["Matriz","Uno","Dos","Tres"]] 

var matriz5 = [["Ocho5","Nueve5","Diez5","Once5"], ["Cuatro5","Cinco5","Seis5","Siete5"], ["Matriz5","Uno5","Dos5","Tres5"]] 

let levelKey = "level" 
let openClosedKey = "openClosed" 
let finishKey = "finishEnd" 

let columnNum: Int! 
let rowNum: Int! 

let plist = Plist(name: "MatrizMenu") 

var levelID: Int! 
var openCID: Int! 
var finishID: Int! 

init() { 

    self.columnNum = matriz4.count + 1 
    self.rowNum = matriz4.count 
} 

func getTile(column: Int, row: Int, matrixNum: Int) -> (SKSpriteNode,SKLabelNode) { 

    let textLabel = SKLabelNode(fontNamed: "HelveticaRoundedLTStd-BdCn") 
    textLabel.fontColor = UIColor.whiteColor() 
    textLabel.text = " " 

    switch(matrixNum){ 
    case 4: 

     let dict = plist?.getMutablePlistFile()! 
     if let myDict = dict![matriz4[row][column]] { 

      openCID = myDict.valueForKey(openClosedKey) as! Int! 
      finishID = myDict.valueForKey(finishKey) as! Int! 

      if matriz4[row][column] == "Matriz" { 

       textLabel.text = "4x4" 
       return (SKSpriteNode(imageNamed: "rectangle-play"),textLabel) 

      } else if openCID != 0 && finishID == 0 { 
       levelID = myDict.valueForKey(levelKey) as! Int! 
       textLabel.text = "\(levelID)" 
       return (SKSpriteNode(imageNamed: "UnfinishTile"), textLabel) 

      } else if openCID != 0 && finishID != 0 { 
       levelID = myDict.valueForKey(levelKey) as! Int! 
       textLabel.text = "\(levelID)" 
       return (SKSpriteNode(imageNamed: "FinishTile"), textLabel) 

      }else { 
       textLabel.text = "lock" 
       return (SKSpriteNode(imageNamed: "rectangle-play-normal"), textLabel) 
      } 
     } 

    case 5: 

     let dict = plist?.getMutablePlistFile()! 
     if let myDict = dict![matriz5[row][column]] { 

      openCID = myDict.valueForKey(openClosedKey) as! Int! 

      if matriz5[row][column] == "Matriz5" { 

       let sprite = SKSpriteNode(color: UIColor(red: 1, green: 0.541, blue: 0.298, alpha: 1), size: CGSize(width: 50, height: 50)) 
       textLabel.text = "5x5" 
       return (sprite,textLabel) 

      } else if openCID != 0 && finishID == 0 { 
       levelID = myDict.valueForKey(levelKey) as! Int! 
       textLabel.text = "\(levelID)" 
       return (SKSpriteNode(imageNamed: "UnfinishTile"), textLabel) 


      } else if openCID != 0 && finishID != 0 { 
       levelID = myDict.valueForKey(levelKey) as! Int! 
       textLabel.text = "\(levelID)" 
       return (SKSpriteNode(imageNamed: "FinishTile"), textLabel) 

      }else { 
       textLabel.text = "lock" 
       return (SKSpriteNode(imageNamed: "rectangle-play-normal"), textLabel) 
      } 

     } 

    default: 
     return (SKSpriteNode(), textLabel) 

    } 

    return (SKSpriteNode(), textLabel) 
} 

func get_level(column: Int, row: Int, matrixNum: Int) -> (Int,Bool) { 

    switch(matrixNum){ 
    case 4: 

     let dict = plist?.getMutablePlistFile()! 
     if let myDict = dict!["\(matriz4[row][column])"] { 

      openCID = myDict.valueForKey(openClosedKey) as! Int! 
      levelID = myDict.valueForKey(levelKey) as! Int! 

      if matriz4[row][column] != "Matriz" && openCID != 0 { 
       return (levelID,true) 
      } 
     } 
     break 

    case 5: 

     let dict = plist?.getMutablePlistFile()! 
     if let myDict = dict!["\(matriz5[row][column])"] { 

      openCID = myDict.valueForKey(openClosedKey) as! Int! 
      levelID = myDict.valueForKey(levelKey) as! Int 

      if matriz5[row][column] != "Matriz5" && openCID != 0 { 
       return (levelID,true) 
      } 
     } 
     break 

    default: 
     return (0,false) 
    } 
    return (0,false) 
} 

func getBool(column: Int, row: Int) -> Bool { 

    if matriz4[row][column] == "Matriz" { 
     return true 
    } else { return false } 
} 

} 

這是plist中類,我覺得工作(Help for plist):

import CoreData 

struct Plist { 
//1 
enum PlistError: ErrorType { 
    case FileNotWritten 
    case FileDoesNotExist 
} 
//2 
let name:String 
//3 
var sourcePath:String? { 
    guard 

     let path = NSBundle.mainBundle().pathForResource(name, ofType: "plist") 

     else { return .None } 
    return path 
} 
//4 
var destPath:String? { 
    guard sourcePath != .None else { return .None } 
    let dir = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] 
    return (dir as NSString).stringByAppendingPathComponent("\(name).plist") 
} 

init?(name:String) { 
    //1 
    self.name = name 
    //2 
    let fileManager = NSFileManager.defaultManager() 
    //3 
    guard let source = sourcePath else { return nil } 
    guard let destination = destPath else { return nil } 
    guard fileManager.fileExistsAtPath(source) else { return nil } 
    //4 
    if !fileManager.fileExistsAtPath(destination) { 
     //5 
     do { 
      try fileManager.copyItemAtPath(source, toPath: destination) 
     } catch let error as NSError { 
      print("Unable to copy file. ERROR: \(error.localizedDescription)") 
      return nil 
     } 
    } 
} 

//1 
func getValuesInPlistFile() -> NSDictionary?{ 
    let fileManager = NSFileManager.defaultManager() 
    if fileManager.fileExistsAtPath(destPath!) { 
     guard let dict = NSDictionary(contentsOfFile: destPath!) else { return .None } 
     return dict 
    } else { 
     return .None 
    } 
} 
//2 
func getMutablePlistFile() -> NSMutableDictionary?{ 
    let fileManager = NSFileManager.defaultManager() 
    if fileManager.fileExistsAtPath(destPath!) { 
     guard let dict = NSMutableDictionary(contentsOfFile: destPath!) else { return .None } 
     return dict 
    } else { 
     return .None 
    } 
} 
//3 
func addValuesToPlistFile(dictionary:NSDictionary) throws { 
    let fileManager = NSFileManager.defaultManager() 
    if fileManager.fileExistsAtPath(destPath!) { 
     if !dictionary.writeToFile(destPath!, atomically: false) { 
      print("File not written successfully") 
      throw PlistError.FileNotWritten 
     } 
    } else { 
     throw PlistError.FileDoesNotExist 
    } 
} 

}

那麼,如何保存級別的進度? 感謝您的幫助!

+0

PList應該可以正常工作,你能解釋你如何佈置你的plist – Knight0fDragon

+0

這就是我對plist做的問題它是我放的名字,這是非常困難的工作,沒有數字,因爲我將一個func接收編號並返回字數(1 - >一),但plist不讓我把數字:(@ Knight0fDragon – AnaMM

+0

嗯,你的代碼看起來更復雜,那麼它需要是,NSDictionary有內置的函數來編寫和閱讀('dict.writeToFile(...)'和'dict = NSDictionary(contentsOfFile :))。然後如果你想把它作爲一個Swift字典,就把它轉換成'let swiftDict = dict as![NSObject:AnyObject] ' – Knight0fDragon

回答

1

有幾種方法可以做到這一點。我目前正在完成我的遊戲,我正在使用UICollectionView進行類似的菜單。爲了存儲數據,我在用於處理遊戲保存的Singleton遊戲數據類中爲此創建了一個字典數組。

例如

var unlockedLevels: [[String: Bool]] = [ 
    // Empty, so array starts at index 1 and not 0 
    [:], 
    // World 1 
    ["1": true, "2": false, "3": false, "4": false], // Level 1-4 
    // World 2 
    ... 
] 

我不是使用indexPath在我的集合視圖,以檢查被按下哪個小區和比較,爲所述陣列,看它是否被解鎖並加載水平。

let world = indexPath.section + 1 // + 1 because indexPath starts at 0 
    let level = indexPath.row + 1 // If collection view is horizontal need to convert this because indexPath goes up/down not left/right. 

    // Load level only if unlocked, otherwise exit method 
    guard GameData.sharedInstance.unlockedLevels[world]["\(level)"] == true else { return } 

    // code to load level 

你只是要確保更改單元格取決於級別是否解鎖。我在我的集​​合視圖的CellForRowAtIndexPath方法中這樣做,它有2個單元格,1個正常,1個鎖定。 由於單元出列和重用,我無法使其在1個單元中可靠工作。

let world = indexPath.section + 1 
    let level = indexPath.row + 1 

    if GameData.sharedInstance.unlockedLevels[world]["\(level)"] == true { 
     return cell // returns normal cell to play level 
    } else { 
     return cellLocked // returns cell with padlock. 
    } 

比一旦完成一個級別,您將相應級別的布爾值設置爲true並保存進度。

要保存數組,您可以使用NSCoding,NSUserDefaults或最佳解決方案Keychain。

https://www.hackingwithswift.com/read/12/3/fixing-project-10-nscoding

how to don't get a nil value from NSUserDefaults in ViewDidLoad

https://github.com/jrendel/SwiftKeychainWrapper

https://www.raywenderlich.com/63235/how-to-save-your-game-data-tutorial-part-1-of-2(的OBJ C,但我覺得還是有用的)

不是100%肯定這是你在找什麼,因爲我不使用的Plist。讓我知道事情的後續。

+0

感謝您的信息,它真的很有幫助,但問題是他們我有一個矩陣不是一個數組,當我嘗試使用NUserDefaults或NScoding保存矩陣不起作用:(如果您知道wa Ÿ用矩陣做我會更感激然後知道。非常感謝! – AnaMM

+0

我不確定你的意思是矩陣。你可以發佈一些幫助人們更好地理解你的問題的代碼。 – crashoverride777

+0

我把我用plist做的代碼。我希望你明白 – AnaMM