jqueryWeb前端之路技术干货

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

2017-02-17  本文已影响414人  向布谷鸟说早安

如果你对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;
}
上一篇下一篇

猜你喜欢

热点阅读