常识 共享 合作 bodog官网

    bodog官网专心于网页资料下载,供给博狗博彩、网页规划、ps资料、图片资料等,服务于【个人站长】【网页规划师】和【web开发从业者】的代码资料与规划资料网站。

    bodog官网供给网页资料下载、博狗博彩
    常识 共享 合作!

    微信小程序运用websocket制造多人版扫雷小游戏

    作者:佳明妈 来历:jquery插件 2016-12-04 人气:
    微信小程序运用websocket制造多人版扫雷小游戏,当然这首要是操练运用微信小程序中的websocket和小游戏制造思路,微信小程序不答应发布游戏类运用。
    微信小程序运用websocket制造多人版扫雷小游戏,当然这首要是操练运用微信小程序中的websocket和小游戏制造思路,微信小程序不答应发布游戏类运用。

    为什么需求websocket?

    传统的实时交互的游戏,或服务器自动发送音讯的行为(如推送服务),假如想做在微信上,或许你会运用轮询的办法进行,不过这太耗费资源,许多的恳求也加剧了服务器的担负,并且推迟问题比较严重。假如是自己开发的app,为了处理这些问题,许多团队会自建socket,运用tcp长链接、自定协议的办法与服务器进行相对实时的数据交互。有才干的团队,选用这种办法天然没什么大问题。不过小团队或许就要花费许多时刻去调试,要处理许多难题,这个在本钱上就划不来。
    H5引入了webSocket来处理网页端的长链接问题,而微信小程序也支撑websocket。这是一个十分重要的特性,所以本系列的文章会专门拿出一篇来谈论websocket。

    webSocket本质上也是TCP衔接,它供给全双工的数据传输。一方面能够防止轮询带来的衔接频频树立与断开的功用损耗,另一方面数据能够是比较实时的进行双向传输(由于是长链接),并且WebSocket答应跨域通讯(这儿有个潜在的跨域安全的问题,得靠服务端来处理)。现在除IE外的浏览器现已对webSocket支撑得很好了,微信小程序再推一把之后,它会变得愈加盛行。
    咱们来规划一个新的demo,一个比较风趣的小游戏,多人版扫雷,精确地讲,多人版挖黄金。

    后台代码:https://github.com/jsongo/mime-server
    前端代码:https://github.com/jsongo/wx-mime
    微信小程序运用websocket制造多人版扫雷小游戏
    游戏规则是这样的:把雷换成金子,挖到金子加一分,每人轮番一次(A挖完轮到B,B挖完A才干再点击),点中金子就算你的,也不会炸,游戏持续,直到把场上一切的金子都挖完游戏才完毕。跟扫雷相同,数字也是表明周边有几个金子,然后用户依据场上现已翻出来的数字来猜哪一格或许有金子。
    这种交互的游戏难点在于,用户的点击操作都要传到服务器上,并且服务器要实时的推送到其它玩家的运用上。别的用户自己也要接纳对方操作时实时传过来的数据,这样才不至于重复点中同一个格子。简略讲,便是你要上报操作给服务器,而服务器也要实时给你推音讯。为了简化整个模型,咱们规则玩家有必要轮番来点击,玩家A点完后,才干轮到玩家B,玩家B操作完,玩家A才干点。
    咱们分几步来完成这个功用。

    一、完成思路

    1、第一步,咱们要先生成扫雷的地图场景

    这个算法比较简略,简述一下。随机取某行某列就能够定位一个格子,符号成金子(-1表明金子)。mimeCnt表明要生成的金子的数量,用相同的办法循环符号mimeCnt个随机格子。生成完后,再用一个循环去扫描这些-1的格子,把它周边的格子都加1,当然有必要对错金子的格子才加1。代码放在这儿。
    微信小程序运用websocket
    其间increaseArround用来把这格金子周边的格子都加1,完成也比较简略:
    履行genMimeArr(),随机生成成果如下:
    微信小程序运用websocket制造多人版扫雷小游戏数组
    -1表明金子。看了下形似没什么问题。接下去,咱们就要接入webSocket了。
    (这个是js版别的,其实生成地图场景的作业是在后台生成,这个js版别仅仅一个演示,不过算法是相同的。)

    2、咱们需求一个支撑webSocket的服务端

    本比方中,咱们运用python的tornado结构来完成(tornado供给了tornado.websocket模块)。当然读者也能够运用socket.io,专为webSocket规划的js言语的服务端,用起来十分简略,它也对不支撑webSocket的浏览器供给了兼容(flash或comet完成)。
    笔者自己比较喜爱运用tornado,做了几年后台开发,运用最多的结构之一的便是它,NIO模型,并且十分轻量级,相同的rps,java或许需求700-800M的内存,tornado只需30-40M,所以在一台4G内存的机子上能够跑上百个tornado服务,而java,对不住,只能跑3个虚拟机。微服务的年代,这一点对小公司很重要。当然假如读者自己对java比较了解的话,也能够挑选netty结构测验一下。
    webSocket用tornado的另一个优点是,它能够在同一个服务(端口)上一同支撑webSocket及http两种协议。tornado的官方demo代码中展现了怎样完成一同运用两种协议。在本游戏中,能够这么用:用户进入主页,用http协议去拉取当时的房间号及数据。由于主页是翻开最多的,进了主页的用户纷歧定会玩游戏。所以主页还没必要树立webSocket链接,webSocket链接首要用来处理频频恳求及推送的操作。主页只要一个恳求操作。选了房间号后,进去下一个游戏页面再开端树立webSocket链接。

    3、客户端

    运用微信小程序开发东西,直接衔接是会报域名安全过错的,由于东西内部做了约束,对安全域名才会答应衔接。所以相同的,这儿咱们也持续改下东西的源码,把相关的行改掉就行修正办法如下:
    找到asdebug.js的这一行,把它改成: if(false)即可。
    1. if (!i(r, "webscoket"))

    懒得修正的读者能够直接运用我破解过的IDE。 建议一个websocket链接的代码也比较简略:
    1. wx.connectSocket({
    2.     url: webSocketUrl,
    3. });

    在调用这个恳求代码之前,先添加下事情监听,这样才知道有没有衔接成功:
    1. wx.onSocketOpen(function(res){
    2.     console.log('websocket opened.');
    3. });

    衔接失利的事情:
    1. wx.onSocketError(function(res){
    2.   console.log('websocket fail');
    3. })

    收到服务器的音讯时触发的事情:
    1. wx.onSocketMessage(function(res){
    2.     console.log('received msg: ' + res.data);
    3. })

    当链接树立之后,发送音讯的办法如下:
    1. wx.sendSocketMessage({
    2.     data:msg
    3. })

    音讯发送
    由于树立链接是需求几回握手,需求必定的时刻,所以在wx.connectSocket成功之前,假如直接wx.sendSocketMessage发送音讯会报错,这儿做一个兼容,假如衔接还没树立成功,则用一个数组来保存要发送的信息;而链接第一次树立时,把数据遍历一遍,把音讯拿出来一个个补发。这个逻辑咱们封装成一个send办法,如下:
    1. function sendSocketMessage(msg) {
    2.     if (typeof(msg) === 'object') { // 只能发送string
    3.         msg = JSON.stringify(msg);
    4.     }
    5.     if (socketOpened) { // socketOpened变量在wx.onSocketOpen时设置为true
    6.         wx.sendSocketMessage({
    7.             data:msg
    8.         });
    9.     } else { // 发送的时分,链接还没树立
    10.         socketMsgQueue.push(msg);
    11.     }
    12. }

    二、demo功用解析

    1、主页entry

    为了简化模型,把要点放在webSocket上,咱们把主页做成自己填写房间号的办法。读者假如自己有时刻和才干的话,能够把主页做成一个房间列表,并显现每个房间有多少人在玩,只要一人的能够进去跟他玩。乃至后边还能够加上观看方式,点击他人的房间进去观看他人怎样玩。
    填写房间号的input组件,添加一个事情,获得它的值event.detail.value后setData到本page里边。
    点击“开端游戏”,再把房间号存入app的globalData里边,然后wx.navigateTo到主游戏页面index。
    这个页面比较简略。

    2、主游戏页面

    咱们封装一个websocket/connect.js模块,专门用来处理websocket链接。首要有两个办法,connect建议webSocket链接,send用来发送数据。 index主页面:
    初始化状况,9x9的格子,每一格子其实都是一个button按钮。咱们生成的地图场景数据,别离对应着每一格。比方1表明周边的1个金子,0表明周边没有金子,-1表明这格是个金子,咱们的方针便是找到这些-1。找得越多得分越高。
    这儿谈论一个安全性问题。信任一句话:在前端做的安全措施大都是不靠谱的。上图中的矩阵,每个格子背面的数据,不应该放在前端,由于js代码是能够调试的,能够下断点在相应的变量上,就能够看到整个矩阵数据,然后就知道哪些格子是金子,就能够做弊,这对错常不公平的。所以最好的办法是把这些矩阵数据存在后端,每次用户操作的时分,把用户点击的坐标发到后台,后台再判别相应的坐标是什么数据,再回来给前端。这个看似有许多数据传输的交互办法,其实是不会浪费资源,由于用户的每个点击操作,原本就要上签到后台,这样游戏的另一玩家才知道你点了哪个格子。横竖都是要传数据的,所以肯定要传坐标,这样前端就彻底没有必要知道哪个格子是什么数据,由于后台的推送音讯会告知你。
    这样咱们就绕过了前端存矩阵数据的问题。可是咱们仍是需求一个数组来存储当时矩阵状况的,比方哪个格子现已被翻开,里边是什么数据,也便是说要存储场上现已被翻开的格子。所以在后台,咱们要存储两个数据,一个是一切的矩阵数据,也便是地图场景数据;另一个是当时状况的数据,这个要用来同步两边的界面。

    3、完毕页面

    游戏完毕的判别条件,便是场上一切的金子都被挖完了。这个条件也是在后台判别的。
    在每次用户挖到金子的时分,后台都会多一个判别逻辑,便是看这个金子是否是最终一个。假如是的话,就发送一个over类型的音讯给游戏的一切玩家。
    玩家终端接纳到这个音讯时,就会完毕当时的游戏,并跳到完毕页面。
    没有专门的规划师,随意网上偷了张图片贴上去,界面比较丑。下方显现自己的得分和当时的房间号。
    三、完成细节

    1、代码结构

    前端代码,分了几个模块:pages放一切的页面,common放通用的模块,mime放挖金子的主逻辑(暂时没用到),res放资源文件,websocket放webSocket相关的处理逻辑。
    后台代码,读者略微了解一下就行了,不谈论太多。里边我放了docker文件,了解docker的读者能够直接一个指令跑起整个服务端。笔者在自己的服务器上跑了这个webSocket服务,ip和端口现已写在前端代码里,读者轻虐。或许放不久,读者能够自己把这个服务跑起来。

    2、音讯收发

    (1)音讯协议

    咱们简略地界说下,音讯的格局如下。 发送音讯:
    1. {type: 'dig', …}

    type是必带字段。
    服务器回来的音讯:
    1. {errCode: 0, data: {type: 'dig', …} }

    errCode为0的时分,表明恳求处理成功,后边带上data字段表明回来的数据,里边的type也是必带字段,表明的是什么类型的音讯。
    由于webSocket类型的音讯跟传统的http恳求不太相同,http恳求没有状况,一个恳求曩昔,一瞬间就回来,回来的数据肯定是针对这个恳求的。而webSocket的模型是这样的:客户端发曩昔许多恳求,然后也不知道服务器回来的数据哪个是对应哪个恳求,所以需求一个字段来把一切的回来分红多种类型,并进行相应的处理。

    (2)发送音讯

    发送音讯就比较简略了,上面咱们界说了一个send办法及未衔接成功时的简略的音讯列表。

    (3)接纳音讯

    读者在阅览代码的时分,或许会有一个疑问,websocket/connect.js里只要send发送办法,而没有接纳推送音讯的处理,那接纳音讯的处理在哪?怎样相关起来的?
    websocket/目录里边还有另一个文件,msgHandler.js,它便是用来处理接纳音讯的首要处理模块:
    从服务器推送过来的音讯,首要有这三种类型:1挖金子操作,或许是自己的操作,也或许是对方的操作,里边有一个字段isMe来表明是否是自己的操作。接纳到这类音讯时,会翻转地图上相应的格子,并显现出挖的成果。2创立或进入房间的操作,一个房间有两个用户玩,创立者先开端。3游戏完毕的音讯,当运用接纳到这类音讯时,会直接跳转到完毕页面。
    这个处理逻辑,是在websocket/connect.js的wx.onSocketMessage回调里相关上的。
    在音讯的收发过程中,每个音讯交互,调试东西都会记载下来。能够在调试东西里看到,在NetWork->WS里就能够看到:

    3、前端挖金子

    代码如下:
    1. var websocket = require('../../websocket/connect.js');
    2. var msgReceived = require('../../websocket/msgHandler.js');
    3. Page({
    4.     data: {
    5.         mimeMap: null,
    6.         leftGolds: 0, // 总共有多少金子
    7.         score: 0,     // 我的得分
    8.         roomNo: 0     // 房间号
    9.     },
    10.     x: 0, // 用户点中的列
    11.     y: 0, // 用户点中的行
    12.     onLoad: function () {
    13.         var roomNo = app.getRoomNo();
    14.         this.setData({
    15.             roomNo: roomNo
    16.         });
    17.         // test
    18.         // websocket.send('before connection');
    19.  
    20.         if (!websocket.socketOpened) {
    21.             // setMsgReceiveCallback
    22.             websocket.setReceiveCallback(msgReceived, this);
    23.             // connect to the websocket
    24.             websocket.connect();
    25.             websocket.send({
    26.               type: 'create'
    27.             });
    28.         }
    29.         else {
    30.             websocket.send({
    31.               type: 'create',
    32.               no: roomNo
    33.             });
    34.         }
    35.     },
    36.     digGold: function(event) { // 不直接判别,而把坐标传给后台判别
    37.         // 被开过的就不管了
    38.         if (event.target.dataset.value < 9) {
    39.           return;
    40.         }
    41.  
    42.         // 取到这格的坐标
    43.         this.x = parseInt(event.target.dataset.x);
    44.         this.y = parseInt(event.target.dataset.y);
    45.         console.log(this.x, this.y);
    46.         // 上报坐标
    47.         this.reportMyChoice();
    48.     },
    49.     reportMyChoice: function() {
    50.         roomNo = app.getRoomNo();
    51.         websocket.send({
    52.             type: 'dig',
    53.             x: this.x,
    54.             y: this.y,
    55.             no: roomNo
    56.         });
    57.     },
    58. });

    在page的onLoad事情里,先更新界面上的房间号信息。然后开端咱们的要点,websocket.connect建议webSocket链接,websocket是咱们封装的模块。然后把咱们msgHandler.js处理逻辑设置到服务端推送音讯回调里边。接着,发送一个create音讯来创立或参加房间。服务端会对这个音讯做出呼应,回来本房间的地图场景数据。
    digGold是每个格子的点击事情处理函数。这儿有一个逻辑,一个格子周边最多有8个格子,所以每个格子的数据最大不或许大于8,上面代码中能够看到有一个9,这其实是为了跟0区别,用来表明场上现在的还没被翻开的格子的数据,用9来表明,当然你也能够用10,100都行。
    wxml的矩阵数据绑定代码如下:
    1. <view wx:for="{{mimeMap}}" wx:for-item="row" wx:for-index="i"
    2.     class="flex-container">
    3.     <button wx:for="{{row}}" wx:for-item="cell" wx:for-index="j"
    4.         class="flex-item {{cell<0?'gold':''}} {{cell<9?'open':''}}"
    5.         bindtap="digGold" data-x="{{j}}" data-y="{{i}}" data-value="{{cell}}">
    6.         {{cell<9?(cell<0?'*':cell):"-"}}
    7.     </button>
    8. </view>

    这个比较复杂些。两层for,第一层遍历行,第二层遍历行里的每个格子的数据。wx:for-item指定里边用到的item的姓名,wx:for-index指定里边用到的key的姓名。每个格子是一个button,class值做了两次判别,假如这个格子的数据小于0,表明它是金子,加上gold这个class,首要是为了给它加款式。而当数据对错9的时分,表明这个格子被翻开了,这时就加上open款式,把色彩设置成橙色。data-x和data-y用来记载格子的坐标,这样的话,用户点击的时分,就能够直接从dataset里取出坐标值,再把这个值发到服务端进行判别。

    4、服务端完成

    简略的提一下就好,由于后台不是本系列文章的要点,尽管这个demo的开发也花了多半的时分在写后台。前后端的音讯交互,凭借了webSocket通道,传输咱们自己界说格局的内容。上面有个截图显现了后台代码目录的结构,划分得比较随意,handlers里存放了的是首要的处理逻辑。webSocketHandler是进口,在它的on_message里,对收到的客户端的音讯,依据类型进行分发,dig类型,分发到answerHandler去处理,create类型,分发到roomHandler里去处理。
    还有一点略微提一下,本比方中的后台webSocket音讯处理也跟传统的http处理流程有一点不相同。便是在最终回来的时分,不是直接回来的,而是播送的办法,把音讯发送给一切的人。比方用户A点击了格子,后台收到坐标后,会把这个坐标及坐标里的数据一同发送给房间里的一切人,而不是独自回来给上报坐标的人。仅仅会有一个isMe字段来告知客户端是否是自己的操作。
    总归,在做webSocket开发的时分,上面说到的,前后端都或许会有一些当地跟传统的http接口开发不太相同。读者测验在做webSocket项目的时分,转化一下思想。
    最终提下一个留意点:微信小程序的websocket链接是大局只能有一个,官方提示:“一个微信小程序一同只能有一个 WebSocket 衔接,假如当时已存在一个 WebSocket 衔接,会自动封闭该衔接,偏重新创立一个 WebSocket 衔接。”
    ↓ 检查全文

    微信小程序运用websocket制造多人版扫雷小游戏由bodog官网收集整理,您能够自在传达,请自动带上本文链接

    bodog官网便是免费共享,觉得有用就多来支撑一下,没有能帮到您,懒人也只能表明遗憾,期望有一天能帮到您。

    微信小程序运用websocket制造多人版扫雷小游戏-最新谈论

    • 货源网 2017-03-27 04:51:40
      [nono拜年]精仿? CASIO(卡西欧) 韩娴宫 Alexander Wang(亚历山大王) Gianvito Rossi MiuMiu(缪缪) Tmo Ford(汤姆·福特) EVISU(福神) ahuo.ml