如果你对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;
}