使用jquery实现2048小游戏(1)

如果你对jquery完全不懂,请看以下准备知识:
准备知识:
http://www.jianshu.com/writer#/notebooks/7726663/notes/9065929
http://www.jianshu.com/writer#/notebooks/7726663/notes/9070196
http://www.jianshu.com/writer#/notebooks/7726663/notes/9199977
http://www.jianshu.com/writer#/notebooks/7726663/notes/9220485
http://www.jianshu.com/writer#/notebooks/7726663/notes/9240458

第一步:创建背景和背景块

1.创建有一个div的html,引入jquery库,并调用make2048方法
html代码链接:https://github.com/wangyiman/2048Demo1/blob/master/index.html
2.为jquery对象添加make2048()扩展方法
关于函数的扩展方法详细参看http://www.jianshu.com/writer#/notebooks/7726663/notes/9240458

$.fn.make2048 = function(option){
}

3.在方法内创建对象实现默认配置,这里的block_width,block_height,等css,style设置没有必要加上px,具体参看其中以font-size属性为例,做了一下简单说明:http://www.jianshu.com/writer#/notebooks/7726663/notes/9199977

//默认配置
var defaultOption = {
width:4,
height:4,
style:{
//背景颜色
background_color:"rgb(184,175,158)",
//背景块颜色
block_background_color:"rgb(204,192,178)",
padding:18,
//块的默认大小
block_width:100,
block_height:100
}

}
//如果传入了option,则覆盖defaultOption,否则则使用默认的defaultOption,扩展该方法对象
option = $.extend({},defaultOption,option);
console.log("游戏配置",option);
if(this.length>1) throw "只能打开一个游戏";
if(this.length==0) throw "未找到游戏容器";

4.用jquery创建2048背景,通过操作css来实现

//获取容器
$this=$(this[0]);
//使用json
$this.css({
    "background-color":option.style.background_color,
    "border-radius":option.style.padding,
    "position":"relative",
    //不允许用户在网站上选择文本
    "-webkit-user-select":"none"
    
});

5.用jquery创建2048背景块,创建块,添加css,加入数组,把数组放入页面
<a name="first">根据坐标获取位置函数</a>

//根据坐标获取位置函数
var getPosition=function(x,y){
return {
  "top":option.style.padding+y*(option.style.block_size+option.style.padding),
  "left":option.style.padding+x*(option.style.block_size+option.style.padding),
}
}
//创建背景块函数
var buildBackgroundBlocks=function(){
  for(var i =0;i<option.width;i++){
   for(var j=0;j<option.height;j++){
  //存放块的数组
 var backgroundBlocks =[];
   //创建块
    var bg_block = $("<div></div>");
   //获取块的x,y坐标
    var position=getPosition(i,j);
   //在块中添加css
    bg_block.css({
      "background-color":option.style.block_background_color,
      "width":option.style.block_width,
      "height":option.style.block_height,
      "top":position.top,
      "left":position.left
});
backgroundBlocks.push(bg_block);
}
}
$this.append(backgroundBlocks);
}
//调用函数显示块
buildBackgroundBlocks();

结果如图:


此时发现,父级背景颜色没有被撑开,此时要把父级容器手动加宽高修改4中代码如下:

//获取容器
$this=$(this[0]);
//使用json
$this.css({
    "background-color":option.style.background_color,
    "border-radius":option.style.padding,
    "position":"relative",
    //不允许用户在网站上选择文本
    "-webkit-user-select":"none"
       "width":option.style.block_size*option.width+option.style.padding*(option.width+1),
        "height":option.style.block_size*option.width+option.style.padding*(option.width+1)
    
});

此时结果如下:

第二步:生成随机背景块

随机生成数字块,也是比较重要的一步
1.首先,在之前的生成背景块的代码中添加空块,比较简单,就添加两行代码

//声明空块
var state=[];
var buildBackgroundBlock=function(){
    var backgroundBlocks=[];
    for(var i=0;i<option.width;i++){
        for(var j=0;j<option.height;j++){
        //先填上null
            state.push(null);
            var bg_block = $("<div></div>");
            var position = getPosition(i,j);
            bg_block.css({
                "width":option.style.block_size,
                "height":option.style.block_size,
                "background-color":option.style.block_background_color,
                "position":"absolute",
                "left":position.left,
                "top":position.top

                
            });
            backgroundBlocks.push(bg_block);
    }}
    $this.append(backgroundBlocks);

}

我们就有了一个装满空块的state,然后我们写创建随机移动的块的函数,用each方法遍历并得到空块的各个索引值,each方法具体使用请参看:http://www.jianshu.com/writer#/notebooks/7726663/notes/9199977

//获取空块的各个索引值函数
var getIndex = function(){
    var arr=[];
    $(state).each(function(i,o){
if(o==null) arr.push(i);
});
return arr;
}

var buildBlock=function(){
//得到索引数组,得到所有空块的索引
  var emptyBlock = getIndex();
//如果所有空块被填满返回错误
 if(emptyBlock.length==0) return false;
//生成随机空块
var putIndex;
//注意,随机函数,包括前面的不包括后面的
putIndex = emptyBlock[Math.floor(Math.random()*emptyBlock.length)];

  return true;
}

2.生成随机空块之后,我们就可以创建数字块,及其样式来填补这些随机块啦,在上面代码的基础上,我们可以完善buildBlock()函数,在这之前,我们需要在配置文件中添加一个blocks数组,block数组中是动态的方式,并在style中添加公共的字体样式,以便进行随机空块内容和样式的填补:

blocks:[{level:0,value:2,style:{"background-color":"rgb(238,228,218)","color":"rgb(124,115,106)","font-size":58}},
    {level:1,value:4,style:{"background-color":"rgb(236,224,200)","color":"rgb(124,115,106)","font-size":58}},
    {level:2,value:8,style:{"background-color":"rgb(242,228,218)","color":"rgb(255,247,235)","font-size":58}},
    {level:3,value:16,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,250,235)","font-size":50}},
    {level:4,value:32,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":50}},
    {level:5,value:64,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":50}},
    {level:6,value:128,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":42}},
    {level:7,value:256,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":42}},
    {level:8,value:512,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":42}},
    {level:9,value:1024,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":34}},
    {level:10,value:2048,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":34}},
    {level:11,value:4096,style:{"background-color":"rgb(238,228,218)","color":"rgb(255,247,235)","font-size":34}},
]
//需要写在style中
block_style:{
"font-family":"微软雅黑",
"font-weight":bold,
"text-align":center
}

3.之后我们先获取到随机的块的标号值(通过数组来实现),然后根据这个值先获得坐标,再获得位置,获取位置函数之前已经定义过<a href="#first">(根据坐标获取位置函数)</a>,最后对其进行样式和数字的分别设置

//根据putIndex获得坐标的函数
var getCoordinate=function(putIndex){
  return {x:putIndex%option.block_size,y:parseInt(putIndex/block_size)}
}
var buildBlock=function(){
//得到索引数组,得到所有空块的索引
  var emptyBlock = getIndex();
//如果所有空块被填满返回错误
 if(emptyBlock.length==0) return false;
//生成随机空块
var putIndex;
//注意,随机函数,生成随机的块坐标,包括前面的不包括后面的
putIndex = emptyBlock[Math.floor(Math.random()*emptyBlock.length)];
//1.随机生成块
var block =Math.random()>0.5?option.blocks[0]:option.blocks[1];
//根据putIndex获取到块的坐标值
var coordinate = getCoordinate(putIndex);
//2.根据坐标获取位置
var position =getPosition(coordinate.x,coordinate.y);
//3.得到位置之后,又得到了块我们就可以渲染块了
//生成块
var blockDom = $("<div></div>");
//4.渲染块,三个参数分别是,默认字体样式,位置渲染,随机生成的块的样式
blockDom.css($.extend(option.style.block_font,{
  //这里把位置设置成块的中间位置
   "top":position.top+option.style.block_size/2,
   "left":position.left+option.style.block_size/2,
//这里把高宽设置为0,以便动画效果显示出来
   "width":0,
  "height":0
},block.style));
//5.利用动画效果显示块的样式,在配置项中设置timeSpeed为300ms
blockDom.animate({
   "top":position.top,
   "left":position.left,
   "width":option.style.block_size,
  "height":option.style.block_size
},timeSpeed,
//6.animate的第三个参数,用闭包来实现,数字块和样式的同步显示
(function(blockDom){
return function(){
   blockDom.text(block.value);
}
})(blockDom)
);
//7.在页面中加入该blockDom
$this.append(blockDom);

  return true;
}

4.最后,我们通过给这个函数加参数来进行级别的判断

var getIndex = function(x,y){
  return x+y*option.width;
}
//重载
var buildBlock=function(level,x,y){
//得到索引数组,得到所有空块的索引
  var emptyBlock = getIndex();
//如果所有空块被填满返回错误
 if(emptyBlock.length==0) return false;
//0.生成随机空块的位置
var putIndex;
//注意,随机函数,生成随机的块坐标,包括前面的不包括后面的
if(x!=undefined&&y!=undefined){putIndex=getIndex(x,y);}
else
putIndex = emptyBlock[Math.floor(Math.random()*emptyBlock.length)];
//1.随机生成块的数值
var block;
if(level!=undefined){block=option.blocks[level];}
else block =Math.random()>0.5?option.blocks[0]:option.blocks[1];
//根据putIndex获取到块的坐标值
var coordinate = getCoordinate(putIndex);
//2.根据坐标获取位置
var position =getPosition(coordinate.x,coordinate.y);
//3.得到位置之后,又得到 了块我们就可以渲染块了
//生成块
var blockDom = $("<div></div>");
//4.渲染块,三个参数分别是,默认字体样式,位置渲染,随机生成的块的样式
blockDom.css($.extend(option.style.block_font,{
    //
    "position":"absolute",
  //这里把位置设置成块的中间位置
   "top":position.top+option.style.block_size/2,
   "left":position.left+option.style.block_size/2,
//这里把高宽设置为0,以便动画效果显示出来
   "width":0,
  "height":0
},block.style));


$this.append(blockDom);
    //只有2,4,用于测试
    state[putIndex]=block;

//5.利用动画效果显示块的样式,在配置项中设置timeSpeed为300ms

blockDom.animate({
   "width":option.style.block_size,
  "height":option.style.block_size,
  "top":position.top,
   "left":position.left
},option.timeSpeed,
//6.animate的第三个参数,用闭包来实现,数字块和样式的同步显示
(function(blockDom){
return function(){
   blockDom.text(block.value);
}
})(blockDom)
);
$this.append(blockDom);
  return true;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 前些日子从@张鑫旭微博处得一份推荐(Front-end-tutorial),号称最全的资源教程-前端涉及的所有知识...
    谷子多阅读 4,169评论 0 44
  • 题记:春天已到,夏天还远吗?亲爱的girls,你们想拥有一双属于自己的大长腿吗?让自己在整个夏天成为路上行人的美丽...
    悦读时刻阅读 2,420评论 0 23
  • hey.ovk . . # 转折 # . . 前方一个红发霸道西装boy 回头对他女朋友邪魅一笑 笑得同在后方的我...
    ovk阅读 154评论 0 0
  • 桃花开了三两朵 粉红散漫在空中 蝶蜂笑了 翩翩夹翅又颦颦 相逢语噎两盈盈 春深执袖忍背驰 如邂逅时愣住 之后又回想...
    山屈生阅读 79评论 0 0