TAT.vorshen 从零到一,撸一个在线斗地主上篇
In 未分类 on 2019年07月30日 by view: 3,468
0

背景:朋友来深圳玩,若说到在深圳有什么好玩的,那当然是宅在家里斗地主了!可是天算不如人算,扑克牌丢了几张不全……大热天的,谁愿意出去买牌啊。不过问题不大,作为移动互联网时代的程序猿,当然是撸一个手机在线斗地主来代替实体牌了。

github 地址:https://github.com/vorshen/landlord

阅读前注意:
本文分为上下两篇,本篇讲准备工作以及前端一些布局相关的知识;下一篇讲 webassembly 实现核心逻辑和 server 端相关。

由于源码在 github 上全部都有,所以文章更偏向于思路的讲解。

业余时间有限,游戏样式丑= =,有些细节也没打磨,敬请谅解。不过还是达到了闭环,线下开黑娱乐应该没有问题。

17张牌,你能秒我?

游戏大概样式
游戏大概样式

准备

技术选型与准备

typescript + canvas + webassembly + c++(server)
首先肯定是 Web 的,人齐有个局域网 server 端启动,然后 QQ、微信、浏览器访问,直接就开干了啊。既然是 Web 的,那必须是 typescript 啊,我觉得写过 ts 的,这辈子应该不会再想写 js 了吧……

斗地主作为一个元素不多、没炫酷场景的游戏,其实 dom 完全可以吃得住。但是做个 Web 游戏,不用个 canvas 作为舞台,总感觉哪里不对劲。所以最终我们还是用 canvas 来渲染。这里我们就没有用成熟的渲染引擎了,锻炼锻炼自己。

既然作为练手作品,总要折腾点,webassembly 作为目前很火的技术,我们当然要尝试一下啦,所以游戏的一些核心逻辑采用了 webassembly 实现,这里会在下一篇详细讲解。

编码前

既然是自己从零到一,产品设计开发都得是自己,我们先简单梳理一下游戏的流程。我们这个斗地主不同于 QQ 斗地主,QQ 斗地主是随机进入房间,无法开黑。而我们追求的是一起玩,所以游戏房间的概念是一大不同。

简单列了一下我们游戏的流程:

  1. 快速进入,即开即玩,无需注册
  2. 创建房间或搜索加入房间
  3. 进入房间之后,传统的斗地主逻辑

传统的斗地主逻辑如下:
传统斗地主逻辑

虽然这里贴出来了,但自己真正开始写的时候,压根没梳理,就是一把梭,上来就撸码。结果发现了不少逻辑上的冲突点和细节点,斗地主看起来是一个小游戏,不过逻辑还蛮复杂的,再加上在线非单机,完全低估了游戏的复杂度,一把辛酸泪……

设计没啥好说的,从网上找了几个图就当作基本的元素了(难看就难看了……没办法)

下面就正式开始了

布局

横屏

首先斗地主这个游戏是横屏的,这个蛋疼了,因为 web 对横屏的控制太弱了一点。我们无法强制横版,全部依赖系统的行为。

既然横屏限制多不好用,那么我们能不能直接用竖屏来模拟横屏呢?也就是手机保持竖屏状态,然后我们整个页面旋转一下,就模拟了竖屏了,写样式布局啥的,完全可以按照横屏的来写,还是挺方便的。

原理如下:
模拟横屏的原理

大概代码

注意!这样的横屏,会导致无法直接使用点击事件的 clientX/Y,这里也需要进行一下转换,具体代码在 Stage.ts 中,这里不再展开。

不过这种方案在模拟器上看起来没啥问题,真机上还是有缺陷的,就是标题栏的问题,如图
标题栏无法横过来

不过我觉得这个还行,无伤大雅,所以就采取了这种方式

适配

游戏分为三个场景页面:首页,大厅页,房间页。其中首页和大厅页其实也就是走个流程,我们很随意,房间页就是对战相关,最为复杂,这里就以房间页来说。下面是经典的 QQ 斗地主的房间页:

QQ斗地主

我们大致划分一下模块,如图所示:
QQ斗地主,模块分析

不考虑细节的情况下还是比较简单的,可以看出,主要就是六大区域:

  1. 顶部信息展示区
  2. 底部信息展示区
  3. 左侧玩家区域
  4. 右侧玩家区域
  5. 主视角玩家区域
  6. 特效区域

我们这就不考虑出牌特效啥的了(找几个基础的素材就要了我命了),如果用 dom 实现,那直接 flex 就安排的明明白白,如下(只是举例子,没有用前面横屏的方式)