最近用Jqery写了一个1024小游戏,由于是第一次写小游戏,所以就选了一个基础的没什么难度游戏。具体实现如下:

首先在开发时将整个游戏分成两层(自认为),底层是游戏的数据结构以及对数据的操作,上层是显示出来的用户界面。底层选择使用一个4x4的二维数组,整个游戏的数据操作都围绕着这个二维数组进行。

【一】游戏基础界面

  1. <div id="game">
  2. <div id="header">
  3. <h1>1024</h1>
  4. <button id="newGame">开始新的游戏</button>
  5. <p>分数:<span id="score">0</span>&nbsp;&nbsp;&nbsp;&nbsp;最高分:<span id="maxScore">0</span></p>
  6. <div id="movescore"><p>+16</p></div>
  7. </div>
  8. <div id="container">
  9. <div class="cell" id="cell-0-0"></div>
  10. <div class="cell" id="cell-0-1"></div>
  11. <div class="cell" id="cell-0-2"></div>
  12. <div class="cell" id="cell-0-3"></div>
  13. <div class="cell" id="cell-1-0"></div>
  14. <div class="cell" id="cell-1-1"></div>
  15. <div class="cell" id="cell-1-2"></div>
  16. <div class="cell" id="cell-1-3"></div>
  17. <div class="cell" id="cell-2-0"></div>
  18. <div class="cell" id="cell-2-1"></div>
  19. <div class="cell" id="cell-2-2"></div>
  20. <div class="cell" id="cell-2-3"></div>
  21. <div class="cell" id="cell-3-0"></div>
  22. <div class="cell" id="cell-3-1"></div>
  23. <div class="cell" id="cell-3-2"></div>
  24. <div class="cell" id="cell-3-3"></div>
  25. </div>
  26. <div class="gameover">
  27. <div id="gameoverText">
  28. <p></p>
  29. </div>
  30. <p id="gameoverScore"></p>
  31. <div id="reStart">
  32. <button id="reStartBtn">再玩一次</button>
  33. </div>
  34. </div>
  35. </div>

CSS:

  1. *{
  2. margin:;
  3. padding:;
  4. }
  5. #game{
  6. font-family: Arial;
  7. margin: 0 auto;
  8. text-align: center;
  9. }
  10. #header{
  11. margin: 20px;
  12. }
  13. #header a{
  14. font-family: Arial;
  15. text-decoration: none;/*设置 h1、h2、h3、h4 元素的文本修饰*/
  16. display: block;
  17. color: white;
  18. margin: 20px auto;
  19. width: 125px;
  20. height: 35px;
  21. text-align: center;
  22. line-height: 40px;
  23. background-color: #8f7a66;
  24. border-radius: 10px;
  25. font-size: 15px;
  26. }
  27. #header p{
  28. font-family: Arial;
  29. font-size: 20px;
  30. }
  31. #container{
  32. width: 460px;
  33. height: 460px;
  34. background-color: #bbada0;
  35. margin: 0 auto;
  36. border-radius: 10px;
  37. position: relative;
  38. padding: 20px;
  39. }
  40. .cell{
  41. width: 100px;
  42. height: 100px;
  43. border-radius: 6px;
  44. background-color: #ccc0b3;
  45. position: absolute;
  46. font-size: 3.5em;
  47. font-weight:;
  48. text-align: center;
  49. line-height:100px;
  50. }
  51. #newGame{
  52. width: 120px;
  53. height: 30px;
  54. border-radius: 5px;
  55. border: 1px solid rgb(143,122,102);
  56. background-color: rgb(143,122,102);
  57. color: white;
  58. margin-top: 10px;
  59. margin-bottom: 10px;
  60. }
  61. .gameover{
  62. width: 100%;
  63. height: 500px;
  64. background-color: rgba(255,255,255,0.5);
  65. position: absolute;
  66. top:153px;
  67. display: none;
  68. }
  69. #gameoverText{
  70. font-size: 4em;
  71. font-weight:;
  72. color: #363636;
  73. text-align: center;
  74. opacity:;
  75. padding-top: 10%;
  76. }
  77. #reStartBtn{
  78. width: 100px;
  79. height: 40px;
  80. border-radius: 5px;
  81. border: 1px solid rgb(143,122,102);
  82. background-color: rgb(143,122,102);
  83. color: white;
  84. margin-top: 3%;
  85. }
  86. #gameoverScore{
  87. font-size: 1.5em;
  88. }
  89. #movescore{
  90. position: absolute;
  91. text-align: center;
  92. padding-left: 45%;
  93. top:110px;
  94. font-weight:;
  95. display: none;
  96. }

此时界面的16个格子是重叠在一起的,给每个格子写css比较麻烦,所以通过js循环进行设置:

  1. //初始化绘制表格
  2. function printTab(){
  3. for(var i=0;i<4;i++){
  4. for(var j=0;j<4;j++){
  5. var cell=$('#cell-'+i+'-'+j);
  6. cell.css({top:(20+i*120),left:(20+j*120)});
  7. }
  8. }
  9. }

不同的数字显示不同的背景颜色与文字颜色:

  1. function getBackgroundColor(number){
  2. switch (number) {
  3. case 2:return "#eee4da";break;
  4. case 4:return "#ede0c8";break;
  5. case 8:return "#f2b179";break;
  6. case 16:return "#f59563";break;
  7. case 32:return "#f67c5f";break;
  8. case 64:return "#f65e3b";break;
  9. case 128:return "#edcf72";break;
  10. case 256:return "#edcc61";break;
  11. case 512:return "#9c0";break;
  12. case 1024:return "#33b5e5";break;
  13. case 2048:return "#09c";break;
  14. case 4096:return "#a6c";break;
  15. case 8192:return "#93c";break;
  16. }
  17. }
  18. // 设置相应数字的文字颜色
  19. function getColor(number){
  20. if (number <= 4) {
  21. return "#776e65"
  22. }
  23. return "white";
  24. }

每次操作后根据当前二维数组进行重绘画面:

  1. //根据二维数组绘制画面
  2. function rePrint(checkerboard){
  3. for(var i=0;i<4;i++){
  4. for(var j=0;j<4;j++){
  5. if(checkerboard[i][j]!=0){
  6. var printCell=$('#cell-'+i+'-'+j);
  7. printCell.css('background-color',getBackgroundColor(checkerboard[i][j]));
  8. printCell.css('color',getColor(checkerboard[i][j]));
  9. printCell.text(checkerboard[i][j]);
  10. if(checkerboard[i][j]>=1024){
  11. printCell.css('font-size','2.5em');
  12. printCell.css('font-weight','500');
  13. }
  14. }else{
  15. var printCell=$('#cell-'+i+'-'+j);
  16. printCell.css('background-color','#ccc0b3');
  17. printCell.css('color','black');
  18. printCell.text('');
  19. }
  20. }
  21. }
  22. }

【二】游戏逻辑

除了需要定义一个二维数组checkerboard,还需要定义一个存总分的变量score,一个存每次操作得分的变量addScore,一个记录键盘是否可以操作的变量ableKeyDown,0可以响应键盘操作,1禁止键盘操作。

①游戏初始化

初始化封装成一个函数方便后续的【开始新的游戏】以及【再玩一次】功能。

  1. //初始化游戏
  2. function newgame(){
  3. ableKeyDown=0;
  4. score=0;
  5. checkerboard=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
  6. $('#score').text('0');
  7. $('#maxScore').text(window.localStorage.getItem("maxScore"));
  8. rePrint(checkerboard);
  9. randNum(checkerboard);
  10. randNum(checkerboard);
  11. }

②在随即位置生成2或4

根据游戏规则,在游戏刚开始时会在两个随即位置分别生成2或4,在每次操作后若游戏没结束,会在一个空的位置随机生成一个2或4,将这一功能封装成一个函数,Math.random()生成的随机数范围是[0,1),由于二维数组范围是[0,3],所以通过Math.floor(Math.random()*4)将得到0-3的随机数。另外需要随机得到2或4,定义一个数组initRandNum=[2,4],只需随机得到initRandNum[0]或initRandNum[1]即可,所以同理使用Math.floor(Math.random()*2)随机得到1或2即可。

  1. function randNum(checkerboard){//在随机位置随机产生2或4
  2. var randX = Math.floor(Math.random()*4);
  3. var randY = Math.floor(Math.random()*4);
  4. var initRandNum=[2,4];
  5. var randNum=Math.floor(Math.random()*2);
  6. var randVal=initRandNum[randNum];
  7. while(true){
  8. if(checkerboard[randX][randY]==0){
  9. break;
  10. }else{
  11. var randX = Math.floor(Math.random()*4);
  12. var randY = Math.floor(Math.random()*4);
  13. }
  14. }
  15. checkerboard[randX][randY]=randVal;
  16. printRandNum(randX,randY,randVal);//将randNum()绘制出来
  17. }

在得到上述随即位置的2或4后需要将其绘制出来:

  1. function printRandNum(randX,randY,randVal){
  2. var printRandCell=$('#cell-'+randX+'-'+randY);
  3. printRandCell.css('background-color',getBackgroundColor(randVal));
  4. printRandCell.css('color',getColor(randVal));
  5. printRandCell.text(randVal);
  6. }

③游戏中最重要的两个函数

即判断当前能否移动的函数以及如何移动合并的函数。

1)--------判断能否移动,以左移为例

根据对游戏的观察发现在两中情况下可以移动,一是存在某个不为零的方块,该数字左边为空,即其左边的数组值为0;二是存在某个不为零的方块,,该数字左边与其相同,即其左边的数组值与其相等。对二维数组进行循环,若满足上述条件就返回1,即可以移动。

  1. function canMoveLeft(checkerboard){
  2. for(var i=0;i<4;i++){
  3. for(var j=0;j<4;j++){
  4. if(checkerboard[i][j]!=0){
  5. if(j!=0){
  6. if(checkerboard[i][j-1]==0||checkerboard[i][j-1]==checkerboard[i][j]){
  7. return 1;
  8. break;
  9. }
  10. }
  11. }
  12. }
  13. }
  14. }

2)--------移动合并函数,以左移为例

这个应该是游戏中最重要的函数,根据游戏规则,1)若一个非零方块左边全部为空,它将移动到最左边,若左边的某个不为0,它将移动到这个不为0方块的右边;2)若一个非零方块与左边的数字相同,它将移动到左边并与之合并相加;3)若一个非零方块与左边的数字相同,他与左边合并后的值恰巧与再左边的数相同,此时应该只进行第一次合并,不进行第二次合并。例如当前一排是4,2,2,0,其移动后结果应该是4,4,0,0,而不是8,0,0,0。

第三点尤为重要,最开始由于忽略了这点写出来后结果是不对的。我真对3)的解决办法是,在每次循环一行时初始化一个长度为4的数组var tag=[0,0,0,0],若某个数在此次循环制相加过一次,就在tag相应位置置为1,再然后在每次合并前做一次判断,若该tag为1,则不进行相加。

  1. function moveLeft(checkerboard){
  2. addscore=0;
  3. for(var i=0;i<4;i++){
  4. var tag=[0,0,0,0];
  5. for(var j=1;j<4;j++){ if(checkerboard[i][j]!=0){
  6. if(checkerboard[i][j-1]==0){//左边为空时
  7. for(k=j-1;k>=0;k--){
  8. if(checkerboard[i][k]!=0){
  9. checkerboard[i][k+1]=checkerboard[i][j];
  10. checkerboard[i][j]=0;
  11. if(checkerboard[i][k+1]==checkerboard[i][k]){//移动后与左边相等
  12. if(tag[k]==0&&tag[k+1]==0){
  13. checkerboard[i][k]+=checkerboard[i][k+1];
  14. score += checkerboard[i][k];
  15. addscore+=checkerboard[i][k];
  16. tag[k]=1; checkerboard[i][k+1]=0;
  17. }
  18. }
  19. break;
  20. }else if(k==0){//左边全空
  21. checkerboard[i][0]=checkerboard[i][j];
  22. checkerboard[i][j]=0;
  23. break;
  24. }
  25. }
  26. }else if(checkerboard[i][j-1]==checkerboard[i][j]){//左边相等时
  27. if(tag[j-1]==0&&tag[j]==0){
  28. checkerboard[i][j-1]+=checkerboard[i][j];
  29. score += checkerboard[i][j-1];
  30. addscore+=checkerboard[i][j-1];
  31. tag[j-i]=1; checkerboard[i][j]=0;
  32. }
  33. }
  34. }
  35. }
  36. }
  37. rePrint(checkerboard);//停止移动后重绘画面
  38. }

值得注意的是,为了计算游戏的总分以及每次操作的得分,需要在每次合并后对addScore和score进行计算。

右移、上移、下移与左移逻辑基本相同,只需对左移代码稍作修改即可。

④关于分数

  1. //更新分数
  2. function updateScore(num){
  3. $('#score').text(num);
  4. }

在每次得分后会在总分位置产生一个加分动画

  1. //分数动画
  2. function movescore(score){
  3. if(score>0){
  4. $('#movescore p').text('+'+score);
  5. $('#movescore').css('top','110px');
  6. $('#movescore').show();
  7. var top;
  8. var topVal=110;
  9. var opacityVal=1;
  10. var timer=null;
  11. timer=setInterval(function(){
  12. topVal-=5;
  13. opacityVal-=0.1;
  14. top=topVal+'px';
  15. $('#movescore').css('top',top);
  16. $('#movescore').css('opacity',opacityVal);
  17. if(topVal<50){
  18. clearInterval(timer);
  19. $('#movescore').hide();
  20. }
  21. },40);
  22. }
  23. }

⑤游戏结束

若二维数组中某一项等于1024游戏结束,显示最终得分,并设置键盘不可继续操作;或者当前无法继续移动游戏结束,显示最终得分。

  1. //游戏结束函数
  2. function gameOver(checkerboard){
  3. if(canMoveLeft(checkerboard)!=1&&canMoveRight(checkerboard)!=1&&canMoveUp(checkerboard)!=1&&canMoveDown(checkerboard)!=1){
  4. $('.gameover').show();
  5. $('#gameoverText p').text('Game Over !');
  6. $('#gameoverScore').text('最终得分'+score);
  7. if(score>window.localStorage.getItem("maxScore")){
  8. window.localStorage.setItem("maxScore",score);
  9. $('#maxScore').text(window.localStorage.getItem("maxScore"));
  10. }
  11. }
  12. for(var i=0;i<4;i++){
  13. for(var j=0;j<4;j++){
  14. if(checkerboard[i][j]==1024){
  15. ableKeyDown=1;//键盘不可操作
  16. $('.gameover').show();
  17. $('#gameoverText p').text('Congratulations!');
  18. $('#gameoverScore').text('最终得分'+score);
  19. if(score>window.localStorage.getItem("maxScore")){
  20. window.localStorage.setItem("maxScore",score);
  21. $('#maxScore').text(window.localStorage.getItem("maxScore"));
  22. }
  23. break;
  24. }
  25. }
  26. }
  27. }

⑥开始新游戏&再玩一次

  1. //开始新游戏
  2. $('#newGame').click(function(){
  3. newgame();
  4. });
  5. //再玩一次
  6. $('#reStartBtn').click(function(){
  7. $('.gameover').hide();
  8. newgame();
  9. });

JQuery实现1024小游戏的更多相关文章

  1. js、jQuery实现2048小游戏

    2048小游戏 一.游戏简介:  2048是一款休闲益智类的数字叠加小游戏 二. 游戏玩法: 在4*4的16宫格中,您可以选择上.下.左.右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合 ...

  2. jQuery实现拼图小游戏

    小熊维尼拼图                                                                                    2017-07-23 ...

  3. jQuery 打气球小游戏 点击气球爆炸效果

    最近在学习前端,看到偶尔看到前端小游戏,就想自己写一个小游戏,奈何水平有限,只能写打气球这种简单的,所有的气球都是动态生成的,气球的颜色也是随机的 html部分 <div class=" ...

  4. 基于jQuery的2048小游戏设计(网页版)

    上周模仿一个2048小游戏,总结一下自己在编写代码的时候遇到的一些坑. 游戏规则:省略,我想大部分人都玩过,不写了 源码地址:https://github.com/xinhua6/2048game.g ...

  5. jquery实现抽奖小游戏

    在很多网站或游戏活动中我们都会看到有关抽奖的活动或界面: 下面我将给大家介绍下如何通过javascript来实现这样的一个抽奖功能,主要从下面三个步骤入手(文中着重介绍第三部分有关功能的实现): 1. ...

  6. jQuery之-拼图小游戏

    在线实例:http://lgy.1zwq.com/puzzleGame/ 源代码思路分析: [一]如何生成图片网格,我想到两种方法: (1)把这张大图切成16张小图,然后用img标签的src (2)只 ...

  7. 在HTML页面中有jQuery实现实现拼图小游戏

    1.用jQuery实现拼图小游戏 2.首先获得td的点击事件.再进行交换位置 3.下面这种仅供参考 4.下面这些是HTMl标签 当这个世界变得越来越复杂的时候,内心最需保持一份简单一份纯真:

  8. jQuery实践-网页版2048小游戏

    ▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...

  9. JQuery&原生js ——实现剪刀石头布小游戏

    前言 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库( 或JavaScript框架).jQuery设计的宗旨是“write L ...

随机推荐

  1. ADSL 动态IP拨号VPS 软件配置

    http://yun.baidu.com/share/link?uk=2520566727&shareid=330788421&third=0&adapt=pc&fr= ...

  2. 从零开始学 Web 之 CSS3(八)CSS3三个案例

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  3. C/C++和Lua是如何进行通信的?

    为了实现Lua和其他语言之间的通信,Lua虚拟机为C/C++提供了两个特性: Lua_State状态机 lua_State主要是管理一个lua虚拟机的执行环境, 一个lua虚拟机可以有多个执行环境.L ...

  4. go runtime.Gosched()的作用分析

    untime.Gosched()用于让出CPU时间片.这就像跑接力赛,A跑了一会碰到代码runtime.Gosched()就把接力棒交给B了,A歇着了,B继续跑. 看代码: package main ...

  5. 深度学习论文翻译解析(三):Detecting Text in Natural Image with Connectionist Text Proposal Network

    论文标题:Detecting Text in Natural Image with Connectionist Text Proposal Network 论文作者:Zhi Tian , Weilin ...

  6. python解析处理snmp回显----snmp

    查看服务端配置:https://www.cnblogs.com/dpf-10/p/9175409.html 查看内容示例: D:\python>snmpwalk -v 2c -c public ...

  7. Postman接口测试_添加断言

    1.设置环境变量 postman.setEnvironmentVariable("key", "value");  例子: postman.setEnviron ...

  8. [SPOJ22343] Norma

    Description 现在有一个长度为\(N(N\leq 500000)\)的序列,定义区间\([l,r]\)的价值为\([l,r]\)的最小值乘上\([l,r]\)的最大值乘上\([l,r]\)的 ...

  9. 按值传递 vs. 按指针传递

    按值传递还是指针传递? 变量赋值有两种方式:按值传递.按"指针"传递(指针也常称为"引用").不同的编程语言赋值的方式不一样,例如Python是按"指 ...

  10. Python爬虫之多线程下载程序类电子书

      近段时间,笔者发现一个神奇的网站:http://www.allitebooks.com/ ,该网站提供了大量免费的编程方面的电子书,是技术爱好者们的福音.其页面如下:   那么我们是否可以通过Py ...