Основанная на поворотах карточная игра с использованием Firebase и Kotlin: хранение и получение данных - PullRequest
0 голосов
/ 10 марта 2020

Я создаю основанную игру на терне с использованием kotlin и огненной базы.

Моя проблема в том, что каждый игрок может выбрать персонажа для игры между Воином, Магом, Целителем и Лучником. Все персонажи имеют схожую структуру (hp, точка атаки, деньги и карты для рисования), однако они также имеют индивидуальные переменные (например, у мага и целителя есть мана). То, что я хочу сделать, это иметь класс «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
    }

    ...
}
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, когда я пытаюсь получить значение игрока. Он попытается создать экземпляр персонажа, что невозможно из-за его абстрактности. Я хочу, чтобы в Firebase был создан правильный подтип Character, когда он читает данные, но у него нет возможности узнать, что это за подтип. (см. Фрэнк ван Пуффелен на android firebase, неспособном создать экземпляр абстрактного класса при вызове getValue () в слушателе ).

Так что, если у кого-нибудь есть какие-либо предложения о том, как я мог бы сделать эту работу или о том, как я мог бы лучше управлять своими классами, я буду очень признателен! Спасибо.

1 Ответ

1 голос
/ 10 марта 2020

У Firebase нет возможности узнать, какой класс нужно создать, поэтому вам придется создавать эту часть самостоятельно. Обычно это означает сохранение свойства о классе символов в базе данных и запись / чтение этого свойства перед записью / чтением других свойств символа.

Затем, как только вы прочитаете класс символов из базы данных, Вы можете создать экземпляр класса в своем коде и прочитать его (другие) свойства.

Так что, если вы используете базу данных Realtime и у вас есть путь к 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()
  }
})

Возможно, есть более идиоматический c способ сделать это в Kotlin, но этого должно быть достаточно, чтобы вы начали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...