Android 基于Firebase和Kotlin的回合纸牌游戏:存储和检索数据

Android 基于Firebase和Kotlin的回合纸牌游戏:存储和检索数据,android,firebase,kotlin,Android,Firebase,Kotlin,我正在使用kotlin和firebase创建一个基于转换卡的游戏 我的问题是每个玩家都可以在战士、法师、治疗者和弓箭手之间选择一个角色。这些角色都有相似的结构(生命、攻击点、金钱和卡片),但是他们也有各自的变量(例如法师和治疗者有法力)。 我想做的是让一个“Player”类包含一个对象“Character”。这意味着拥有一个“角色”职业和从中继承的4个职业“战士”、“法师”、“治疗者”和“弓箭手” class Player constructor(uid: String?, name: Stri

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

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

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
    }

    ...
}
抽象开放类字符:可序列化{
var mStartingMoney=0
var mStartingHealth=0
var mStartingAttack=0
抽象趣味卡片1(listPlayer:HashMap?,currentPlayerUid:String?)
抽象趣味卡片2(listPlayer:HashMap?,currentPlayerUid:String?)
抽象趣味卡片3(listPlayer:HashMap?,currentPlayerUid:String?)
有趣的游戏卡(i:Int,listPlayer:HashMap?,currentPlayerUid:String?){
何时(i){
1->card1(列表播放器,当前播放器ID)
2->card2(列表播放器,当前播放器ID)
3->card3(列表播放器,当前播放器ID)
}
}
...
}
class-Mage:Character(){
变量mStartingMana=0
初始化{
mStartingHealth=4
mStartingAttack=1
mStartingMoney=2
mStartingMana=3
}
覆盖趣味卡1(listPlayer:HashMap?,currentPlayerUid:String?)
{
listPlayer!![currentPlayerUid]!!.addMana(2)
}
覆盖趣味卡片2(listPlayer:HashMap?,currentPlayerUid:String?)
{
listPlayer!![currentPlayerUid]!!。添加金钱(2)
}
覆盖趣味卡片3(listPlayer:HashMap?,currentPlayerUid:String?)
{
listPlayer!![currentPlayerUid]!!。失去健康(2)
}
...
}
然而,当我试图获取玩家的价值时,这似乎会导致Firebase出现问题。它将尝试实例化一个字符,这是不可能的,因为它是抽象的。我想让Firebase在读取数据时实例化正确的字符子类型,但它无法知道它是什么子类型。(比照弗兰克·范·帕夫伦的小说)


所以,如果有人对我如何做这项工作或如何更好地管理我的课程有任何建议,我将非常感谢!谢谢。

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

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

因此,如果您使用的是实时数据库,并且具有一个字符的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中可能有一种更惯用的方法来实现这一点,但这应该足以让您开始使用。

您使用的是哪种数据库,实时数据库还是Firestore?另外,请编辑问题以准确显示您试图使用的代码,这些代码无法按您期望的方式工作。
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)
    }

    ...
}
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()
  }
})