JavaScript繪制游戲地圖并且操控人物移動(dòng)
JavaScript開發(fā)小游戲,目標(biāo)是使用JavaScript繪制簡(jiǎn)單的二維地圖,采用二維數(shù)組存儲(chǔ)地圖信息,使用表格繪制地圖,每個(gè)td單元格存儲(chǔ)數(shù)據(jù)。使用JavaScript keyPress鍵盤事件監(jiān)聽WASD鍵,按鍵觸發(fā)時(shí)人物做出相應(yīng)操作。人物下一步碰撞到障礙物,終止人物運(yùn)動(dòng)。
一、列計(jì)劃
1.1、目標(biāo)
做一個(gè)2D二維地圖繪制、人物移動(dòng)、障礙檢測(cè)相關(guān)的單頁(yè)面游戲
1.2、步驟
準(zhǔn)備素材(圖片):草坪、人物(熊貓)、障礙(石頭)
初始化布局(表格),邊距設(shè)置為0,無邊框,設(shè)置背景圖(草坪)平鋪拉滿
標(biāo)記草坪、熊貓、石頭的代碼
初始化二維地圖數(shù)據(jù),初始化障礙物圍墻,初始化人物位置
計(jì)算公共變量二維地圖的行、列
合并二維地圖數(shù)據(jù)、人物位置數(shù)據(jù),渲染到頁(yè)面
設(shè)置全局鍵盤事件(在Body上添加),監(jiān)聽wasd按鍵事件:w(上) s(下) a(左) d(右)
在事件里增加任務(wù)移動(dòng)邏輯、增加邊界邏輯
在事件里增加障礙檢測(cè)邏輯
二、使用步驟
2.1、準(zhǔn)備素材(圖片):草坪、人物(熊貓)、障礙(石頭)
2.2、初始化布局(表格),邊距設(shè)置為0,無邊框,設(shè)置背景圖(草坪)平鋪拉滿
設(shè)置table的ID:map1001
代表是編號(hào)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、標(biāo)記草坪、熊貓、石頭的代碼
<script>
var empty = 0; //空地或草坪
var stone = 1; //石頭的標(biāo)記是1
var panda = 9; //熊貓的標(biāo)記是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、計(jì)算公共變量二維地圖的行、列
<script>
var row = mapData.length; //地圖的行
var column = mapData[0].length; //地圖的列
</script>2.6、合并二維地圖數(shù)據(jù)、人物位置數(shù)據(jù),渲染到頁(yè)面
<script>
/**
* 合并二維地圖數(shù)據(jù)、人物位置數(shù)據(jù),渲染到頁(yè)面
*/
function init() {
//二維數(shù)組里,去初始化熊貓的位置
mapData[initPoint[0]][initPoint[1]] = panda
loadData(mapData);
}
/**
* 渲染地圖
* @param mapData
*/
function loadData(mapData) {
// 獲取地圖對(duì)象
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ù)移動(dòng)邏輯/增加邊界邏輯、在事件里增加障礙檢測(cè)邏輯
<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("碰撞到石頭了,停止動(dòng)作")
return
}
console.log("移動(dòng)后的位置:x:" + xPoint + " , y:" + yPoint )
initPoint = [yPoint,xPoint]
operatePanda(point);
console.log("向上")
} else {
console.log("超出地圖范圍了,停止動(dòng)作")
}
} 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("碰撞到石頭了,停止動(dòng)作")
return
}
console.log("移動(dòng)后的位置:x:" + xPoint + " , y:" + yPoint )
initPoint = [yPoint,xPoint]
operatePanda(point);
console.log("向左")
} else {
console.log("超出地圖范圍了,停止動(dòng)作")
}
} 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("碰撞到石頭了,停止動(dòng)作")
return
}
console.log("移動(dòng)后的位置:x:" + xPoint + " , y:" + yPoint )
initPoint = [yPoint,xPoint]
operatePanda(point);
console.log("向下")
} else {
console.log("超出地圖范圍了,停止動(dòng)作")
}
} 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("碰撞到石頭了,停止動(dòng)作")
return
}
console.log("移動(dòng)后的位置:x:" + xPoint + " , y:" + yPoint )
initPoint = [yPoint,xPoint]
operatePanda(point);
console.log("向右")
} else {
console.log("超出地圖范圍了,停止動(dòng)作")
}
}
}
/**
* 障礙檢測(cè)(可加多個(gè)障礙條件)
* @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,目標(biāo)值:1,1
嘗試走直線,從左走到目標(biāo),中途碰到石頭障礙就走不動(dòng)了,此時(shí)上下左都有石頭障礙,都走不動(dòng),只能向右走
向右走1格
向下走2格
向左走2格
向上走一格
向左走一格
向上走一格
抵達(dá)目標(biāo)
總結(jié)
以上就是今天要講的內(nèi)容,本文僅僅簡(jiǎn)單介紹了2D二維地圖繪制、人物移動(dòng)、障礙檢測(cè),可以根據(jù)此開發(fā)出自動(dòng)尋徑避障、多障礙物繪制、NPC自動(dòng)出現(xiàn)并移動(dòng)、人物動(dòng)畫動(dòng)作、多地圖切換、裝備倉(cāng)庫(kù)、裝備效果等。例如:推箱子、走迷宮、副本游戲、熊貓吃竹子等。
相關(guān)文章
js判斷當(dāng)頁(yè)面無法回退時(shí)關(guān)閉網(wǎng)頁(yè)否則就history.go(-1)
當(dāng)頁(yè)面沒有前驅(qū)歷史記錄時(shí),點(diǎn)擊返回按鈕時(shí)直接關(guān)閉頁(yè)面,否則就退回到前一頁(yè)2014-08-08
基于JavaScript中標(biāo)識(shí)符的命名規(guī)則介紹
下面小編就為大家分享一篇基于JavaScript中標(biāo)識(shí)符的命名規(guī)則介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
JavaScript中數(shù)組flat方法的使用與實(shí)現(xiàn)方法
在Array的顯示原型下有一個(gè)flat方法,可以將多維數(shù)組,降維,傳的參數(shù)是多少就降多少維,下面這篇文章主要給大家介紹了關(guān)于JavaScript中數(shù)組flat方法的使用與實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2022-08-08
js+canvas實(shí)現(xiàn)刮刮獎(jiǎng)功能
這篇文章主要為大家詳細(xì)介紹了js+canvas實(shí)現(xiàn)刮刮獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
javascript FAQ函數(shù)(提問+回復(fù))
javascript FAQ函數(shù),當(dāng)點(diǎn)擊問題時(shí)顯示下面的回復(fù)內(nèi)容。2009-07-07
JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)事件畫筆
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)事件畫筆,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08

