一、canvas簡介
canvas是HTML5提供的一種新標簽,雙標簽;
HTML5 canvas標簽元素用于圖形的繪制,通過腳本 (通常是JavaScript)來完成;
canvas標簽只是圖形容器,必須使用腳本來繪制圖形;
Canvas是一個矩形區域的畫布,可以用JavaScript在上面繪畫;
二、案例目標
我們今天的目標是使用HTML5畫布技術制作一款拼圖小游戲,要求將圖像劃分為3*3的9塊方塊并打亂排序,用戶可以移動方塊拼成完整圖片。
效果如下所示:
三、程序流程
3.1 HTML靜態頁面布局
-
"container"> - --頁面標題-->
-
HTML5畫布綜合項目之拼圖游戲
- --水平線-->
-
- --游戲內容-->
- --游戲時間-->
-
"timeBox" > -
共計時間:
"time" >00:00:00 -
- --游戲畫布-->
-
"myCanvas" width="300"height="300"style="border:1pxsolid"> - 對不起,您的瀏覽器不支持HTML5畫布API。
- --游戲按鈕-->
-
-
"restartGame()" > - 重新開始
-
-
效果如下所示:
我們可以看到頁面的大致結構是已經顯現出來了,就是骨架已經搭建好了,現在我們要使用css強化樣式;
3.2 CSS打造頁面樣式
整體背景設置
- body{
- background-color:silver;/*設置頁面背景顏色為銀色*/
- }
游戲界面樣式設置
- #container{
- background-color:white;
- width:600px;
- margin:auto;
- padding:20px;
- text-align:center;
- box-shadow:10px10px15pxblack;
- }
游戲時間面板樣式設置
- #timeBox{
- margin:10px0;
- font-size:18px;
- }
游戲按鈕樣式設置
- button{
- width:200px;
- height:50px;
- margin:10px0;
- border:0;
- outline:none;
- font-size:25px;
- font-weight:bold;
- color:white;
- background-color:lightcoral;
- }
鼠標懸浮時的按鈕樣式設置
- button:hover{
- background-color:coral;
- }
設置好界面整體樣式之后我們得到完整的界面,如下所示:
可以看到整體的靜態界面已經搭建出來了
3.3 js構建交互效果
3.3.1 對象的獲取以及圖片的設置
目標對象的獲取
- varc=document.getElementById('myCanvas');//獲取畫布對象
- varctx=c.getContext('2d');//獲取2D的context對象
聲明拼圖的圖片素材來源
- varimg=newImage();
- img.src="image/pintu.jpg";
- img.onload=function(){//當圖片加載完畢時
- generateNum();//打亂拼圖的位置
- drawCanvas();//在畫布上繪制拼圖
- }
3.3.2 初始化拼圖
需要將素材圖片分割成3行3列的9個小方塊,并打亂順序放置在畫布上;
為了在游戲過程中便于查找當前的區域該顯示圖片中的哪一個方塊,首先為原圖片上的9個小方塊區域進行編號;
定義初始方塊位置
- varnum=[[00,01,02],[10,11,12],[20,21,22]];
打亂拼圖的位置
- functiongenerateNum(){//循環50次進行拼圖打亂
- for(vari=0;i<50;i++){
- //隨機抽取其中一個數據
- vari1=Math.round(Math.random()*2);
- varj1=Math.round(Math.random()*2);
- //再隨機抽取其中一個數據
- vari2=Math.round(Math.random()*2);
- varj2=Math.round(Math.random()*2);
- //對調它們的位置
- vartemp=num[i1][j1];
- num[i1][j1]=num[i2][j2];
- num[i2][j2]=temp;
- }
- }
繪制拼圖
自定義名稱的drawCanvas()方法用于在畫布上繪制亂序后的圖片;
- functiondrawCanvas(){
- //清空畫布
- ctx.clearRect(0,0,300,300);
- //使用雙重for循環繪制3x3的拼圖
- for(vari=0;i<3;i++){
- for(varj=0;j<3;j++){
- if(num[i][j]!=22){
- //獲取數值的十位數,即第幾行
- varrow=parseInt(num[i][j]/10);
- //獲取數組的個位數,即第幾列
- varcol=num[i][j]%10;
- //在畫布的相關位置上繪圖
- ctx.drawImage(img,col*w,row*w,w,w,j*w,i*w,w,w);//w:300/3=100(小圖寬度)
- }
- }
- }
- }
如下所示:
3.3.3 事件綁定
監聽鼠標監聽事件
- c.onmousedown=function(e){
- varbound=c.getBoundingClientRect();//獲取畫布邊界
- varx=e.pageX-bound.left;//獲取鼠標在畫布上的坐標位置(x,y)
- vary=e.pageY-bound.top;
- varrow=parseInt(y/w);//將x和y換算成幾行幾列
- varcol=parseInt(x/w);
- if(num[row][col]!=22){//如果當前點擊的不是空白區域
- detectBox(row,col);//移動點擊的方塊
- drawCanvas();//重新繪制畫布
- varisWin=checkWin();//檢查游戲是否成功
- if(isWin){//如果游戲成功
- clearInterval(timer);//清除計時器
- ctx.drawImage(img,0,0);//繪制完整圖片
- ctx.font="bold68pxserif";//設置字體為加粗、68號字,serif
- ctx.fillStyle="red";//設置填充色為紅色
- ctx.fillText("游戲成功!",20,150);//顯示提示語句
- }
- }
- }
點擊方塊移動
- functiondetectBox(i,j){
- //如果點擊的方塊不在最上面一行
- if(i>0){
- //檢測空白區域是否在當前方塊的正上方
- if(num[i-1][j]==22){
- //交換空白區域與當前方塊的位置
- num[i-1][j]=num[i][j];
- num[i][j]=22;
- return;
- }
- }
- //如果點擊的方塊不在最下面一行
- if(i<2){
- //檢測空白區域是否在當前方塊的正下方
- if(num[i+1][j]==22){
- //交換空白區域與當前方塊的位置
- num[i+1][j]=num[i][j];
- num[i][j]=22;
- return;
- }
- }
- //如果點擊的方塊不在最左邊一列
- if(j>0){
- //檢測空白區域是否在當前方塊的左邊
- if(num[i][j-1]==22){
- //交換空白區域與當前方塊的位置
- num[i][j-1]=num[i][j];
- num[i][j]=22;
- return;
- }
- }
- //如果點擊的方塊不在最右邊一列
- if(j<2){
- //檢測空白區域是否在當前方塊的右邊
- if(num[i][j+1]==22){
- //交換空白區域與當前方塊的位置
- num[i][j+1]=num[i][j];
- num[i][j]=22;
- return;
- }
- }
- }
3.3.4 游戲計時
自定義函數getCurrentTime()用于進行游戲計時;
- functiongetCurrentTime(){
- s=parseInt(s);//將時分秒轉換為整數以便進行自增或賦值
- m=parseInt(m);
- h=parseInt(h);
- s++;//每秒變量s先自增1
- if(s==60){
- s=0;//如果秒已經達到60,則歸0
- m++;//分鐘自增1
- }
- if(m==60){
- m=0;//如果分鐘也達到60,則歸0
- h++;//小時自增1
- }
- //修改時分秒的顯示效果,使其保持兩位數
- if(s<10)
- s="0"+s;
- if(m<10)
- m="0"+m;
- if(h<10)
- h="0"+h;
- time.innerHTML=h+":"+m+":"+s;//將當前計時的時間顯示在頁面上
- }
在JavaScript中使用setInterval()方法每隔1秒鐘調用getCurrentTime()方法一次,以實現更新效果;
- vartimer=setInterval("getCurrentTime()",1000)
3.3.5 游戲成功與重新開始
游戲成功判定與顯示效果的實現
自定義函數checkWin()用于進行游戲成功判斷;
- functionrestartGame(){
- clearInterval(timer);//清除計時器
- s=0;//時間清零
- m=0;
- h=0;
- getCurrentTime();//重新顯示時間
- timer=setInterval("getCurrentTime()",1000);
- generateNum();//重新打亂拼圖順序
- drawCanvas();//繪制拼圖
- }
如果成功則使用clearInterval()方法清除計時器。然后在畫布上繪制完整圖片,并使用fillText()方法繪制出“游戲成功”的文字圖樣;
- if(isWin){//如果游戲成功
- clearInterval(timer);//清除計時器
- ctx.drawImage(img,0,0);//繪制完整圖片
- ctx.font="bold68pxserif";//設置字體為加粗、68號字,serif
- ctx.fillStyle="red";//設置填充色為紅色
- ctx.fillText("游戲成功!",20,150);//顯示提示語句
- }
3.4 最終效果演示
靜態效果如上所示,至于游戲成功這里伙計們可以自行操作;
四、總結
本次案例我們使用HTML5的新特性canvas畫布標簽打造了簡單的9宮格拼圖游戲,總體來說沒有特別的復雜,主要是圖片的分割方塊移動事件的綁定,以及重新游戲的初始化操作,明確了游戲邏輯之后其實代碼的編寫其實不難。感興趣的小伙伴可以去嘗試一下。
原文鏈接:https://mp.weixin.qq.com/s/lK2iUsmKx5bi8k9EtnaYsQ