【问题标题】:Based turn card game using Firebase and Kotlin: Storing and retrieving data使用 Firebase 和 Kotlin 的基于转牌游戏:存储和检索数据
【发布时间】:2020-03-09 22:25:38
【问题描述】:

我正在使用 kotlin 和 firebase 创建一个基于转牌的游戏。

我的问题是每个玩家都可以在战士、法师、治疗师和弓箭手之间选择一个角色来玩。这些角色都有相似的结构(生命值、攻击点、金钱和要抓的牌),但它们也有各自的变量(例如法师和治疗者有法力值)。 我想要做的是有一个包含对象“Character”的“Player”类。这意味着有一个“Character”类和从它继承的 4 个类“Warrior”、“Mage”、“Healer”和“Archer”。

class Player constructor(uid: String?, name: String?): Serializable{

    var mUid: String? = ""
    var mName: String? = null
    var mCharacter: Character? = null
    var mHealth = 0
    var mAttack = 0
    var mMoney = 0

    init {
        mUid = uid
        mName = name
    }

    ...
}
abstract open class Character: Serializable {

    var mStartingMoney = 0
    var mStartingHealth = 0
    var mStartingAttack = 0

    abstract fun card1(listPlayer: HashMap<String, Player>?, currentPlayerUid: String?)
    abstract fun card2(listPlayer: HashMap<String, Player>?, currentPlayerUid: String?)
    abstract fun card3(listPlayer: HashMap<String, Player>?, currentPlayerUid: String?)

    fun playCard(i: Int, listPlayer: HashMap<String, Player>?, currentPlayerUid: String?) {
        when (i) {
            1   -> card1(listPlayer, currentPlayerUid)
            2   -> card2(listPlayer, currentPlayerUid)
            3   -> card3(listPlayer, currentPlayerUid)
        }
    }

    ...
}
class Mage: Character() {

    var mStartingMana = 0

    init {
        mStartingHealth = 4
        mStartingAttack = 1
        mStartingMoney = 2
        mStartingMana = 3
    }

    override fun card1(listPlayer: HashMap<String, Player>?, currentPlayerUid: String?)
    {
        listPlayer!![currentPlayerUid]!!.addMana(2)
    }

    override fun card2(listPlayer: HashMap<String, Player>?, currentPlayerUid: String?)
    {
        listPlayer!![currentPlayerUid]!!.addMoney(2)
    }

    override fun card3(listPlayer: HashMap<String, Player>?, currentPlayerUid: String?)
    {
        listPlayer!![currentPlayerUid]!!.loseHealth(2)
    }

    ...
}

但是,当我尝试检索播放器的值时,这似乎会导致 Firebase 出现问题。它将尝试实例化一个 Character,这是不可能的,因为它是抽象的。我想要的是 Firebase 在读取数据时实例化 Character 的正确子类型,但它无法知道它是什么子类型。 (参见android firebase unable to instantiate abstract class when call getValue() in listener 上的 Frank van Puffelen)。

因此,如果有人对我如何完成这项工作或如何更好地管理我的课程有任何建议,我将不胜感激!谢谢。

【问题讨论】:

  • 您使用的是哪个数据库,实时数据库还是 Firestore?另外,请编辑问题以准确显示您尝试使用的代码无法按您预期的方式工作。

标签: android firebase kotlin


【解决方案1】:

Firebase 无法知道要实例化哪个类,因此您必须自己构建该部分。通常这意味着在数据库中存储有关字符类的属性,并在写入/读取字符的其他属性之前写入/读取该属性。

然后,一旦您从数据库中读取了字符类,您就可以在代码中实例化该类,并让它读取(其他)属性。

因此,如果您使用的是实时数据库并且有一个字符的 JSON 路径,那看起来像这样:

val ref = FirebaseDatabase.instance.reference.child("path/to/character")
ref.addListenerForSingleValueEvent(object:ValueEventListener() {
  fun onDataChange(dataSnapshot:DataSnapshot) {
    val character:Char
    val characterClass = dataSnapshot.child("class").getValue(String::class.java)
    if ("Mage" == characterClass)
    {
      character = dataSnapshot.getValue(Mage::class.java)
    }
  }
  fun onCancelled(databaseError:DatabaseError) {
    throw databaseError.toException()
  }
})

在 Kotlin 中可能有一种更惯用的方式来执行此操作,但这应该足以让您入门。

【讨论】:

    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 2017-04-10
    • 2014-10-25
    相关资源
    最近更新 更多