H5坦克大戰之【玩家控制坦克移動】

来源:http://www.cnblogs.com/zhouhuan/archive/2016/12/25/H5_tankgame2.html
-Advertisement-
Play Games

自從威少砍下45+11+11的大號三雙之後,網上出現了各種各樣的神級段子,有一條是這樣的: 威少:Hey,哥們,最近過得咋樣! 濃眉:對方開啟了好友驗證,請先添加對方為好友 威少:。。。。。。 JRS:2333333 看到了一條比賽當天的數據統計:威少45+11+11,杜少32+8+3,伊巴卡19+ ...


  自從威少砍下45+11+11的大號三雙之後,網上出現了各種各樣的神級段子,有一條是這樣的:   威少:Hey,哥們,最近過得咋樣!   濃眉:對方開啟了好友驗證,請先添加對方為好友   威少:。。。。。。   JRS:2333333   看到了一條比賽當天的數據統計:威少45+11+11,杜少32+8+3,伊巴卡19+11+2,雷吉傑克遜17+3+6,哈登16+6+16,雷霆管理層真應該改名雷鋒管理層了,現在對雷霆管理層的每日一輪都是JRS們的常態了。   好了,不扯,接著上一篇博客(H5坦克大戰之畫出坦克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坐標增加向右移動
    }
};    
  所有必要的說明都已經寫在了註釋中。這樣寫出來之後,我們發現坦克已經可以隨著玩家的按鍵上下左右移動了,但是還存在一點問題,坦克運動起來非常的生硬,不管向哪個方向動它的頭一直都是朝上的,我們必須在這個基礎上做以修改。   不過今天先寫到這裡,接下來的內容筆者寫好之後下次再分享給大家!   明天周一,工作的要上班了,上學的也要上課了,大家伙加油哦,過了下周,大家離夢想便又近了一步(\(^o^)/)也在此祝福所有考研的同學,希望大家都能獲得一個自己滿意、別人羡慕的成績!祝福你們! (註:一個人的力量畢竟有限,如果在閱讀的過程中發現有描述不當或者錯誤的地方,歡迎隨時指正,筆者不勝感激!)
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • soChange一款多很經典的幻燈片的jQuery插件。 實例預覽 引入文件 <link rel="stylesheet" type="text/css" media="all" href="style.css" /> <script type="text/javascript" src="jque ...
  • 一、this 在JavaScript中this表示:誰調用它,this就是誰。 JavaScript是由對象組成的,一切皆為對象,萬物皆為對象。this是一個動態的對象,根據調用的對象不同而發生變化,當然也可以使用call、apply修改this指向的對象。它代表函數運行時,自動生成的一個內部對象, ...
  • 一、游標 新增加not-allowed游標,不允許訪問 隱藏游標,在觸模應用上很有用,css2.1需要一個透明的圖片來實現,而css3直接用cursor:none即可。 完整代碼: 二、擴大熱區 應用在小按鈕的情況下,不好被滑鼠點擊到 代碼如下: 三、自定義覆選框 系統自帶覆選框美化 利用css3提 ...
  • 本人Sam。啟蒙微軟派,遁入前端教。已修煉後端技能、領域驅動設計、前端技能等近八餘載。擅長C#,領域驅動設計,必殺技為Javascript、Css。為領域驅動設計在前端教的應用而奮鬥。現將自我領悟的前端教技能秘笈總結如下: 上圖咯: 內功心法 前端教的三大內功秘笈:Html、Css、Javascri ...
  • 由於a標簽屬於內聯元素,無高度和寬度屬性,因此控制滑鼠經過狀態改變背景顏色時,僅在有文字的地方顯示背景顏色。解決的辦法是把a標簽變為塊級元素,display:block ...
  • 設置圖片和文字的垂直居中。vertical-align:middle;圖片豎向居中,然後文字就可以和圖片對齊。 ...
  • 本文系筆者學習原生javascript動效的筆記。內容基於某非著名培訓機構的視頻教程。並重新做了歸類整理。刪除了一些過時的內容。並重做了GIF圖,加上了自己的一些分析。 一. 運動學基礎 引子:從左到右的div 點擊按鈕,一個紅色div從左向右運動! 運動的要素在於一個絕對定位的主體,一個定時器。和 ...
  • 註意:leftBox和rightBox設置浮動之後脫離了普通的文檔流,不再占用原來文檔中的位置,因此無法把父div撐開。 解決的方法: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...