如何使用Firestore和Swift为2人muliplayer游戏构建数据?

时间:2018-03-22 13:55:01

标签: swift google-cloud-firestore

首先,我对Firestore及其功能真的很陌生,所以如果其中一些人对其他人感到明显,我会道歉。这些东西还没有记录在我的脑海里。

我正在尝试使用Swift和Firestore语言作为后端创建一个2人多人游戏。但是我不确定如何在给定时间内创建仅允许单个游戏中的两个玩家的此功能。我如何限制每场比赛只允许一场比赛中的两名球员?这是我需要在Firestore的安全和规则部分中设置的吗?或者我需要在如何建模数据中创建此功能吗?

我目前对数据建模方式的设置包括创建一个“游戏”集合,其中每个“游戏”都有两个“player1”和“player2”文档。然后,在每个玩家/文件中,我存储每个玩家功能的值。但是通过这种方法,我仍然没有解决只允许一个“游戏”/集合中的两个玩家的问题。如何防止第三个玩家进入游戏?或者当多个人同时进入游戏时,我将如何处理这种情况?

感谢您提供任何建议。

2 个答案:

答案 0 :(得分:2)

您可以使用云功能将玩家分配到游戏,管理游戏已满,然后启动游戏。在Medium,Building a multi-player board game with Firebase Firestore & Functions

上查看这篇文章

答案 1 :(得分:1)

这是我最终在Swift中使用Firestore创建2人多人游戏的代码。

import UIKit
import Firebase

class WaitForOpponentViewController: UIViewController
{
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!

    var battleRoomDocumentReference : DocumentReference!
    var battleRoomListenerRegistration : ListenerRegistration!

    override func viewDidLoad(){
        super.viewDidLoad()

         activityIndicator.hidesWhenStopped = true
         activityIndicator.startAnimating()

        Firestore.firestore().collection(BATTLEROOMS_Collection)
            .whereField(BATTLEROOMFULL_FIELD, isEqualTo: false)
            .whereField(NUMOFPLAYERS_FIELD, isLessThan: 2)
            .limit(to: 1)
            .getDocuments { (snapShot, error) in

            if let error = error
            {
                print("There was a error while fetching the documents: \(error)")
            }
            else
            {
                guard let snap = snapShot else {return}
                if(snap.documents.count > 0)
                {
                    //Update the current battle room
                    for document in snap.documents
                    {
                        Firestore.firestore().collection(BATTLEROOMS_Collection)
                            .document(document.documentID)
                            .setData(
                                [
                                    BATTLEROOMFULL_FIELD : true,
                                    NUMOFPLAYERS_FIELD : 2, //Note: Player1Id is not changed because there is already a player1Id when this document is updated
                                    PLAYER2ID_FIELD : Auth.auth().currentUser?.uid ?? "AnonymousNum2"
                                ], options: SetOptions.merge(), completion: { (error) in

                                    if let error = error
                                    {
                                        print("There was an error while adding the second player to the battle room document : \(error)")
                                    }

                                    self.addBattleRoomListener(battleRoomDocumentId: document.documentID)
                          })
                       }
                   }
                   else
                   {
                      //Create a new battle room
                      self.battleRoomDocumentReference =  Firestore.firestore().collection(BATTLEROOMS_Collection)
                           .addDocument(data:
                            [
                                BATTLEROOMFULL_FIELD: false,
                                NUMOFPLAYERS_FIELD : 1,
                                PLAYER1ID_FIELD : Auth.auth().currentUser?.uid ?? "AnonymousNum1",
                                PLAYER2ID_FIELD : ""
                            ], completion: { (error) in

                                if let error = error
                                {
                                    print("Error while adding a new battle room/player 1 to the battle room document : \(error)")
                                }
                    })
                    self.addBattleRoomListener(battleRoomDocumentId: self.battleRoomDocumentReference.documentID)
                }
            }
        }
     }

    override func viewWillDisappear(_ animated: Bool) {

        //Remove Battle Room Listener
        battleRoomListenerRegistration.remove()

        activityIndicator.stopAnimating()
    }

    func addBattleRoomListener(battleRoomDocumentId : String)
    {
        battleRoomListenerRegistration = Firestore.firestore().collection(BATTLEROOMS_Collection)
            .document(battleRoomDocumentId)
            .addSnapshotListener { (documentSnapshot, error) in

                guard let snapshot = documentSnapshot else { return }
                guard let documentData = snapshot.data() else { return }
                let battleRoomFullData = documentData[BATTLEROOMFULL_FIELD] as? Bool ?? false
                let numOfPlayerData = documentData[NUMOFPLAYERS_FIELD] as? Int ?? 0

                if(battleRoomFullData == true && numOfPlayerData == 2)
                {
                    print("Two Players in the Game, HURRAY. Segue to GAME VIEW CONTROLLER")
                }
                else
                {
                    return
                }
        }
    }

    @IBAction func cancelBattle(_ sender: UIButton) {

        //NOTE: Canceling is only allowed for the first user thats creates the Battle Room, once the Second Person enters the Battle Room the system will automatically segue to the Game View Controller sending both players into the game VC

        Firestore.firestore().collection(BATTLEROOMS_Collection)
            .document(battleRoomDocumentReference.documentID)
            .delete { (error) in
                if let error = error
                {
                    print("There was an error while trying to delete a document: \(error)")
                }
        }

        activityIndicator.stopAnimating()

        self.dismiss(animated: true, completion: nil)
    }
}