当前位置: 首页 > Web前端 > JavaScript

我做了一个《联机桌游合集- UNO+斗地主+五子棋》享受“纯粹”的游戏!

时间:2023-03-26 23:49:25 JavaScript

我是公众号线下派对游戏的作者HullQin(欢迎关注公众号,发送加微信,交朋友)。转载本文前必须获得作者HullQin的授权。我独立开发了《联机桌游合集》,这是一个网页,在这里你可以轻松和朋友一起玩网络游戏,五子棋等游戏,免费,无广告。还为GameJam2022开发了《Dice Crush》,喜欢的话可以关注我HullQin哦~有空我会分享制作游戏的相关技术。0.《联机桌游合集: UNO+斗地主+五子棋》是什么?这是我独立开发的一款H5小游戏。它是棋盘游戏的集合,每一款都可以和朋友一起在线玩。目前包括3款游戏:UNO、Game、Backgammon,未来会不断开发新游戏。地址:game.hullqin.cn特点支持联机和好友同房,可以联机对战。《UNO》支持2-10人一起玩。《斗地主》支持2-4人玩牌。《五子棋》支持1-2人下棋。第一个进入房间的人将成为“房主”,可以修改游戏的玩家人数,待所有玩家填满后房主可以“开始游戏”。游戏中断可以在开始游戏后随时重新连接,如果掉线,或者关闭网页。不管时间多长,只要宿主没有结束游戏,你回到这个房间,就可以继续游戏。就算所有人都关闭了网页,只要游戏还没有结束。回来之后还可以继续战斗!当然,如果游戏还没有开始,或者游戏已经结束,那么你就关闭网页退出房间。Allowspectators当房间满了,后进房间的人可以旁观。游戏结束后,如果房间还有空间,访客可以点击“刷新”成为玩家。1.我为什么要做《联机桌游合集》?之前和朋友聚会,但是没有带卡,所以很多桌游玩不了。我搜索了公众号和小程序,但大部分都是广告满满,或者只支持在线匹配,或者交互复杂。我们迫切需要——无广告、在线支持朋友、简单的工具。因为对前后端有点了解,所以做了一些尝试。上个月,我开了一个公众号“线下派对游戏”来发布这些“工具”。目前,我制作了西洋双陆棋、游戏和UNO。但是因为是网络游戏,所以在线的朋友也可以玩。2、技术选择?为什么?通信毫无疑问,这是一个需要Client和Server频繁交互的场景。不宜使用HTTP轮询或长轮询,会浪费资源。所以我选择了WebSocket作为通信协议。它和HTTP一样也是基于TCP的,但不同的是Client和Server都可以随时主动发送数据和接收数据。这节省了带宽资源。你可能想知道数据序列化协议,这也需要决策?使用无脑JSON还不够吗?但是我真的不使用JSON。因为JSON是基于字符串反序列化的,所以它的体积肯定会比基于二进制的序列化协议更大。因为涉及到频繁的数据交互,加上我的服务器网络带宽不高,我不想一个免费的游戏给我带来太多的成本。所以初期的技术选型尤为重要(如果后期要改,就难了)。我期望有这样一个协议:我定义了数据格式,比如五子棋游戏有2个字段,分别是“谁是黑棋子”和“棋盘上的棋子列表”。我使用第一位,0表示房主是黑人,1表示房主是白人。接下来的8位表示棋盘上有多少个棋子,假设是K,那么接下来的K*8位,每8位代表这K个棋子各自的坐标。这样的数据序列化协议是最短的。但是我为什么要自己创建协议呢?这种东西肯定有现成的协议!我敢肯定这不仅仅是我。检查后,果然有——ProtocolBuffer。这个想法和我脑海中的约定差不多。虽然空间比我心目中的协议大了几分(可以忽略不计),但是扩展性比我心目中的协议好太多了。所以,对于数据序列化协议,我选择了ProtocolBuffer。在这次技术选型中,我节省了带宽资源。数据更新方案这种桌游一定是数据驱动的。服务器保存一份游戏数据,前端根据数据获取当前数据状态,根据数据状态渲染游戏界面。数据更新方案有2种:优缺点方案一:游戏数据每次更新,服务器全量数据同步到前端,前端可以有统一的版本控制。如果游戏数据量很大,那么每次传输的成本就很高。方案二:每次更新游戏数据,增量更新数据从服务端到前端,每次传输成本低。对于并发增量更新,需要保证每个操作都是原子操作;对于非并发增量更新,需要版本控制。如果是你,你会选择几个选项??猜猜我选择了什么计划?您可能认为我将重复相同的技巧并选择选项2以节省带宽。但我选择了选项一。为什么?我的游戏是小游戏,只要游戏数据总量足够小(连一个TCP包都能发),那你把100b压缩成20b也没意义,可能只有21ms和20ms的区别。用户能感觉到21ms和20ms的区别吗?不能。方案2增量更新确实很有吸引力,尤其是像《王者荣耀》这样实时性强,数据量大的游戏。但是我是小游戏,实时性没有那么强。增量更新带来的前后端开发成本更高,远高于收益。后台选择其实只要支持websocket就可以了。我用的是我擅长的python,ASGI协议,还有Daphne来实现。不过python解析protobuf是有代价的。幸运的是,python可以用C++实现。最好的技术选择其实就是直接用C++修改Nginx源码,以Nginx模块的形式实现小游戏后台。但开发成本相对较高。为了快速实现、实现和验证想法,我使用了自己熟悉的python。后面有时间的话,我会以Nginx模块开发的形式重构后端。既然前端选型已经是数据驱动,那么React就完美了。把游戏数据当成State,当你收到后台更新,setState,UI就会自动更新。当然Vue也可以,不过我比较熟悉React。用户认证方案当用户第一次访问时,我会在后台Nginx中埋一个随机数cookie,这个cookie是长期有效的。之后,此cookie用于验证用户。如果没有cookie,websocket将拒绝建立连接。之后,用户可以断开连接并重新连接,因为他的cookie没有改变。如果用户删除cookie,服务器将不再识别他。一个监控解决方案要做一个平台,至少要知道实时在线用户的数量吧?只有这样才能知道服务器的负载情况如何,才能提前扩容。我使用了某云平台的日志工具进行监控。通过后台写入日志,通过统计日志展示服务监控。看个pvuv没问题。3.技术实现亮点UNO是迄今为止我做过的最复杂的桌游。熟悉我的朋友都知道,UNO花了我7天的时间制作。为什么这么快统一的后端框架首先得益于统一的后端框架。所有游戏的后台都是一样的,只是配置文件不同(比如可以设置的最大人数,最小人数,游戏名称等)。相当于把游戏开发的复杂性全部转移到了前端,后端只负责数据的传递。也就是说,其实每个人收到的数据都是一样的(如果你玩游戏,你可以解析数据,你会发现你知道别人的牌。只是解析的成本比较高,并且你需要知道二进制协议才行)我这样做是为了提高开发效率。当然,有些人可能会作弊,但我不会在线匹配,我只是想提供给一群亲密的朋友玩,朋友之间,你还作弊吗?(我不会每分钟都陪你玩hhh)如果你访问前端脚手架和组件库,你会发现它们在外观上看起来非常相似,但是皮肤(色号)不同。因为我做了一套游戏脚手架和组件库,把所有的公共能力都抽取出来放到组件里。以后开发新游戏的时候,只需要写那个游戏特有的业务逻辑,其他的都由脚手架生成。组件库也是现成的,所以开发效率特别高。这就是我能够在7天内开发出UNO的真正原因。其他特点服务器实现简单,无数据库依赖,数据暂存在内存中。如果服务器需要更新重启,游戏数据会保留!有一个简单的DevOps系统可以帮助我快速开发、部署、上线。4.最后,我是公众号线下派对游戏的作者HullQin(欢迎关注公众号,发送加微信,交友),转载本文需作者HullQin授权。我独立开发了《联机桌游合集》,这是一个网页,在这里你可以轻松和朋友一起玩网络游戏,五子棋等游戏,免费,无广告。还为GameJam2022开发了《Dice Crush》,喜欢的话可以关注我HullQin哦~有空我会分享制作游戏的相关技术。