使用 React 和 Firebase 构建实时多人游戏:角斗士嘲讽战争
简介
在本深入指南中,我们将逐步使用 Firebase 和 React 构建实时多人游戏,并使用 Gladiator Taunt Wars 中的详细示例。在这种游戏模式中,玩家进行策略性的嘲讽决斗,轮流选择和回应嘲讽以减少对手的生命值(HP)。本文将涵盖构建此类游戏的各个方面,包括 Firebase 设置、匹配、游戏状态管理、动画、实时更新和基于 ELO 的排行榜集成。最后,您将深入了解如何实现响应灵敏、引人入胜的实时多人游戏体验。
设置 Firebase 和项目初始化
Firebase 设置
使用 Firestore 和身份验证初始化 Firebase,以进行实时数据处理和玩家验证。这些将为存储和管理比赛数据、玩家信息和实时排行榜更新提供基础。确保您设置 Firestore 规则来限制对比赛数据的访问,仅允许经过身份验证的玩家查看和更新相关信息。
React 项目结构
将您的 React 项目组织成可重用的组件,这些组件将代表每个游戏元素,例如匹配系统、游戏板、排行榜和聊天。按层次结构构建组件,以获得清晰且可维护的架构。
游戏的关键组件
- 主菜单和配对 MainMenu 组件向玩家提供选项,允许他们加入匹配、查看统计数据或访问排行榜。匹配组件有助于实时配对玩家,利用 Firestore 事务来保持一致性。
匹配逻辑
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 函数在这里很有用,可以确保跨多个时区的时间戳一致。
- GameBoard 组件上的实时游戏状态 监听游戏状态变化 GameBoard 组件侦听 tauntWars_matches 集合中的更改。当玩家选择嘲讽或做出响应时,更改会立即反映在 Firestore 中,从而触发两名玩家的重新渲染。
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 切换为“响应”,提醒对手选择响应。
- 玩家动作和嘲讽选择 动作选择组件 该组件显示可用的嘲讽并处理选择过程。玩家选择一个嘲讽或响应,该响应存储在 Firestore 中并触发下一阶段。
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, }); };
- Konva 的生命值和攻击动画 CanvasComponent:使用react-konva来动画健康变化和攻击。生命条直观地代表了因嘲讽而受到或造成的伤害,从而增强了参与度。
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]); };
通过以这种方式模拟攻击,我们可以直观地指示每个嘲讽或响应的力量和结果,从而创造更加身临其境的体验。
- 使用 ChatBox 进行实时聊天 ChatBox 组件是一个实时聊天,显示嘲讽和响应消息。该聊天界面为玩家提供反馈和上下文,创造互动体验。
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 有条件地呈现,以不同的样式区分发送和接收的消息。
- 带有 ELO 排名的排行榜 EloLeaderboard 组件根据 ELO 评级对玩家进行排序。每场比赛都会更新 Firestore 中的玩家评分,该评分是实时获取和显示的。
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中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。
