做一个飞行棋的SPA需要用哪些技术

SPA (Single-Page Application)单页应用,通过动态重写的方式与用户进行交互,不用重复刷新整个页面,而是动态刷新其中的一部分。

本文涉及到的知识面都是浅层知识并不复杂,其中包括:

接下来开始叙述这个应用的始末


视图部分:

首先是入口,我采用bootstrap快速搭建一个简单的入口:

输入用户名,房间代号,就可以进入房间。这个时候用jquery把第一个表单隐藏,第二个表单展现出来就行了,至于数据也是用jquery发送,socket.io的函数可以定义一些事件用来监听服务器传来的数据,一旦传来就用jquery更新一下页面数据即可。

这一页会实时显示可以选择的颜色,以及当前其他用户的用户名和所选颜色,凑齐四个人,就用jquery隐藏这个表单,把棋盘展现出来就行了。

而这个棋盘和棋子的定制需要有一些技巧。

那天在看一本书《高性能响应式web开发实战》,第二章节详细的叙述了像素之间的关系,并对css像素以及设备像素之间的关系做了详细解释。其中阐述了最关键的一个<meta>标签属性viewport,这个属性用于告诉浏览器,当前的网页应用要用多少个css像素来渲染,请注意,这个css像素和设备像素是不一样的东西。

举例说明:<meta name="viewport" content="width=300" />

如果你的设备宽度是600,则每个css像素会包含2个设备像素;如果你的设备宽度是1200,则每个css像素会包含4个设备像素。

那么为什么要说这个东西呢?作为一盘飞行棋,我们肯定不希望看到不同设备下,棋子或棋盘产生不同的偏移,并且我们又希望看到的是棋盘刚好占满整个手机宽度,而不是多出去或者留一截空白,如果我们能用同一套标准衡量这个基本单位,就不会有这个问题发生。所以viewport可以完美解决这个问题。

出于时间考虑,我在网上下载了一个没有水印的棋盘:

这个棋盘大小已经比普通手机大很多了,在手机看的效果不需要拉伸,不会产生模糊。

接着我们可以把棋盘放到一个固定的位置,css里使用fixed+top+left的操作就能固定好它。

固定完以后用css做一个棋子出来,并且采集所有的坐标数据,即棋子放在那个位置恰好对着棋盘的某个格子,这个过程比较繁琐,因为棋盘有90个左右的位置,需要花一点时间才能完成。

做完效果还不错:

至此视图部分就算完成了。


逻辑部分:

接下来的问题是怎么与后端建立联系并传输数据?

后端的数据交互是用nodejs写的,主要是用了socket.io模块,所以数据传输的部分用socket.io里的函数就行了,里面的函数也不多,客户端API:https://socket.io/docs/client-api/,服务端API:https://socket.io/docs/server-api/

主要的函数是emit和on,emit是用于发送一个event到另一端的指定事件,而on是用来创建并监听指定事件的。

另外还有一些默认的事件可以监听,例如:

服务器的index.js:

客户端的local.js:

这样当你运行服务端的js文件 node index.js,并且在本地打开一个引用了local.js的html文件时,在服务端和本地的控制台可以看到两端都输出了本次连接的id。

on函数的第一个参数是所监听事件的名称,第二个是一个回调函数,其传入参数是可以不定个数的。上例中我们在服务端监听了 "get message" 事件,它会向回调函数传入一个参数data,一旦这个监听函数被激活,换句话说,一旦前端发送数据到这个事件,这个事件的就会把前端发来的数据传入回调函数,回调函数会把它打印出来。

emit是发送数据的函数,第一个参数是另一端监听的事件名称,其它参数是不定个数不定类型的。

例如在本地端控制台输入socket.emit("get message", "hello server"); 服务端的控制台就会输出 hello server 字样。

另外服务端还有两个函数也是要用的,一个是join,一个是in。join是用来加入房间的,传入一个字符串以后socket就算加入了这间房间,in则是用来操控整个同一房间的连接,例如io.in('room').emit('event', data);可以向所有在room这个房间里的连接发送数据data到其监听的event事件。这在同步所有人的棋局中很管用。


控制部分:

控制部分最麻烦的就是游戏逻辑了,飞行棋没有明确的起源,不过目前普遍认为是国人根据某个外国游戏改造成的。因为找不到明确的起源,所以也没有明确的规则,具体规则由自己拟定。最早想参照的是百度百科的规则,但是因为引进了叠子的情况而十分复杂,所以我先做了一个最简单的规则,就是不考虑叠子的情况,每个棋子踩到别人就把它吃掉,遇到同色就跳格子,遇到飞行格就飞过河。就是这样也还是还是有些钻牛角尖的情况,比如跳了棋子以后刚好能飞过河等等,总之情况依旧很复杂,尝试多次列举都没能成功,不过最后还是被我写出来了这个最简单的规则。

等这些都做完以后就是部署到服务器啦。因为我一直在本地环境运行,所以用http没什么问题,但是我服务器已经完全部署了https(不部署大家都问我为啥是钓鱼网站警告),https环境里是不允许用一些http的不安全连接的,我尝试把index.js也用上https但是事实证明这很复杂,不过换个思路思考,我直接再解析一个https的二级域名,然后用nginx把这个域名转发到127.0.0.1不就解决了。事实证明,这个方法很顶用。后来还提醒了一个wss不能使用的情况,实际上也可以用nginx转发解决,不过它并不影响我的运行结果,所以我没有去解决它。


后面我还会完善游戏规则、改善连接稳定性和添加聊天功能。

链接:https://lab.ghyer.com/fly/

-- 热度:88 ℃
-- 于 共写了2547个字
-- 文内使用到的标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注