H5 canvas控制坦克移動


  接着上一篇( http://www.cnblogs.com/zhouhuan/p/H5_tankgame.html),這一篇研究一下怎么響應玩家的操作讓坦克進行相應的移動。
 
   1. 了解keydown事件
  keydown這一鍵盤事件的觸發條件為按下鍵盤上的任意鍵,如果按住不放,則會重發觸發。
  示例:
window.onkeydown = function(){
    alert("Merry Christmas!");
};
  此時載入頁面之后,無論按下哪個鍵,都會彈出“Merry Christmas!”的彈窗。
 
   2. 了解鍵碼和字符編碼
 
   ① 鍵碼
  在發生keydown和keyup事件時,event對象的keyCode(鍵碼)屬性會包含一個代碼,與鍵盤上一個特定的鍵對應。對於數字字母字符集,keyCode屬性的值與ASCII碼中對應小寫字母或數字的編碼相同。字母中的大小寫不影響。
window.onkeydown = function(eve){
    alert(eve.keyCode);
};
  此時按鍵盤上的任意鍵,便可得到所按鍵對應的keyCode
  
   ② 字符編碼
  發生keypress事件時,event對象的charCode屬性會包含一個值,這個值就是按下的那個鍵所代表字符的ASCII編碼,並且,同一個字母的大小寫對應的字符編碼也是不一樣的。
  要注意的是,keypress事件只有在按下字符鍵時才會觸發,並不是所有的按鍵,像Ctrl, Alt之類的就不會觸發該事件。
 
   3. 熱身環節
 
   ① 獲取玩家的指令
  我們先看看怎么獲取到玩家的操控指令,這里我們寫一段代碼:
window.onkeydown = function(eve){
    alert("所按鍵對應的鍵碼是: " + eve.keyCode);
};    
  大家運行一下就可以知道鍵盤上每一個按鍵所對應的鍵碼是多少了,然后取自己需要的按鍵繼續編寫程序。這里需要的是方向鍵的上下左右,當然這個在網上可以查到,也非常方便。
  我們運行了之后會發現,上下左右對應的鍵碼分別是38, 40, 37, 39。考慮到有些玩家習慣於使用W A S D來操作,那我們把這幾個鍵也做進去,這幾個鍵對應的鍵碼分別是87, 65, 83, 68。
  OK,知道了上面這些東西之后我們就可以寫出下面這段代碼了:
window.onkeydown = function(eve){                                                
    if(eve.keyCode == 38 || eve.keyCode == 87){
        alert("上");
    }else if(eve.keyCode == 40 || eve.keyCode == 83){
        alert("下");
    }else if(eve.keyCode == 37 || eve.keyCode == 65){
        alert("左");
    }else if(eve.keyCode == 39 || eve.keyCode == 68){
        alert("右");
    }
};
  此時,根據玩家的操作便能彈出相應方向的文字。
  鑒於上面if語句的條件分支數量略多,我們最好用switch語句改寫一下上面的代碼,這樣可以提高性能,如下:
window.onkeydown = function(eve){                                                
    switch(eve.keyCode){
        case 38:
        case 87:
            alert("上");
            break;
        case 40:
        case 83:
            alert("下");
            break;
        case 37:
        case 65:
            alert("左");
            break;
        case 39:
        case 68:
            alert("右");
    }
};

 

   ② 封裝畫坦克的函數
  前面我們寫的畫坦克的代碼其實是面向過程的,我們將它拿過來改巴改巴做以封裝:
function drawTank(x,y){
    var myCanvas = document.getElementById('floor');
    var cxt = myCanvas.getContext('2d');
    cxt.fillStyle = "#542174";
    cxt.fillRect(x,y,20,65);                
    cxt.fillRect(x+70,y,20,65);                
    cxt.fillRect(x+23,y+10,44,50);                
    cxt.fillStyle = "#FCB827";
    cxt.beginPath();
    cxt.arc(x+45,y+35,16,0,2*Math.PI,false);        
    cxt.closePath();
    cxt.fill();
    cxt.strokeStyle = "#FCB827";
    cxt.lineWidth = "8.0";
    cxt.moveTo(x+45,y+35);                        
    cxt.lineTo(x+45,y-25);                        
    cxt.stroke();
}
  這個函數調用的時候傳兩個參數(x, y),分別代表坦克左上角的X坐標,Y坐標。
  封裝好之后,在任何地方只要一調用,便可以造出一個坦克了:
drawTank(150,200);        //以(150,200)的點為坦克的左上角(左邊履帶的左上角)造一個坦克
 
   ③ 了解clearRect()方法
  有一個前面遺漏掉的知識點clearRect()方法,這個方法是做游戲的關鍵,用來清空指定矩形內的所有像素,傳四個參數(x, y, width, height),前兩個參數表示要清除的矩形的左上角坐標,后兩個參數表示要清除的矩形的寬高。
  比如我們先畫一個矩形:
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.fillStyle = "orange";
cxt.fillRect(50,50,300,80);

得到:

  我們再加上下面這句代碼運行一下:
cxt.clearRect(0,0,800,500);
  此時會發現整個畫布又空空如也了,因為我們把整個畫布的像素都清除掉了。
 
   4. 熱身完畢,正式開始
  前面熱身熱了這么久,相信大家已經可以寫出一個根據玩家的操作移動的坦克了。
  我們盡量以面向對象的思想來寫每一個過程,代碼如下:
//封裝一個獲取繪圖環境的函數
function getCxt(){
    var myCanvas = document.getElementById('floor'),
       myContext = myCanvas.getContext('2d');
    return myContext;
}

//封裝一個畫坦克的函數,傳兩個參數x,y,分別代表左上角的橫縱坐標
function drawTank(x,y){
    var cxt = getCxt();
    cxt.fillStyle = "#542174";
    cxt.fillRect(x,y,20,65);                
    cxt.fillRect(x+70,y,20,65);                
    cxt.fillRect(x+23,y+10,44,50);                
    cxt.fillStyle = "#FCB827";
    cxt.beginPath();
    cxt.arc(x+45,y+35,16,0,2*Math.PI,false);        
    cxt.closePath();
    cxt.fill();
    cxt.strokeStyle = "#FCB827";
    cxt.lineWidth = "8.0";
    cxt.moveTo(x+45,y+35);                        
    cxt.lineTo(x+45,y-25);                        
    cxt.stroke();
}

//初始化一個對象myTank,用來存儲一些屬性和方法
var myTank = {};
myTank.x = 350;
myTank.y = 400;
myTank.step = 3;        //設置步長,步長越大那么坦克運動的速度越快

//先畫一個坦克出來
drawTank(myTank.x,myTank.y);

//封裝一個更新戰場的函數
function updateFloor(){
    var cxt = getCxt();
    cxt.clearRect(0,0,800,500);            //更新之前先清除畫布
    drawTank(myTank.x,myTank.y);        //清除完之后重新造坦克,坦克要移動就必須實時地根據坐標重新來造
}

//設置一個間歇調用的函數,每隔100ms更新一下戰場
setInterval(function(){
    updateFloor();
},100);

//響應玩家的操作指令
window.onkeydown = function(eve){                                                
    switch(eve.keyCode){
        case 38:
        case 87:
            myTank.y -= myTank.step;    //Y坐標減小向上移動
            break;
        case 40:
        case 83:
            myTank.y += myTank.step;    //Y坐標增加向下移動
            break;
        case 37:
        case 65:
            myTank.x -= myTank.step;    //X坐標減小向左移動
            break;
        case 39:
        case 68:
            myTank.x += myTank.step;    //X坐標增加向右移動
    }
};    
  所有必要的說明都已經寫在了注釋中。這樣寫出來之后,我們發現坦克已經可以隨着玩家的按鍵上下左右移動了,但是還存在一點問題,坦克運動起來非常的生硬,不管向哪個方向動它的頭一直都是朝上的,我們必須在這個基礎上做以修改,下篇待續...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM