Html5游戏之2048

canvas版2048,PC端上下左右控制,并支持移动端滑动控制(发现canvas做这种小游戏真是方便啊)

首先用一个center标签显示Score,然后用一个canvas标签绘制游戏画面

<center id="score" style="font:bold 25px Arial,Microsoft Yahei"></center><br/>
<canvas id="canvas" width="500" height="500"></canvas>

然后设置canvas的样式

canvas{
    display: block;
    margin: 0 auto;
    border-radius: 10px;
    background-color: #bbada0;
}

设置后的canvas看起来像这样

然后进行地图的初始化以及一些数据结构定义

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
//初始化地图
var map = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
//不同数字的颜色信息
var num_color = {0:"#ccc0b3",2:"#eee4da",4:"#ede0c8",8:"#f2b179",16:"#f59563",32:"#f67c5f",64:"#ec6544",128:"#e44d29",256:"#edcf72",512:"#c8a145",1024:"#a8832b",2048:"#86aa9c"};
//不同数字的大小信息        
var num_size = {0:"60",2:"60",4:"60",8:"60",16:"60",32:"60",64:"60",128:"50",256:"50",512:"50",1024:"40",2048:"40"};
//不同数字的偏移量(为了将数字画在方块中心)        
var offsetx = {0:53,2:53,4:53,8:53,16:34,32:35,64:35,128:28,256:28,512:28,1024:24,2048:25};
//上下左右键的code对应的方向信息        
var keycom = {'38':[0,-1],'40':[0,1],'37':[-1,0],'39':[1,0]}
//space表示当前剩余的空格块数,score表示当前的分数
var space=16,score=0;

formap函数用来遍历地图中4×4的方格并执行操作

function formap(func){
for(var i=0;i<4;i++)
    for(var j=0;j<4;j++){
        func(i,j);
    }
}

produce函数用来在地图的空白处随机生成一个方块,并重绘地图,这里“~~”操作是为了取整

function produce(){
    var cot = ~~(Math.random()*space);
    var k = 0;
    formap(function(i,j){
        if(map[i][j]==0){
            if(cot==k){
                map[i][j]=2;
                    draw();
            }
            k+=1;
         }
    });
    space-=1;
}

draw函数用来绘制地图,包括每个小方格的绘制和Score的更新

function draw(){
    formap(function(i,j){
        var num = map[i][j];
        ctx.fillStyle = num_color[num];
        ctx.fillRect(j*120+20,i*120+20,100,100);
        if(num!=0){
             ctx.font = "bold "+num_size[num]+"px Arial,Microsoft Yahei";
             ctx.fillStyle = (num<=4)?"#776e65":"white";
             ctx.fillText(String(map[i][j]),j*120+offsetx[num],i*120+70+num_size[num]/3);
        }
    });
    document.getElementById("score").innerText="Score: "+String(score);
}

move函数用来处理方块的移动

function move(dir){
    //用来调整不同方向的遍历方式
    function modify(x,y){
        tx=x,ty=y;
        if(dir[0]==0)tx=[ty,ty=tx][0];
        if(dir[1]>0)tx=3-tx;
        if(dir[0]>0)ty=3-ty;
        return [tx,ty];
    }
    //根据移动的方向,将地图中对应行/列中的数字一个个压入栈中,如果第一次遇到栈顶数字和待入栈数字相等,则栈顶数字乘2,最后用栈中数字更新地图中的对应行/列
    for(var i=0;i<4;i++){
        var tmp = Array();
        var isadd = false;
        for(var j=0;j<4;j++){
            var ti=modify(i,j)[0],tj=modify(i,j)[1];
            if(map[ti][tj]!=0){
                if(!isadd&&map[ti][tj]==tmp[tmp.length-1])score+=(tmp[tmp.length-1]*=2),isadd=true,space+=1;
                else tmp.push(map[ti][tj]);
            }
        }
        for(var j=0;j<4;j++){
            var ti=modify(i,j)[0],tj=modify(i,j)[1];
            map[ti][tj] = isNaN(tmp[j])?0:tmp[j];
        }
    }
    produce();
    if(space==0)alert("game over");
    draw();
}

随机生成两个方块,开始游戏

produce();produce();

监听键盘的上下左右事件,并调用move方法

document.onkeydown=function(e){
    dir = keycom[(e?e:event).keyCode];
    move(dir);
};

监听移动端屏幕的touch事件,判断滑动方向,并调用move方法

var sx,sy,dx,dy,ex,ey;
canvas.ontouchstart=function(event){
    var touch = event.touches[0];
    sx=touch.clientX,sy=touch.clientY;
}
canvas.ontouchmove=function(event){
    var touch = event.touches[0];
    ex=touch.clientX,ey=touch.clientY;
    dx=ex-sx,dy=ey-sy;
    //禁止默认的滑动事件
    event.preventDefault();
}
canvas.ontouchend=function(event){
    //根据横纵坐标位移判断滑动方向
    if(dy<-50&&Math.abs(dy/dx)>2)move([0,-1]);
    if(dy>50&&Math.abs(dy/dx)>2)move([0,1]);
    if(dx<-50&&Math.abs(dx/dy)>2)move([-1,0]);
    if(dx>50&&Math.abs(dx/dy)>2)move([1,0]);
}

像这样,一个简单的web版2048游戏就做好啦~~

完整代码已上传到我的github

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

推荐阅读更多精彩内容