【问题标题】:firebase game where each player has a targetFirebase 游戏,每个玩家都有一个目标
【发布时间】:2021-06-16 08:06:23
【问题描述】:

我正在尝试开发一款游戏,在其中的一轮中,每个玩家都有不同的玩家作为他们的目标。

这是我的逻辑:我对我的玩家集合执行 .onSnapshot() 以实时获取我的数据。

然后对于每个玩家,我执行 Math.floor(Math.random()*players.length) 来为我的玩家获取随机目标。然后我做一个检查:

玩家是把自己作为他们的目标还是已经是某人的目标? => 寻找新目标

否则将目标分配给玩家。 (也在firebase中将目标的isATarget设置为true) 对所有其他玩家重复。

现在我对这种方法有 2 个问题:

如果有 4 个玩家(a、b、c、d),那么可能 a 有 b,b 有 c,c 有 a,d 永远找不到目标,导致函数永远循环。

我遇到的另一个问题是我的播放器数组没有实时更新。因此代码无法检测到某人的 isATarget 何时设置为 true。

这是我的源代码:

import { useEffect, useState } from "react"
import { useLocation } from "react-router"
import { db } from "../../services/firestore"

const Round2Info = () => {

    const [players, setPlayers] = useState([]);
    const [foundPlayers, setFoundPlayers] = useState(false)
    const location = useLocation();
    
    useEffect(() => {
        if (location.state.you.host === true) { // so only 1 person in the lobby is executing this code
            console.log('Step 1: code is only accessable by host');
            // get players
            db.collection("GameLobbies").doc(location.state.lobby.id).collection("players").onSnapshot((snapshot) => {
                let playersArr = players;
                console.log('getting players in round2info');
                const changes = snapshot.docChanges();
                changes.forEach(change => {
                    if (change.type === 'added') {
                        playersArr.push(change.doc.data());
                    }
                })
                setPlayers([...playersArr]);
                setFoundPlayers(true);
            });

        }
    }, []);

    useEffect(() => {
        if(foundPlayers){
            console.log('foundPlayers is true so', players); // this works. it shows all players
            givePlayersTheirTarget();
        }

    },[foundPlayers])

    const givePlayersTheirTarget = () => {
            console.log('Step 2: every player,', players, 'foreach'); // works
            players.forEach(player => {
                givePlayerTheirTarget(player)
            })
    }

    const givePlayerTheirTarget = player => {
        console.log('Step 3: player get their target');
        let target = getRandomPlayer();
        if (target.id === player.id || target.isATarget === true) {
            console.log(player.name, 'cant have', target.name, 'as their target');
            givePlayerTheirTarget(player);
        } else {
            console.log(player.name, 'has', target.name, 'as their target');
            // set target's isATarget to true
            db.collection("GameLobbies").doc(location.state.lobby.id).collection("players").doc(target.id).update({
                isATarget: true
            });
            // assign target to person
            db.collection("GameLobbies").doc(location.state.lobby.id).collection("players").doc(player.id).update({
                round2Target: target.name
            })
            console.log(players); // player who's been picked as a target stills shows isATarget = false while it should be true by now
        }
    }

    const getRandomPlayer = () => {
        return players[Math.floor(Math.random() * players.length)];
    }

    return (
        <div className="container">
            round 2 info
        </div>
    )
}
export default Round2Info

【问题讨论】:

    标签: reactjs firebase


    【解决方案1】:

    关于第一个问题:您可以使算法更喜欢针对尚未参与的玩家 -> 针对没有任何目标设置的玩家,这将使玩家-C 瞄准玩家-D 而不是玩家-A/ 玩家A 已经参与了游戏玩法(即使只是作为“猎人”,而不是“猎物”),所以更好的决定是添加玩家-D。当所有玩家都设置了“目标”后,您就可以选择最近的玩家

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多