JavaScript繪制游戲地圖并且操控人物移動
JavaScript開發(fā)小游戲,目標是使用JavaScript繪制簡單的二維地圖,采用二維數(shù)組存儲地圖信息,使用表格繪制地圖,每個td單元格存儲數(shù)據(jù)。使用JavaScript keyPress鍵盤事件監(jiān)聽WASD鍵,按鍵觸發(fā)時人物做出相應(yīng)操作。人物下一步碰撞到障礙物,終止人物運動。
一、列計劃
1.1、目標
做一個2D二維地圖繪制、人物移動、障礙檢測相關(guān)的單頁面游戲
1.2、步驟
準備素材(圖片):草坪、人物(熊貓)、障礙(石頭)
初始化布局(表格),邊距設(shè)置為0,無邊框,設(shè)置背景圖(草坪)平鋪拉滿
標記草坪、熊貓、石頭的代碼
初始化二維地圖數(shù)據(jù),初始化障礙物圍墻,初始化人物位置
計算公共變量二維地圖的行、列
合并二維地圖數(shù)據(jù)、人物位置數(shù)據(jù),渲染到頁面
設(shè)置全局鍵盤事件(在Body上添加),監(jiān)聽wasd按鍵事件:w(上) s(下) a(左) d(右)
在事件里增加任務(wù)移動邏輯、增加邊界邏輯
在事件里增加障礙檢測邏輯
二、使用步驟
2.1、準備素材(圖片):草坪、人物(熊貓)、障礙(石頭)
2.2、初始化布局(表格),邊距設(shè)置為0,無邊框,設(shè)置背景圖(草坪)平鋪拉滿
設(shè)置table的ID:map1001
代表是編號1001的地圖
<style> table { border-collapse: collapse; padding: 0 ; background: url("../img/item/grass.png"); width:100%; height:100% ; background-position: center; background-size:cover; background-repeat: no-repeat; } td { width: 100px; height: 100px; } tr { display: block; margin: -5px; } </style> <body onload="init()" onkeypress="keypress(event)"> <table id="map1001"> </table> </body>
2.3、標記草坪、熊貓、石頭的代碼
<script> var empty = 0; //空地或草坪 var stone = 1; //石頭的標記是1 var panda = 9; //熊貓的標記是9 </script>
2.4、初始化二維地圖數(shù)據(jù),初始化障礙物圍墻,初始化人物位置
<script> /** * 加載地圖數(shù)據(jù) * 0 空地/草坪 * 1 石頭 * 9 熊貓 * @type {number[]} */ var mapData = [ [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1] , [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1] , [ 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1] , [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1] , [ 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1] , [ 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1] , [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1] ] var initPoint = [1,4]; //初始化熊貓的位置是 1,4 </script>
2.5、計算公共變量二維地圖的行、列
<script> var row = mapData.length; //地圖的行 var column = mapData[0].length; //地圖的列 </script>
2.6、合并二維地圖數(shù)據(jù)、人物位置數(shù)據(jù),渲染到頁面
<script> /** * 合并二維地圖數(shù)據(jù)、人物位置數(shù)據(jù),渲染到頁面 */ function init() { //二維數(shù)組里,去初始化熊貓的位置 mapData[initPoint[0]][initPoint[1]] = panda loadData(mapData); } /** * 渲染地圖 * @param mapData */ function loadData(mapData) { // 獲取地圖對象 var map = document.getElementById("map1001"); //渲染一行八列的數(shù)據(jù) var mapHTML = ""; for (var i = 0; i < row; i++) { mapHTML += "<tr>"; for (var j = 0; j < column; j++) { if( mapData[i][j] == 0 ){ mapHTML += "<td></td>"; } else if( mapData[i][j] == 1 ){ mapHTML += '<td><img src="../img/item/stone.png" style="height: 90px; height: 90px; border-radius: 50%;" ></td>'; } else if( mapData[i][j] == 9 ){ mapHTML += '<td><img src="../img/item/panda1.png" style="height: 90px; height: 90px; border-radius: 50%;" ></td>'; } } mapHTML += "</tr>"; } map.innerHTML = mapHTML; } </script> <body onload="init()" >
2.7、設(shè)置全局鍵盤事件(在Body上添加),監(jiān)聽wasd按鍵事件:w(上) s(下) a(左) d(右)、在事件里增加任務(wù)移動邏輯/增加邊界邏輯、在事件里增加障礙檢測邏輯
<script> /** * 監(jiān)聽wasd按鍵事件:w(上) s(下) a(左) d(右) * @param e */ var keypress = function keypress(e){ var keynum = window.event ? e.keyCode : e.which; if( 119 == keynum ) { var point = initPoint; if( point[0] < row - 1 ) { var xPoint = initPoint[1]; var yPoint = initPoint[0] - 1; if( checkStone(yPoint,xPoint) ){ console.log("碰撞到石頭了,停止動作") return } console.log("移動后的位置:x:" + xPoint + " , y:" + yPoint ) initPoint = [yPoint,xPoint] operatePanda(point); console.log("向上") } else { console.log("超出地圖范圍了,停止動作") } } else if( 97 == keynum ) { var point = initPoint; if( point[1] > 0 ) { var xPoint = initPoint[1] -1; var yPoint = initPoint[0]; if( checkStone(yPoint,xPoint) ){ console.log("碰撞到石頭了,停止動作") return } console.log("移動后的位置:x:" + xPoint + " , y:" + yPoint ) initPoint = [yPoint,xPoint] operatePanda(point); console.log("向左") } else { console.log("超出地圖范圍了,停止動作") } } else if( 115 == keynum ) { var point = initPoint; if( point[0] < row - 1 ) { var xPoint = initPoint[1]; var yPoint = initPoint[0] + 1; if( checkStone(yPoint,xPoint) ){ console.log("碰撞到石頭了,停止動作") return } console.log("移動后的位置:x:" + xPoint + " , y:" + yPoint ) initPoint = [yPoint,xPoint] operatePanda(point); console.log("向下") } else { console.log("超出地圖范圍了,停止動作") } } else if( 100 == keynum ) { var point = initPoint; if( point[1] < column -1 ) { var xPoint = initPoint[1] + 1; var yPoint = initPoint[0]; if( checkStone(yPoint,xPoint) ){ console.log("碰撞到石頭了,停止動作") return } console.log("移動后的位置:x:" + xPoint + " , y:" + yPoint ) initPoint = [yPoint,xPoint] operatePanda(point); console.log("向右") } else { console.log("超出地圖范圍了,停止動作") } } } /** * 障礙檢測(可加多個障礙條件) * @param yPoint * @param xPoint * @returns {boolean} */ function checkStone(yPoint , xPoint ) { return mapData[yPoint][xPoint] == stone; } </script> <body onload="init()" onkeypress="keypress(event)">
3、部分效果
嘗試走到右上角的位置,初始化位置:1,4,目標值:1,1
嘗試走直線,從左走到目標,中途碰到石頭障礙就走不動了,此時上下左都有石頭障礙,都走不動,只能向右走
向右走1格
向下走2格
向左走2格
向上走一格
向左走一格
向上走一格
抵達目標
總結(jié)
以上就是今天要講的內(nèi)容,本文僅僅簡單介紹了2D二維地圖繪制、人物移動、障礙檢測,可以根據(jù)此開發(fā)出自動尋徑避障、多障礙物繪制、NPC自動出現(xiàn)并移動、人物動畫動作、多地圖切換、裝備倉庫、裝備效果等。例如:推箱子、走迷宮、副本游戲、熊貓吃竹子等。
相關(guān)文章
手把手教會你用Javascript實現(xiàn)放大鏡效果(詳細注釋+完整代碼)
放大鏡可以說是前端人必須學(xué)會的程序之一,下面這篇文章主要給大家介紹了關(guān)于手把手教會你用Javascript實現(xiàn)放大鏡效果的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-03-03JavaScript 函數(shù)用法詳解【函數(shù)定義、參數(shù)、綁定、作用域、閉包等】
這篇文章主要介紹了JavaScript 函數(shù)用法,結(jié)合實例形式分析了JavaScript函數(shù)定義、參數(shù)、綁定、作用域、閉包、回調(diào)函數(shù)、柯理化函數(shù)等相關(guān)概念、原理與操作注意事項,需要的朋友可以參考下2020-05-05Javascript Echarts空氣質(zhì)量地圖效果詳解
這篇文章主要介紹了詳解Javascript利用echarts畫空氣質(zhì)量地圖,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-10-10