十一马上就要到了~~做为前端的小伙伴~活动页面必然是少不了了~那怎么吸引眼球呢?当然是玩游戏啦~这次就带来一个我为十一做的小游戏,作为活动页中的衬托~~

那我们要做个什么样的游戏呢?先上图~

由于实际的效果图因为是公司的活动,我就不贴出来了~这里用这个棋盘来大致说明一下效果咯~下面是游戏规则:

1,当用户看到棋盘的时候,棋子出现在上一次停留下来的位置;

2,当用户点击开始后,中间的骰子开始摇动,最后停止在服务器返回的数字前;

3,当骰子结束动画后,棋子还是移动,一步一步的向前移动,遇到四个顶点的时候自动转弯,并最终停留在骰子步数前进的位置前;

4,当棋子结束移动后,页面上显示用户最后剩下的游戏次数,并且如果移动到有礼物的位置时弹出遮罩告诉用户获奖;

5,在整个游戏期间,不允许用户继续点击开始按钮,并且当用户剩余次数用完之后开始按钮变色;

游戏规则都说明了,那么需求分析就到这里了,下面介绍页面布局:

HTML结构:

<div class="game"><div class="gameimg"><div id="pieces" class="p0-0">    <!-- 棋子 --><img src="data:images/pieces.png" /></div><div class="play"><div class="dice">     <!-- 骰子 --><img id="dice" class="dicelo2" src="data:images/dice.png" /></div><div class="playnum">您今天还有<span id="pn">0</span>次游戏机会</div><div id="playbtn"><img src="data:images/btn_start_gray.png" /></div></div></div>
</div>

整体的结构就是一个大的div标签,它的背景是整个棋盘,然后棋子通过相对布局定位在背景图的18个位置上,然后骰子和开始按钮以及说明都居中显示在背景图的中心。

CSS样式:

对于css样式来说,主要用到的是相对定位,设置了18个位置的css样式,而且命名规则是按照 ’p0-0‘这样的方式来命名?为什么我要这样呢?这样可以用类名保存矩阵坐标的位置。棋盘上的位置1对应坐标的1-0、2对应2-0…..依此类推。最后就可以方便的设置棋子的位置了。同时,对于骰子的动画,是通过一整张png图片来进行定位。从骰子的1到6然后是动起来的3副图片,一共9张图片保存在一整张png中,然后依旧采用相对定位的方式来给用户展示。首先是骰子开始运动,我就循环显示最后3张动起来的图片,然后当动画结束后将位置停留在所要显示对应的数字前。

这样把部分图片贴出来就很明显的说明了我的意图~

javascrpt逻辑篇:

首先是进入页面的加载,流程就是首先通过jsonp请求服务器,获取该用户上次的棋子位置,和剩余次数等基础信息,然后渲染在页面中,我就不在这里展开了,这里注意想说的是负责棋子移动和骰子摇动的逻辑部分。

那么按照游戏规则,首先是骰子的摇动,当点击开始按钮后请求服务器结束后调用骰子执行函数,接着将服务器返回的骰子数字和到达的位置传递给复制骰子动画的函数。

/*** 操作骰子的执行函数** @method play_dice** @param  {ing}  dice_num  [骰子数字]* @param  {int}  next_step [到达位置]*/
function play_dice (dice_num, next_step) {var _stop = dice_num,_pande = next_step;diceroll($('#dice'), _stop, _pande);
}

/*** 摇动骰子的动画函数** @method diceroll** @param  {object} dice      [骰子对象]* @param  {int}    num       [摇动的结果]* @param  {int}    _pande    [棋子停下的位置]*/
function diceroll(dice, num, _pande){var i = 0,b = 0,a = function(i) {b = setTimeout(function() {dice.removeClass().addClass('dicelo' + (i % 3 + 7));   // 清除上次动画后的点数i++;if (i > 5) {// 这里的dicelo9是骰子最后一幅动画的类名,删除后依次添加dicelo7,dicelo8 dice.removeClass('dicelo9').addClass('dicelo'+num);var j = $('#pieces').attr('class').substr(1) || 1,n = j + _pande;var oldstep = _pande-num-1;person.step = num;run(person, true);//  1右,2下,3左,4上
                     clearTimeout(b);i = 0;} else {a(i);}}, 200);};a(i);
}

这里通过一个定时器,不断的循环骰子摇动的这个动画,然后在执行5次之后就让骰子停下来,同时清除定时器,然后在骰子停止摇动之后触发棋子移动的函数,在run函数中需要两个参数,如果第二个参数为true,就让棋子还是移动,否则的话则只是计算棋子的矩阵坐标。而person这个对象中保存着坐标位置start: [0, 0],所要前进的步数step,和当前前进的方向de,de的值我设定为1右,2下,3左,4上 。下面是棋子移动的函数。

/*** 控制棋子的移动和棋盘坐标的转换** @method run** @param  {object}  person [棋子移动的坐标]* @param  {Boolean} isAn   [棋子是否需要移动]** @return {object}         [棋子移动的坐标]*/
function run (person, isAn) {var _start = person.start,_step = person.step,_de = person.de;// 棋子移动过程的坐标集合gameList = new Array();for (var i = 1; i <= _step; i++) {if (_de == 1) {  // 棋子向右移动_start[0] += 1;if (_start[0] == 5) {_de = 2;}}else if (_de == 2) {  // 棋子向下移动_start[1] += 1;if (_start[1] == 4) {_de = 3;}}else if (_de == 3) {  // 棋子向左移动_start[0] += -1;if (_start[0] == 0) {_de = 4;}}else if (_de == 4) {  // 棋子向上移动_start[1] += -1;if (_start[1] == 0) {_de = 1;}}gameList.push([_start[0], _start[1]]);  // 将移动后的结果保存在集合中
    }// 当需要棋子移动时执行if (isAn) {var j = 0,d = 0,c = function(j) {d = setTimeout(function() {$('#pieces').attr('class', null).addClass('p'+gameList[0][0] + '-' +gameList[0][1]);gameList.shift(0);j++;if (gameList.length == 0) { // 如果棋子移动结束后则弹出相应的结果
                          returndice(_start);clearTimeout(d);} else {c(j);}}, 500);};c(j);}person.start = _start;person.step = 0;person.de = _de;return person;
}

这里依旧是使用定时器来重复显示棋子的移动过程,由于定时器是异步执行的,所以我将函数产生的一个运动结果保存在数组中,然后在异步的定时器中一个个的遍历数组中的结果,每次取出数组中的第一个结果,执行移动之后便移除第一个结果,后面的结果顶上来,下次取出的第一个结果就是下一次需要移动的结果,最终在结束移动的时候及队列清空的情况下清除定时器,然后我在代码中执行了returndice函数来显示移动后的结果,如果中奖了则调出遮罩提示用户的获奖情况。

总结:

到这里,全部的逻辑基本都说明白了,其实整体来说就是3个函数的循环调用,为了保证在移动端上的性能,在每次定时器结束之后都需要及时的清除掉定时器,否则会出现定时器覆盖的情况,在我测试的时候如果没有及时清除定时器的话,在执行20000+的时候会出现移动的步数比实际的情况少一步的情况,最开始的时候我在最后写了校验函数来保证最终棋子停下来的位置与服务器返回的一致,本来以为是误差,结果后来再测试的时候发现校验的时候会出现棋子闪现的情况,这是很不好的用户体验,而且按照我棋子移动的逻辑来看,是不可能出现错位的,所以理论上是不需要校验函数的,所以再经过仔细查看代码后发现了第二次棋子移动的定时器在使用后并没有及时清除,在用户游戏次数较少的时候是很难出现bug的,但是自动测试的时候接近于无限的次数很容易出现错误的情况,所以还是很重要的bug,还好及时发现。。。o(︶︿︶)o 最后为了保证在一次游戏的过程中用户不能继续点击开始按钮,所以在开始摇骰子的时候将全局锁设置为false,并在最后棋子结束移动之后再打开全局锁。到此为止,所有的游戏规则都满足了~~

今天就到这里吧。。。下次带来一个页面跑马灯的效果~~

转载于:https://www.cnblogs.com/fuhuixiang/p/4845291.html

我的前端故事----欢乐大富翁( ̄︶ ̄)↗ (摇骰子+棋盘)相关推荐

  1. 新手小白开始学习verilog(学习方法有点歪门邪道的,大佬勿喷( ̄▽ ̄)“)

    新手小白开始学习verilog(学习方法有点歪门邪道的,大佬勿喷( ̄▽ ̄)") #一. 编译环境安装 我用的是Quaters,不会装的话我推荐正点原子的教程爱学习的万能B站 ##二. 基本知 ...

  2. 转载==数论倒数,又称逆元(我整个人都倒了( ̄﹏ ̄))

    数论倒数,又称逆元(我整个人都倒了( ̄﹏ ̄)) 数论倒数,又称逆元(因为我说习惯逆元了,下面我都说逆元) 数论中的倒数是有特别的意义滴 你以为a的倒数在数论中还是1/a吗 (・∀・)哼哼~天真 先来引 ...

  3. Windows通过pip下载安装bs4安装包o( ̄ヘ ̄o#)

    前段时间周董的歌开始需要会员才可以听了,而且鹅厂的音乐文件下载以后你会发现底层被加密了,是qmcflac格式的...这咋办?只能爬取了呗,先不管解密的事情,得先下载下来文件呀>_<.Pyc ...

  4. [UE4/5]蓝图制作手雷(上)d=====( ̄▽ ̄*)b手雷抛物线

    [UE4/5]蓝图制作手雷(上)抛物线d=====( ̄▽ ̄*)b 文章目录 [UE4/5]蓝图制作手雷(上)抛物线d=====( ̄▽ ̄*)b 一.准备 二.开始 1.设置输入 2.书写蓝图 一.准备 ...

  5. 【科技橙就新商业】淘系技术走进四川大学,讲述淘宝天猫的前端故事

    2021年5月13日14时,以"科技橙就新商业"为主题,由CCF.四川大学计算机学院(软件学院)主办.CCF四川大学学生分会.CCF四川会员活动中心和阿里巴巴淘系技术共同承办的&q ...

  6. cad表示计算机辅助,CAD计算机辅助设计之快捷键篇~( ̄▽ ̄)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 DV, *DVIEW 定义平行投影或透视视图 FI, *FILTER 为对象选择创建可重复使用的过滤器 G, *GROUP "对象编组" ...

  7. ( ̄▽ ̄) 关于河北ETC记账卡的默认密码

    去营业厅问了下,是6个1(111111),一般人我不告诉他 ...( _ _)ノ| 好吧,在技术博客里发这种东西合适吗? 还有就是,如果需要打印单位抬头发票的话,需要携带委托书盖单位公章(委托书可以去 ...

  8. 终于学会上传图片了\( ̄︶ ̄*\))

    action bigItem 要点 使用smartupload jar 包 html 表单提交数据有三种类型的提交 bigItem 做项目,发现了一个技术难点. 要上传图片到服务器. 要点 1,sma ...

  9. [-1]是也乎,( ̄▽ ̄)

    2019独角兽企业重金招聘Python工程师标准>>> 先说为毛用纯文字形式: 省时间,限字数,易分享; 唯一问题是无法满屏...不过, 事实上以私人吐糟为格调的公众号,当然得作者爽 ...

  10.  ̄□ ̄他咬了蜘蛛一口,从此蜘蛛精通C语言

    Root 编译自 Wired 量子位 出品 | 公众号 QbitAI  这个人,只能是谷歌新任的AI掌门人Jeff Dean了. 非Coder也就只能看懂这个梗了~ 4月初,谷歌宣布分拆搜索和AI ...

最新文章

  1. JavaScript,25 岁生日快乐!
  2. android服务器压力测试,Android压力测试Monkey工具
  3. 机器学习-tensorflow
  4. 《大数据》2015年第2期“前沿”——大数据技术发展的十个前沿方向(上)
  5. APP中某个页面巨卡
  6. 7z001怎么解压在安卓手机上面_安卓手机怎么设置网易企业邮箱
  7. 安卓应用和ios应用下载地址生成一个统一二维码
  8. 我所了解的GB2312、Unicode、GBK、UTF-8、BIG5等编码
  9. 安卓逆向和手游辅助学习路线
  10. Ubuntu 图标主题 Nitrux 升级
  11. 理解两个函数乘积的导数的一种视角
  12. C语言:梯形面积的求解公式为 S = (a + b) * h / 2。从键盘读入一个梯形的上底a、下底b和高h,请计算表梯形的面积。(结果保留1位小数)
  13. HDOJ--1162--Eddy's picture
  14. 小程序 订单倒计时系列
  15. String字符串分割的3种方法 Java
  16. vba中定时器的用法
  17. 通达信资金净流入公式_通达信资金净入净出指标公式
  18. 一站式在线医疗解决方案,即构音视频技术助建互联网医疗
  19. RestTemplate设置通用header 并获取header请求参数
  20. ERP软件中功能测试的实用方法

热门文章

  1. u盘计算机里打不开怎么办,电脑能识别U盘但是打不开怎么办
  2. wex5 tomcat配置php,WeX5 Tomcate 发布
  3. 商业虚拟专用网络技术二通用路由封装
  4. 9个最适合Elementor的免费主题【官方推荐】
  5. 天梯L2-029 特立独行的幸福
  6. 记一次奇怪的truecrypt解密,隐藏分区的MasterKey
  7. 《UnityAPI.Color颜色》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+Color+Lerp+RGBToHSV+gamma+linear+立钻哥哥++OK++)
  8. 6s126发邮件服务器错误,iphone6s的邮件设置教程
  9. 麒麟V10系统安装教程
  10. 输入整形 matlab仿真