简介
在本深入指南中,我们将逐步使用 Firebase 和 React 构建实时多人游戏,并使用 Gladiator Taunt Wars 中的详细示例。在这种游戏模式中,玩家进行策略性的嘲讽决斗,轮流选择和回应嘲讽以减少对手的生命值(HP)。本文将涵盖构建此类游戏的各个方面,包括 Firebase 设置、匹配、游戏状态管理、动画、实时更新和基于 ELO 的排行榜集成。最后,您将深入了解如何实现响应灵敏、引人入胜的实时多人游戏体验。
设置 Firebase 和项目初始化
Firebase 设置
使用 Firestore 和身份验证初始化 Firebase,以进行实时数据处理和玩家验证。这些将为存储和管理比赛数据、玩家信息和实时排行榜更新提供基础。确保您设置 Firestore 规则来限制对比赛数据的访问,仅允许经过身份验证的玩家查看和更新相关信息。
React 项目结构
将您的 React 项目组织成可重用的组件,这些组件将代表每个游戏元素,例如匹配系统、游戏板、排行榜和聊天。按层次结构构建组件,以获得清晰且可维护的架构。
游戏的关键组件
匹配逻辑
startSearching 函数通过将玩家添加到 Firestore 中的队列来启动匹配过程。如果找到对手,则会创建一个新的比赛文档,存储双方玩家的 ID 并初始化游戏参数。
const startSearching = async () => { const user = auth.currentUser; if (user && db) { try { const matchmakingRef = collection(db, 'tauntWars_matchmaking'); const userDocRef = doc(matchmakingRef, user.uid); await runTransaction(db, async (transaction) => { const userDoc = await transaction.get(userDocRef); if (!userDoc.exists()) { transaction.set(userDocRef, { userId: user.uid, status: 'waiting', timestamp: serverTimestamp() }); } else { transaction.update(userDocRef, { status: 'waiting', timestamp: serverTimestamp() }); } const q = query(matchmakingRef, where('status', '==', 'waiting')); const waitingPlayers = await getDocs(q); if (waitingPlayers.size > 1) { // Pairing logic } }); } catch (error) { setIsSearching(false); } } };
该功能使用 Firestore 交易来确保玩家不会出现双重匹配,否则会破坏匹配系统。 Firebase 的 serverTimestamp 函数在这里很有用,可以确保跨多个时区的时间戳一致。
const startSearching = async () => { const user = auth.currentUser; if (user && db) { try { const matchmakingRef = collection(db, 'tauntWars_matchmaking'); const userDocRef = doc(matchmakingRef, user.uid); await runTransaction(db, async (transaction) => { const userDoc = await transaction.get(userDocRef); if (!userDoc.exists()) { transaction.set(userDocRef, { userId: user.uid, status: 'waiting', timestamp: serverTimestamp() }); } else { transaction.update(userDocRef, { status: 'waiting', timestamp: serverTimestamp() }); } const q = query(matchmakingRef, where('status', '==', 'waiting')); const waitingPlayers = await getDocs(q); if (waitingPlayers.size > 1) { // Pairing logic } }); } catch (error) { setIsSearching(false); } } };
处理游戏阶段
玩家轮流选择嘲讽或回应。 currentTurn 属性指示游戏处于哪个动作阶段。每个动作都会在 Firestore 中更新,从而触发两个客户端之间的实时同步。例如,选择嘲讽的玩家会将 currentTurn 切换为“响应”,提醒对手选择响应。
useEffect(() => { const matchRef = doc(db, 'tauntWars_matches', matchId); const unsubscribe = onSnapshot(matchRef, (docSnapshot) => { if (docSnapshot.exists()) { setMatchData(docSnapshot.data()); if (docSnapshot.data().currentTurn === 'response') { setResponses(getAvailableResponses(docSnapshot.data().selectedTaunt)); } } }); return () => unsubscribe(); }, [matchId]);
计时器组件限制每回合的持续时间。这个超时功能可以维持稳定的游戏流程,并对未能及时行动的玩家进行惩罚,降低他们的HP。
const handleTauntSelection = async (taunt) => { const otherPlayer = currentPlayer === matchData.player1 ? matchData.player2 : matchData.player1; await updateDoc(doc(db, 'tauntWars_matches', matchId), { currentTurn: 'response', turn: otherPlayer, selectedTaunt: taunt.id, }); };
const Timer = ({ isPlayerTurn, onTimeUp }) => { const [timeLeft, setTimeLeft] = useState(30); useEffect(() => { if (isPlayerTurn) { const interval = setInterval(() => { setTimeLeft(prev => { if (prev <= 1) { clearInterval(interval); onTimeUp(); return 0; } return prev - 1; }); }, 1000); return () => clearInterval(interval); } }, [isPlayerTurn, onTimeUp]); };
通过以这种方式模拟攻击,我们可以直观地指示每个嘲讽或响应的力量和结果,从而创造更加身临其境的体验。
const animateAttack = useCallback((attacker, defender) => { const targetX = attacker === 'player1' ? player1Pos.x + 50 : player2Pos.x - 50; const attackerRef = attacker === 'player1' ? player1Ref : player2Ref; attackerRef.current.to({ x: targetX, duration: 0.2, onFinish: () => attackerRef.current.to({ x: player1Pos.x, duration: 0.2 }) }); });
每条消息都会根据用户的 ID 有条件地呈现,以不同的样式区分发送和接收的消息。
const ChatBox = ({ matchId }) => { const [messages, setMessages] = useState([]); useEffect(() => { const chatRef = collection(db, 'tauntWars_matches', matchId, 'chat'); const unsubscribe = onSnapshot(chatRef, (snapshot) => { setMessages(snapshot.docs.map((doc) => doc.data())); }); return () => unsubscribe(); }, [matchId]); };
排行榜根据玩家的 ELO 进行排名,为玩家提供竞争动力和跟踪进度的方式。
技术挑战和最佳实践
与 Firestore 事务的一致性
使用事务可确保同时读取/写入 Firestore 保持数据完整性,尤其是在匹配和评分更新期间。
优化实时监听器
使用 unsubscribe() 进行侦听器清理以防止内存泄漏。此外,限制查询有助于减少 Firestore 读取次数,从而优化成本和性能。
画布响应式设计
CanvasComponent 根据视口调整其大小,使游戏能够跨设备响应。使用react-konva库可以实现交互元素的稳健渲染,通过动画为玩家提供视觉反馈。
处理边缘情况
考虑玩家在游戏中断开连接的场景。为此,实现一个清理功能,以确保更新比赛数据并关闭任何废弃的比赛实例。
总结
借助 Firebase 和 React,您可以创建适应实时用户操作的快节奏多人游戏体验。 Gladiator Taunt Wars 中的示例演示了如何集成实时更新、安全交易和动态动画来制作引人入胜且具有视觉吸引力的游戏。
结论
为《角斗士之战》构建《角斗士嘲讽战争》是一次收获颇丰的旅程,它将 React、Firebase 和沉浸式游戏机制结合在一起,在一款基于 Web 的游戏中捕捉罗马竞技场战斗的激烈程度。利用 Firebase 的实时 Firestore 数据库、安全身份验证和强大的托管功能,我们能够创建无缝、社区驱动的体验,让玩家可以在战略战斗中进行对决。集成 GitHub Actions 进行持续部署也简化了开发,让我们能够专注于增强游戏玩法和用户交互。
随着我们继续扩展《角斗士嘲讽战争》,我们对新功能的潜力感到兴奋,包括人工智能驱动的对手和增强的比赛策略,这将加深游戏体验,让每场战斗都更加身临其境。历史策略与现代技术的结合为玩家提供了一种参与角斗士世界的动态方式。
本系列的后续文章将深入探讨使用 Firebase 创建交互式 Web 应用程序的技术细节,包括优化实时数据流、管理复杂的游戏状态以及利用 AI 增强玩家参与度。我们将探索桥接前端和后端服务的最佳实践,以创建响应迅速的实时多人游戏环境。
无论您是开发自己的互动游戏还是对 Gladiators Battle 背后的技术感到好奇,本系列都提供了有关使用 Firebase 构建现代 Web 应用程序的宝贵见解。加入我们,我们将继续将古代历史与尖端技术相融合,为当今的数字世界重新构想角斗士战斗的刺激。
?发现更多:
探索角斗士之战:潜入罗马世界,体验策略和战斗 https://gladiatorsbattle.com
查看我们的 GitHub:查看我们的代码库和贡献:https://github.com/HanGPIErr/Gladiators-Battle-Documentation。
在 LinkedIn 上联系:在 LinkedIn 上关注我的项目更新 https://www.linkedin.com/in/pierre-romain-lopez/
还有我的 X 帐户:https://x.com/GladiatorsBT
以上是使用 React 和 Firebase 构建实时多人游戏:角斗士嘲讽战争的详细内容。更多信息请关注PHP中文网其他相关文章!