上一篇我們介紹了關於Canvas的基礎知識,用Canvas繪製各種圖形和圖片,在上一篇的基礎上我們來做一個基於HTML5的坦克大戰遊戲,下面我們開始吧
一、用Canvas畫出我們的坦克車
我們設計的坦克結構如下圖所示,如果有的朋友有更好的設計,希望分享並交流一下。
如上圖所示,我們的坦克基本上是由三個矩形和一個圓形一個線段組成,每個部件的尺寸進行了標記,單位為px,下面我們用上一篇中講到的知識來畫出我們的坦克,注意:我們在畫坦克的時候應該選擇一個參考點,這裡我們選擇的是坦克的左上角,如圖所示。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body> <h1>html5-坦克大战</h1> <!--坦克大战的战场--> <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas> <script type="text/javascript"> //得到画布 var canvas1 = document.getElementById("tankMap"); //定义一个位置变量 var heroX = 80; var heroY = 80; //得到绘图上下文 var cxt = canvas1.getContext("2d"); //设置颜色 cxt.fillStyle="#BA9658"; //左边的矩形 cxt.fillRect(heroX,heroY,5,30); //右边的矩形 cxt.fillRect(heroX+17,heroY,5,30); //画中间的矩形 cxt.fillRect(heroX+6,heroY+5,10,20); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(heroX+11,heroY+15,5,0,360,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(heroX+11,heroY+15); cxt.lineTo(heroX+11,heroY); cxt.closePath(); cxt.stroke(); </script> </body> </html>
二、怎麼讓坦克動起來?
在研究怎麼讓坦克動起來之前,我們先來研究一下怎麼讓一個小球透過鍵盤操作使其動起來。
首先我們為
標籤新增一個監聽函數<body onkeydown="test()">
監聽函數
//现在按键盘上ASDW移动小球 //说明:当我们按下一个键,实际上触发了一个onkeydown事件 function test(){ var code = event.keyCode; //键盘上字幕的ASCII码 switch(code){ case 87: ballY--; break; case 68: ballX++; break; case 83: ballY++; break; case 65: ballX--; break; } //重新绘制 drawBall(); }
我們可以在外部定義兩個全域的變數分別表示x軸和y軸的座標,然後透過改變ballX和ballY的值來改變小球的位置,我們用鍵盤的WDSA鍵來控制,這樣出來的效果非常奇怪,如下圖:
我們在繪製的時候沒有將以前位置的小球擦除掉,在每次重新繪製前應該先擦除一下,下面將全部程式碼貼出來:
<body onkeydown="test()">小球上下左右移动
三、讓我們的坦克動起來
我們的坦克如果只是朝一個方向移動的話就非常容易了,只要將上面代碼中的畫小球改成畫坦克就OK了,在讓坦克移動之前我們首先應該考慮的是怎麼讓坦克繞著自己的中心朝各個方向轉動的問題。好的,再將上面的圖貼出來分析一下。
詳細的計算過程我就不囉嗦了,想必大家的數學都很好,按照上圖的比例計算好各個組件的坐標和位置,旋轉後坦克畫法如下:
//设置颜色 cxt.fillStyle="#BA9658"; //上边的矩形 cxt.fillRect(tank.x-4,tank.y+4,30,5); //下边的矩形 cxt.fillRect(tank.x-4,tank.y+17+4,30,5); //画中间的矩形 cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+15-4,tank.y+11+4,5,0,360,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+15-4,tank.y+11+4); if(tank.direct==1){ //只是炮筒的方向不同 cxt.lineTo(tank.x+30-4,tank.y+11+4); }else{ cxt.lineTo(tank.x-4,tank.y+11+4); } cxt.closePath(); cxt.stroke();
好了現在我們發現坦克車朝向左邊和右邊僅僅只有砲筒的方向不同,同理朝向上邊和下邊也僅僅只有砲筒的方向不同,這時候我們可以將四個方向分為兩種情況,再在各個小情況中做處理。同時以OO的思想將程式碼進行了封裝,程式碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body onkeydown="getCommand();"> <h1>html5-坦克大战</h1> <!--坦克大战的战场--> <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas> <script type="text/javascript"> //定义一个Hero类(后面还要改进) //x表示坦克的横坐标 //y表示纵坐标 //direct表示方向 function Hero(x,y,direct){ this.x=x; this.y=y; this.speed=1; this.direct=direct; //上移 this.moveUp=function(){ this.y-=this.speed; this.direct=0; } //右移 this.moveRight=function(){ this.x+=this.speed; this.direct=1; } //下移 this.moveDown=function(){ this.y+=this.speed; this.direct=2; } //左移 this.moveLeft=function(){ this.x-=this.speed; this.direct=3; } } //得到画布 var canvas1 = document.getElementById("tankMap"); //得到绘图上下文 var cxt = canvas1.getContext("2d"); //我的tank //规定0向上、1向右、2向下、3向左 var hero = new Hero(40,40,0); drawTank(hero); //绘制坦克 function drawTank(tank){ //考虑方向 switch(tank.direct){ case 0: //向上 case 2: //向下 //设置颜色 cxt.fillStyle="#BA9658"; //左边的矩形 cxt.fillRect(tank.x,tank.y,5,30); //右边的矩形 cxt.fillRect(tank.x+17,tank.y,5,30); //画中间的矩形 cxt.fillRect(tank.x+6,tank.y+5,10,20); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+11,tank.y+15,5,0,360,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+11,tank.y+15); if(tank.direct==0){ //只是炮筒的方向不同 cxt.lineTo(tank.x+11,tank.y); }else{ cxt.lineTo(tank.x+11,tank.y+30); } cxt.closePath(); cxt.stroke(); break; case 1: case 3: //设置颜色 cxt.fillStyle="#BA9658"; //上边的矩形 cxt.fillRect(tank.x-4,tank.y+4,30,5); //下边的矩形 cxt.fillRect(tank.x-4,tank.y+17+4,30,5); //画中间的矩形 cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+15-4,tank.y+11+4,5,0,360,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+15-4,tank.y+11+4); if(tank.direct==1){ //只是炮筒的方向不同 cxt.lineTo(tank.x+30-4,tank.y+11+4); }else{ cxt.lineTo(tank.x-4,tank.y+11+4); } cxt.closePath(); cxt.stroke(); break; } } //接收用户按键的函数 function getCommand(){ var code = event.keyCode; //键盘上字幕的ASCII码 switch(code){ case 87: hero.moveUp(); break; case 68: hero.moveRight(); break; case 83: hero.moveDown(); break; case 65: hero.moveLeft(); break; } //把画布清理 cxt.clearRect(0,0,400,300); //重新绘制 drawTank(hero); } </script> </body> </html>
以上就是 小強的HTML5行動開發之路(7)-坦克大戰遊戲1的內容,更多相關內容請關注 小強的HTML5行動開發之路(7)-坦克大戰遊戲1的內容,更多相關內容請關注PHP中文網(www.php.cn)!