JavaScript寫(xiě)個(gè)貪吃蛇小游戲(超詳細(xì))
貪吃蛇大家都玩過(guò),但你會(huì)制作嘛?聽(tīng)起來(lái)好像很難的樣子,其實(shí)非常的簡(jiǎn)單,話不多說(shuō)直接上代碼
我們先把dom結(jié)構(gòu)寫(xiě)出來(lái)
<div id="content">
<div id="snake">
<div class="box head"></div>
<div class="box"></div>
</div>
</div>
其中,content為整個(gè)布局的大盒子,snake就是蛇,里面的box就是他的身體,為了區(qū)分頭部我們給第一個(gè)box加了個(gè)head名字用于區(qū)分,下面我們?cè)侔裞ss加上
<style>
.box{
width: 60px;
height: 60px;
background-color: red;
position:absolute;
left: 0;
top: 0;
line-height: 60px;
}
.head{
background-color: yellowgreen;
}
</style>
我們給蛇的每一節(jié)的寬高設(shè)置為60像素,并給了一個(gè)定位,因?yàn)槿绻患佣ㄎ坏脑挓o(wú)法讓他脫離文檔流(在頁(yè)面中飄起來(lái)),而且后續(xù)也無(wú)法通過(guò)left和top來(lái)判斷他的坐標(biāo).

好的這樣我們就得到了一條可愛(ài)的小蛇(然鵝并沒(méi)有看出來(lái)哪里可愛(ài)- -)。什么?你問(wèn)我他的頭哪去了,很簡(jiǎn)單,在給元素加了定位以后后面的元素會(huì)覆蓋掉前面的元素,所以只是頭部和身體重疊了你看不到而已。
隨后咱們得讓這條蛇動(dòng)起來(lái)是吧,那么我們?cè)趺醋屗麆?dòng)起來(lái)呢?原理很簡(jiǎn)單,我們可以設(shè)置一個(gè)定時(shí)器,每過(guò)一個(gè)時(shí)間就讓他動(dòng)一下,而怎么讓他動(dòng)呢,只需要設(shè)置一個(gè)數(shù)值,讓這個(gè)值每動(dòng)一下就+=60,然后通過(guò)判斷是上下動(dòng)還是左右動(dòng),來(lái)給元素的left與top賦值。我們把邏輯寫(xiě)成代碼,就出來(lái)了如下的代碼
<script>
var boxs = document.querySelectorAll(".box");
var snake_x = 0;
var snake_y = 0;
var turn = "right";
setInterval(function(){
snakeMove();
},100)
function snakeMove(){
switch( turn ){
case "right": snake_x += 60;break;
case "left" : snake_x -= 60;break;
case "top" : snake_y -= 60;break;
case "bottom": snake_y += 60;break;
}
for(var i = boxs.length - 1; i > 0 ; i --){
boxs[i].style.left = boxs[i - 1].style.left;
boxs[i].style.top = boxs[i - 1].style.top;
}
boxs[i].style.left = snake_x + "px";
boxs[i].style.top = snake_y + "px";
}
document.onkeydown = function(evt){
var e = evt || event;
var keyCode = e.keyCode || e.which;
switch( keyCode ){
case 37 : turn = "left";break;
case 38 : turn = "top";break;
case 39 : turn = "right";break;
case 40 : turn = "bottom";break;
}
}
</script>
上述代碼中,我們給小蛇的初始位置的x和y的坐標(biāo)都設(shè)置為0,并且默認(rèn)初始向右走,通過(guò)鍵盤(pán)上方向鍵的輸入,來(lái)改變他的方向。其中,難點(diǎn)在于
for(var i = boxs.length - 1; i > 0 ; i --){
boxs[i].style.left = boxs[i - 1].style.left;
boxs[i].style.top = boxs[i - 1].style.top;
}
boxs[i].style.left = snake_x + "px";
boxs[i].style.top = snake_y + "px";
這一塊代碼,這塊代碼的目的是讓后面的元素跟著前面的走,也就是讓蛇的每一塊身體都跟著上一塊去運(yùn)動(dòng),然后最后再給頭部設(shè)置為snake_x和snake_y當(dāng)前的值即可,這樣就形成了第一塊(頭部)坐標(biāo)為
snake_x,snake_y實(shí)時(shí)變化的值,第二塊為第一塊之前的值,第三塊為第二塊之前的值。。。以此類推就得到了一個(gè)身體跟著頭部走的效果

但是當(dāng)你把代碼輸進(jìn)去以后一運(yùn)行會(huì)發(fā)現(xiàn),這條小蛇過(guò)于頑皮,以至于走到邊界以后還會(huì)無(wú)限的向前走,那這不行啊,總不能讓蛇跑了不是,所以得給小蛇加上一個(gè)邊界
var snake_x_max = document.documentElement.clientWidth ;
var snake_y_max = document.documentElement.clientHeight;
if(snake_x > snake_x_max){
snake_x = 0;
}
if(snake_x < 0){
snake_x = snake_x_max;
}
if(snake_y > snake_y_max){
snake_y = 0;
}
if(snake_y < 0){
snake_y = snake_y_max;
}
這里我們?cè)O(shè)置x和y的最大值為當(dāng)前窗口的寬高,然后通過(guò)if語(yǔ)句進(jìn)行判斷,如果當(dāng)前坐標(biāo)大于了最大值,就講當(dāng)前坐標(biāo)歸0,如果小于0的話(也就是跑到了左邊的邊界),就將當(dāng)前坐標(biāo)設(shè)置為最大值,這樣就可以得到一個(gè)邊界啦

你以為這樣就完事啦?nonono,沒(méi)有食物吃的蛇怎么能叫做貪吃蛇呢,那是沒(méi)有靈魂噠。下面我們開(kāi)始制作食物(不能讓蛇餓著是吧)。
<div id="food">
</div>
然后給他加個(gè)css
#food{
width: 60px;
height: 60px;
position: absolute;
background: greenyellow;
}
然后再綁定一下元素并將他的left和top值設(shè)為范圍內(nèi)隨機(jī)數(shù),這樣可以做到隨機(jī)位置生成
var fd=document.getElementById("food");
fd.style.left=Math.random()*snake_x_max+"px";
fd.style.top=Math.random()*snake_y_max+"px";
好的這樣我們就得到了一個(gè)隨機(jī)生成的食物

不過(guò)我們的小蛇好像對(duì)食物并沒(méi)有什么興趣呢,路過(guò)以后并不會(huì)吃掉,所以我們得給他加一個(gè)碰撞檢測(cè)吧,碰撞檢測(cè)的邏輯很簡(jiǎn)單,只需要讓食物的left值與頭部的left值相減的絕對(duì)值<=食物的大小,并且食物的top值與頭部的top值相減的絕對(duì)值<=食物的大小,設(shè)置小于等于是因?yàn)槿绻苯佑孟嗟葋?lái)判斷的話,必須兩個(gè)元素完全重合才行,我們需要的是碰到邊緣就算遲到,所以用兩個(gè)數(shù)值相減小于等于來(lái)做。然后判斷當(dāng)頭部與食物發(fā)生碰撞時(shí),將蛇的身體部分克隆一塊出來(lái)放到蛇的身體里面,并讓食物的位置重新刷新(適用克隆為偷懶方法,此偷懶方法僅適用于當(dāng)小蛇開(kāi)局自帶一個(gè)身體的時(shí)候,如果小蛇開(kāi)局不自帶身體的話,我們無(wú)法克隆已有身體,只能通過(guò)createElement去新創(chuàng)建一個(gè)身體塊出來(lái)并添加className后再添加到父元素中去才行)。下面我們把邏輯轉(zhuǎn)換為代碼
var dl=snake_x;
var dt=snake_y;
var fl=fd.style.left;
var ft=fd.style.top;
var dv=document.querySelectorAll("#snake div");
var sk=document.getElementById("snake");
var a2=Number(fl.substring(0,fl.indexOf("px")));
var b2=Number(ft.substring(0,ft.indexOf("px")));
if(Math.abs(dl-a2)<=60&&Math.abs(dt-b2)<=60){
fd.style.left=Math.random()*1000+"px";
fd.style.top=Math.random()*800+"px";
sk.appendChild(dv[1].cloneNode());
boxs = document.querySelectorAll(".box");
}
其中那一大長(zhǎng)串的substring的方法是因?yàn)楂@取到的left與top的值的格式是例如”200px”這樣的數(shù)組,無(wú)法進(jìn)行數(shù)學(xué)運(yùn)算,所以要把px給截掉,并將剩下的字符串”200”轉(zhuǎn)換成number類型才可以進(jìn)行數(shù)學(xué)運(yùn)算。

這樣一個(gè)簡(jiǎn)單的貪吃蛇就做好啦~
啥?你問(wèn)我什么什么類似碰到自己會(huì)死這樣更多的規(guī)則機(jī)制咋沒(méi)寫(xiě),肯定是因?yàn)槲覒邪?!我連createElement都懶得用直接克隆一個(gè)出來(lái)了,咋會(huì)勤快到把剩下這么多的機(jī)制補(bǔ)全呢哈哈?;A(chǔ)機(jī)制我已經(jīng)寫(xiě)出來(lái)了,各種奇奇怪怪的機(jī)制還是留給小伙伴們自由發(fā)揮吧~
PS:大家完全可以把頭部的背景圖片改成你小伙伴的照片,再把食物改成一些你想讓ta吃的東西,可以拿來(lái)惡搞啊哈哈哈
到此這篇關(guān)于JavaScript寫(xiě)個(gè)貪吃蛇小游戲(超詳細(xì))的文章就介紹到這了,更多相關(guān)js 貪吃蛇內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js下劃線和駝峰互相轉(zhuǎn)換的實(shí)現(xiàn)(多種方法)
本文主要介紹了js下劃線和駝峰互相轉(zhuǎn)換的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
javascript高級(jí)編程之函數(shù)表達(dá)式 遞歸和閉包函數(shù)
這篇文章主要介紹了javascript高級(jí)編程之函數(shù)表達(dá)式 遞歸和閉包函數(shù)的相關(guān)資料,需要的朋友可以參考下2015-11-11
通過(guò)BootStrap實(shí)現(xiàn)輪播圖的實(shí)際應(yīng)用
js我們沒(méi)有學(xué)過(guò),今天我是用bootstrap實(shí)現(xiàn)輪播圖的效果,非常不錯(cuò)代碼簡(jiǎn)單易懂,需要的朋友參考下吧2016-09-09
JavaScript的事件監(jiān)聽(tīng)你了解嗎
這篇文章主要為大家詳細(xì)介紹了JavaScript的事件監(jiān)聽(tīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03
你必須了解的JavaScript中的屬性描述對(duì)象詳解(上)
JavaScript提供了一個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來(lái)描述對(duì)象的屬性,控制它的行為,比如該屬性是否可寫(xiě)、可遍歷等等。這個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu)稱為“屬性描述對(duì)象”。本文主要帶大家了解一下JavaScript中你必須了解的屬性描述對(duì)象,需要的可以參考一下2022-12-12
詳細(xì)聊聊TypeScript中unknown與any的區(qū)別
unknown類型比較謙虛,就和他本身的意思一樣,他從不禍害到其他的變量,但是any類型就是那種惡霸,屬于什么都不管,誰(shuí)也不敢管的類型,這篇文章主要給大家介紹了關(guān)于TypeScript中unknown與any區(qū)別的相關(guān)資料,需要的朋友可以參考下2021-10-10
JS鏈?zhǔn)秸{(diào)用的實(shí)現(xiàn)方法
程序開(kāi)發(fā)人員可以使用一些簡(jiǎn)單的技術(shù)來(lái)改進(jìn)自己的代碼編寫(xiě)工作。你可以寫(xiě)一些函數(shù)來(lái)處理各種常見(jiàn)任務(wù),以節(jié)省時(shí)間;也可以改進(jìn)一下代碼的實(shí)現(xiàn)方式,比如你可以把方法的鏈?zhǔn)秸{(diào)用技術(shù)用到自己所寫(xiě)的JS庫(kù)中,把自己喜歡的方法串起來(lái)調(diào)用。2013-03-03

