前言

Canvas API(画布)是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容。
HTML5的Canvas画布功能真的很强大,与之对应的还有Svg,都是HTML5的核心之一。想了解更多,来看看Canvas和Svg的对比

canvas小游戏-五子棋

HTML主体

<!--难度级别,可以不要,默认简单--> <div class="choose"> <img src="images/bg.jpg" alt="" width="100%"> <div class="choose-lv"> <div class="levl">简单</div> <div class="levl">中级</div> <div class="levl">高级</div> </div> </div> <div class="choose_shade"></div> <!--棋盘上方的提示等,可以不要--> <div class="player"> <div class="baiqi"><img src="images/baiqi.png" alt=""></div> <div class="tips" id="tips">黑子先行</div> <div class="heiqi"><img src="images/heiqi.png" alt=""></div> <div class="clear"></div> </div> <!--这里才是重点,棋盘和棋子--> <div class="checkerboard"> <canvas id="chess" width="450px" height="450px"></canvas> <canvas id="chess_board" width="450px" height="450px"></canvas> <canvas id="chess_pointer" width="450px" height="450px"></canvas> </div>

JS

注释很详细,不做过多介绍了,注意赢棋算法,和难易程度算法

var num = 0;//连胜次数 var gameMode = false; // 模式,默认人机 var complexity = 1; // 人机时难度级别,默认简单 layer.confirm('请选择模式?', { btn: ['人机', '人人'], closeBtn: 0, }, function(index, layero){ gameMode=false; $('.choose').animate({ opacity:1 },800) $('.choose_shade').animate({ opacity:0.6 },800) layer.close(index); }, function(index){ gameMode=true; $('.choose_shade').animate({ opacity:0, 'z-index':-1 },800) $('.choose').animate({ opacity:0, 'z-index':-1 },800) }); $('.levl').click(function(){ var index=$(this).index() + 1; complexity=index; $('.choose').animate({ opacity:0, 'z-index':-1 }) $('.choose_shade').animate({ opacity:0, 'z-index':-1 }) }) var canWidth = Math.min( 500 , $(window).width()-30); var canHeight=canWidth; var chess=document.getElementById('chess'); var context=chess.getContext('2d'); var chess_board=document.getElementById('chess_board'); var context2=chess_board.getContext('2d'); var chess_pointer=document.getElementById('chess_pointer'); var context3=chess_pointer.getContext('2d'); var pointerEnd=[]; // 根据屏幕大小绘制棋盘 $('#chess_pointer').css({ width:canWidth, height:canHeight }) $('#chess').css({ width:canWidth, height:canHeight }) $('#chess_board').css({ width:canWidth, height:canHeight }) $('.checkerboard').css({ width:canWidth, height:canHeight }) var utilW=canWidth/15; var utilH=utilW; var me; var chessBoard; var over; //赢法数组 var wins=[]; //赢法统计数组 var myWin=[]; var computerWin=[]; for(var i=0;i<15;i++){ wins[i]=[]; for(var j=0;j<15;j++){ wins[i][j]=[]; } } //赢法种类索引 var count=0; //赢法种类数组 // 横线赢法 for(var i=0;i<15;i++){ for(var j=0;j<11;j++){ for(var k=0;k<5;k++){ wins[i][j+k][count]=true; } count++; } } // 竖线赢法 for(var i=0;i<15;i++){ for(var j=0;j<11;j++){ for(var k=0;k<5;k++){ wins[j+k][i][count]=true; } count++; } } // 斜线赢法 for(var i=0;i<11;i++){ for(var j=0;j<11;j++){ for(var k=0;k<5;k++){ wins[i+k][j+k][count]=true; } count++; } } // 反斜线赢法 for(var i=0;i<11;i++){ for(var j=14;j>3;j--){ for(var k=0;k<5;k++){ wins[i+k][j-k][count]=true; } count++; } } var init=function(){ context.clearRect(0,0,450,450); context3.clearRect(0,0,450,450); me=true; chessBoard=[]; over=false; for(var i=0;i<15;i++){ chessBoard[i]=[]; for(var j=0;j<15;j++){ chessBoard[i][j]=0; } } for(var i=0;i<count;i++){ myWin[i]=0; computerWin[i]=0; } } init() context2.strokeStyle="#dfdfdf"; var img=new Image(); img.src="images/logo.png"; img.onload=function(){ drawChessBoard(); } var drawChessBoard=function(){ for(var i=0;i<15;i++){ context2.moveTo(15+i*30,15); context2.lineTo(15+i*30,435); context2.stroke(); context2.moveTo(15,15+i*30); context2.lineTo(435,15+i*30); context2.stroke(); } } var oneStep=function(i,j,me){ context3.clearRect(0,0,450,450); context.beginPath(); context.arc(15+i*30,15+j*30,13,0, 2*Math.PI); context.closePath(); var gradient=context.createRadialGradient(15+i*30+2,15+j*30-2,13,15+i*30+2,15+j*30-2,0); if(me){ gradient.addColorStop(0,"#0a0a0a"); gradient.addColorStop(1,"#636766"); }else{ gradient.addColorStop(0,"#C7C7C7"); gradient.addColorStop(1,"#f9f9f9"); } context.fillStyle=gradient; context.fill(); context3.beginPath(); context3.arc(15+i*30,15+j*30,15,0, 2*Math.PI); context3.closePath(); context3.fillStyle="#FF3366"; context3.fill(); } chess.onclick=function(e){ e.preventDefault(); var x=e.offsetX; var y=e.offsetY; moveLater(x,y); } var moveLater=function(x,y){ if(over){ return; } var i=Math.floor(x/utilW); var j=Math.floor(y/utilW); if(chessBoard[i][j]==0){ oneStep(i,j,me); if(gameMode){ if (me) { chessBoard[i][j] = 1; for (var k = 0; k < count; k++) { if (wins[i][j][k]) { myWin[k]++; computerWin[k] = 6; if (myWin[k] == 5) { over = true; layer.open({ title: '黑子赢了', content: '亲,再来一局试试!', btn: ['嗯', '不要'], yes: function(index){ init(); layer.close(index); } }); } } } } else { chessBoard[i][j] = 2; for (var k = 0; k < count; k++) { if (wins[i][j][k]) { computerWin[k]++; myWin[k] = 6; if (computerWin[k] == 5) { over = true; layer.open({ title: '白子赢了', content: '亲,再来一局试试!', btn: ['嗯', '不要'], yes: function(index){ // location.reload(); init(); layer.close(index); } }); } } } } me = !me; }else{ chessBoard[i][j]=1; for(var k=0;k<count;k++){ if(wins[i][j][k]){ myWin[k]++; computerWin[k]=6; if(myWin[k]==5){ over=true; $('.black').css({'z-index':2}) layer.open({ title: '你赢了', content: '亲,人家是你的了!', btn: ['要', '不要'], yes: function(index){ // location.reload(); num++; if(num>=3){ $('#tips').html('常胜将军,已连胜'+num+'局'); }else{ $('#tips').html('你已连胜'+num+'局'); } init(); layer.close(index); } }); } } } if(!over){ $('#tips').html('电脑走棋,走着瞧'); me=!me; computerAI(); } } } } var computerAI=function(){ var myScore=[]; var computerScore=[]; var max=0; var u=0,v=0; for(var i=0;i<15;i++){ myScore[i]=[]; computerScore[i]=[]; for(var j=0;j<15;j++){ myScore[i][j]=0; computerScore[i][j]=0; } } for(var i=0;i<15;i++){ for(var j=0;j<15;j++){ if(chessBoard[i][j]==0){ for(var k=0;k<count;k++){ if(wins[i][j][k]){ if(complexity==1){ if(myWin[k]==1){ myScore[i][j]+=200; }else if(myWin[k]==2){ myScore[i][j]+=400; }else if(myWin[k]==3){ myScore[i][j]+=2000; }else if(myWin[k]==4){ myScore[i][j]+=10000; } if(computerWin[k]==1){ computerScore[i][j]+=100; }else if(computerWin[k]==2){ computerScore[i][j]+=300; }else if(computerWin[k]==3){ computerScore[i][j]+=600; }else if(computerWin[k]==4){ computerScore[i][j]+=14000; } }else if(complexity==2){ if(myWin[k]==1){ myScore[i][j]+=200; }else if(myWin[k]==2){ myScore[i][j]+=400; }else if(myWin[k]==3){ myScore[i][j]+=2000; }else if(myWin[k]==4){ myScore[i][j]+=10000; } if(computerWin[k]==1){ computerScore[i][j]+=300; }else if(computerWin[k]==2){ computerScore[i][j]+=500; }else if(computerWin[k]==3){ computerScore[i][j]+=2100; }else if(computerWin[k]==4){ computerScore[i][j]+=15000; } }else if(complexity==3){ if(myWin[k]==1){ myScore[i][j]+=200; }else if(myWin[k]==2){ myScore[i][j]+=400; }else if(myWin[k]==3){ myScore[i][j]+=2000; }else if(myWin[k]==4){ myScore[i][j]+=10000; } if(computerWin[k]==1){ computerScore[i][j]+=210; }else if(computerWin[k]==2){ computerScore[i][j]+=850; }else if(computerWin[k]==3){ computerScore[i][j]+=3000; }else if(computerWin[k]==4){ computerScore[i][j]+=80000; } } } } if(myScore[i][j]>max){ max=myScore[i][j]; u=i; v=j; }else if(myScore[i][j]==max){ if(computerScore[i][j]>computerScore[u][v]){ u=i; v=j; } } if(computerScore[i][j]>max){ max=computerScore[i][j]; u=i; v=j; }else if(computerScore[i][j]==max){ if(myScore[i][j]>myScore[u][v]){ u=i; v=j; } } } } } oneStep(u,v,false); chessBoard[u][v]=2; for(var k=0;k<count;k++){ if(wins[u][v][k]){ computerWin[k]++; myWin[k]=6; if(computerWin[k]==5){ over=true; layer.open({ title: '你输了', content: '不要放弃,再来一局吧!', btn: ['嗯', '不要'], yes: function(index){ // location.reload(); num=0; init(); layer.close(index); } }); } } } if(!over){ me=!me; if(num==0){ $('#tips').html('该你走棋了,我看好你'); } } }

CSS

css都是可有可无的,不影响功能,都是为了美化页面

body,html { margin: 0; padding: 0; position: relative; width: 100%; height: 100%; } .chess-content { padding-top: 48px; } canvas { display: block; margin: 0px auto; box-shadow: -2px -2px 2px #efefef,5px 5px 5px #b9b9b9; } h3 { margin: 0; } .clear { clear: both; } .checkerboard { margin: 0 auto; } #chess { position: absolute; z-index: 2; } #chess_board { position: absolute; z-index: 1; } #chess_pointer { position: absolute; z-index: 0; } .player { max-width: 500px; margin: 0 auto; } .player .baiqi { float: left; } .player .baiqi { width: 15%; } .player .tips { float: left; width: 70%; text-align: center; font-size: 18px; } .player .heiqi { width: 15%; float: right; } .player div img { width: 100%; } .choose { position: absolute; z-index: 10; width: 80%; max-width: 500px; left: 50%; border: 1px solid #dfdfdf; border-radius: 5px; opacity: 0; top: 50%; transform: translateY(-50%); overflow: hidden; } .choose img { width: 100%; } .choose_shade { width: 100%; height: 100%; position: absolute; z-index: 9; background: #000; opacity: 0.6; margin: 0; } .choose-lv { position: absolute; top: 28%; width: 100%; } .choose-lv div { margin: 19px 0px 10px 52%; width: 40%; text-align: center; border-radius: 5px; border: 1px solid #F2F2F2; color: #fff; text-shadow: 10px 7px 17px; font-weight: bold; line-height: 35px; z-index: 1; position: relative; background: rgba(0, 0, 0, 0.18); cursor: pointer; } .black { float: right; position: absolute; z-index: 1; width: 40%; max-width: 400px; bottom: 0; } .black img { width: 100%; } .b_img3,.b_img4 { right: 0; } .tips { line-height: 75px; }

演示程序:演示代码
下载源码:下载源码

公告

以后每月5、15、25号更新原创文章,内容不限,喜欢小编的可以点击关注,也可在下方评论留言,你喜欢什么内容,小编根据大家喜欢的内容尝试更新