【问题标题】:How to save and load GKGameModelPlayer from Realm in Swift?如何在 Swift 中从 Realm 保存和加载 GKGameModelPlayer?
【发布时间】:2020-05-08 22:00:56
【问题描述】:

我正在尝试在我的应用程序中实现GKGameModel。在其中,它包含一些变量,但就我的问题而言,我对以下两个变量感兴趣:

import GameplayKit
final class GameModel: NSObject, GKGameModel {
    var players: [GKGameModelPlayer]?
    var activePlayer: GKGameModelPlayer?
}

我做了这样的事情来初始化 3 名玩家的游戏(不准确)

let game = GameModel.init()
game.players = [Player(),Player(),Player()] // Create 3 players
guard let firstPlayer = game.players.first else {
     return
}
game.activePlayer = firstPlayer

一个播放器类定义为:

class Player : NSObject, GKGameModelPlayer {
    var playerId: Int // GKGameModelPlayer protocol variable
    let name: String
    var cash: Int = 0
}

在我的项目中,我有领域实体和分离的模型。所以会有一个PlayerEntity 和一个Player 类。

我想使用RealmSwift 来保存和加载GKGameModelPlayer 数据,更具体地说是存储/重新存储活动玩家的能力。

我认为这里的关键是playerId 变量;但我不确定。

但我不确定的是检索此信息,然后将其重新映射为有效的GKGameModelPlayer 格式

我目前的想法/理论是我需要将我的模型映射到实体类,反之亦然。

即:

// [REALM] Player entity
class PlayerEntity: Object {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var playerId: Int = 0
    @objc dynamic var name: String = ""
    @objc dynamic var cash: Int = 0

    override static func primaryKey() -> String {
       return "id"
    }
}

然后我扩展这个类来做一些“映射”:

extension PlayerEntity {
    // Map model -> entity
    convenience init(model: Player) {
        self.init()

        self.playerId = model.playerId
        self.name = model.name
        self.cash = model.cash
    }
}

extension Player {
    // Map entity -> model
    convenience init(entity: PlayerEntity) {
        let playerId = entity.playerId
        let name = entity.name
        let cash = entity.cash

        self.init(id: playerId, name: name, cash: cash)
    }
}

现在,playerId 始终为零 (0),因为我不确定如何设置它。

我可以将玩家保存到服务器。

问题来自于我尝试恢复播放器时,我想恢复GameModel中的activePlayer变量

因此,我的问题是:

我将如何保存和恢复 activePlayer 变量以使其继续符合 GKGameModelPlayer

感谢您对此提供的任何帮助。

感谢

【问题讨论】:

    标签: swift realm gameplay-kit


    【解决方案1】:

    虽然您可以使用这些扩展,但有时越简单越好。这是一个粗略的例子:

    class PlayerEntity: Object {
        @objc dynamic var playerId: Int = 0
        @objc dynamic var name: String = ""
        @objc dynamic var cash: Int = 0
    
        convenience init(withPlayer: PlayerClass) {
           self.init()
           self.playerId = withPlayer.playerId
           self.name = withPlayer.name
           self.cash = withPlayer.cash
        }
    
        func getPlayer() -> Player {
           let p = Player()
           p.playerId = self.playerId
           p.name = self.name
           p.cash = self.cash
           return p
        }
    
        override static func primaryKey() -> String {
           return "playerId"
        }
    }
    

    将所有玩家加载到一个数组中......这样就可以了

    let playerResults = realm.objects(PlayerEntity.self)
    for player in playerResults {
       let aPlayer = player.getPlayer()
       self.playerArray.append(aPlayer)
    }
    

    注意删除

    @objc dynamic var id = UUID().uuidString
    

    因为它并没有真正用于将对象标识为主键。

    主键真的是

    var playerId: Int // GKGameModelPlayer protocol variable
    

    只要是独一无二的就可以使用。

    【讨论】:

    • 我明白,我想我只是把事情复杂化了。我会试一试。我想我可以通过首先依赖playerid来保存和加载activeplayer参考,或者如果我有一个回合索引参考然后从这个参考中设置活跃玩家我会写一些测试看看我是否可以做到
    • @zardon 非常好。如果您遇到困难,请告诉我们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2023-03-07
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多