日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

学写前端原生贪吃蛇

發(fā)布時間:2024/3/13 HTML 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学写前端原生贪吃蛇 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

看了人家視頻上寫的貪吃蛇,瞬間覺得自己low爆了。。。。就學(xué)他寫了三遍,以我的記性,覺得還是有必要記錄下過程,以便記憶。
先看下截圖:

首先html分析:
注:下列的id是用在js里的,class是用在css里的

<div class="startPage" id="startPage"> <!-- 這是開始頁的大頁面 --><div class="startBtn" id="startBtn"></div> <!-- 載在大頁面上的開始按鈕鍵 --></div><div class="wrapper"> <!-- 開始后的大頁面 --><div class="left-side"> <!-- 將大頁面分出一個左邊,用來承載暫停和計(jì)分的按鍵 --><div class="header"> <!-- 在這個左邊的開頭寫個用來載計(jì)分的框 --><div class="score"> <!-- 顯示“分?jǐn)?shù)” -->分?jǐn)?shù):<span id="score"></span> <!-- 用在之后js里的動態(tài)計(jì)分操作 --></div></div><img src="img/zanting.png" id="startP" alt=""> <!-- 顯示暫停按鈕,這個按鈕用圖片代替 --></div><div class="main"> <!-- 大頁面中的主頁面,和左邊的區(qū)分下 --><div class="content" id="content"></div> <!-- 游戲區(qū)域,在js里控制 --></div></div><div class="lose" id="lose"> <!-- 游戲結(jié)束的大頁面 --><div class="con"> <!-- 游戲結(jié)束后的計(jì)分清單 --><span class="loseScore" id="loseScore"> <!-- js動態(tài)計(jì)分 --></span><div class="close" id="close"></div> <!-- 游戲結(jié)束計(jì)分上的關(guān)閉按鈕 --></div></div>

上述是貪吃蛇的全部html代碼,將貪吃蛇游戲的大致界面劃分出來。
接下來是css代碼:

*{ /* css的書寫習(xí)慣,先將所有的margin和padding的默認(rèn)值都去掉 */margin: 0;padding: 0; }.startPage{ /* 開始游戲的大頁面設(shè)置 */width: 100%;height: 640px; /* 游戲界面高度,這是我按自己電腦瀏覽器大小設(shè)置的 */position: absolute; /* 給它個絕對定位 */z-index: 999; /* 顯示在界面最前頭 */}.startBtn{ /* 游戲開始按鍵的設(shè)置 */width: 200px; /* 設(shè)置按鍵圖片的寬和高 */height: 50px;position: absolute; /* 從這到margin:auto,這幾行放在一起,表示居中在大頁面的正中間 */top: 0;left: 0;bottom: 0;right: 0;margin:auto;background-image: url(img/begin.png); /* 把開始按鍵的圖片放入 */background-size: 100% 100%; /* 將圖片平攤開 */cursor: pointer; /* 鼠標(biāo)劃入時,箭頭變成小手 */}.wrapper{ /* 游戲開始后的大頁面 */width: 100%;height: 640px; /* 同上含義 */background-image: url('img/bj1.png'); /* 放入游戲背景圖片 */background-size: 100% 100%; /* 平攤 */position: relative; /* 相對定位 */top: 0px;left: 0px; }.left-side{ /* 在大頁面上劃分出的左邊部分 */width: 14%; /* 占大頁面的14%寬度 */height: 640px; /* 高度 */position: absolute; /* 絕對定位 */top: 0;left: 0; }.left-side img{ /* 顯示暫停按鍵圖片的設(shè)置 */width: 120px; /* 設(shè)置圖片的寬高 */height: 40px;position: absolute; /* 絕對定位 */left: 15%; /* 該圖片在左邊劃分框中,距離左邊距15% */top: 100px; /* 圖片距離上邊距100px */}.header{ /* 用來承載計(jì)分的框 */width: 100%; height: 40px;margin-top: 30px; /* 外邊距30px */position: absolute; /* 絕對定位 */ }.score{ /* 計(jì)分?jǐn)?shù)字顯示 */width: 100px;height: 40px;font-size: 18px;color: #fff; /* 字體白色 */position: absolute; /* 基于上個absolute的中心定位 */top: 0;left: 0;bottom: 0;right: 0;margin:auto; }.main{ /* 在大頁面中劃分出的另一個部分 */position: absolute; /* 絕對定位 */left: 15%; /* 距離大頁面左邊據(jù)15% */width: 52%; /* 占大頁面的寬52% */height: 640px; /* 值含義同上 */border: 1px solid black; /* 邊框,作為標(biāo)識,可去除 */ }.content{ /* 游戲邊框,用來表示蛇不能出去的部分 */position: absolute; top: 0;left: 0;bottom: 0;right: 0;margin:auto; /* 從position到這表示基于父級定位的中心定位 */width: 525px; /* 邊框的寬高 */height: 525px;border: 13px solid rgb(2, 32, 7); /* 邊框框 */ }.lose{ /* 表示游戲結(jié)束后的出現(xiàn)的一個大頁面 */width: 100%;height: 640px;position: absolute;top: 0;left: 0;display: none; /* 先設(shè)置不顯示,之后在js中修改 */ }.con{ /* 表示游戲結(jié)束后出現(xiàn)的結(jié)束圖片 */width: 340px; /* 為圖片設(shè)置寬高 */height: 160px;background-image:url('img/over.png'); /* 加入圖片 */background-size: 100% 100%; /* 平攤圖片 */position: absolute; /* 同上 */top: 0;left: 0;bottom: 0;right: 0;margin:auto;border-radius: 15% 15%; /* 圖片的四個角設(shè)置圓度 */ }.loseScore{ /* 在js中調(diào)用,用來顯示最后的計(jì)分結(jié)果 */font-size: 24px; /* 字體大小24px */color: #fff;position: absolute;left: 130px; /* 計(jì)分?jǐn)?shù)字在游戲結(jié)束圖片上找到合適的位置存放 ,這是按自己的圖片設(shè)置的*/top: 80px; }.close{ /* 設(shè)置游戲結(jié)束右上角的關(guān)閉按鈕 */background-image: url('img/shanchu.png'); /* 插入關(guān)閉按鈕圖片 */background-size: 100% 100%; /* 平攤圖片 */width: 35px; /* 設(shè)置關(guān)閉按鈕的寬高 */height: 35px;position: absolute; /* 絕對定位 */top: 0px;right: 0px; /* 圖片放到右上角 */ }

還有部分css代碼,在js代碼編輯的時候一同寫出,現(xiàn)在上述的css算是將貪吃蛇游戲的頁面背景設(shè)置完畢。
接下來js代碼:

var content = document.getElementById('content'); //將html中有id = content的元素提取出來function init(){ //設(shè)置初始時的所有默認(rèn)值this.foodW = 20; //表示食物的寬this.foodH = 20; //高this.foodX = 0; //表示食物的x坐標(biāo)位置this.foodY = 0; //y坐標(biāo)位置this.snakeW = 0; //蛇的寬高this.snakeH = 0;this.snakeBody = [[4,1,'head'],[3,1,'body'],[2,1,'body']]; //表示三節(jié)蛇身(包括蛇頭),用數(shù)組表示this.mapH = parseInt(getComputedStyle(content).height); //表示游戲界面的寬高,用getComputedStyle(content).height來提取出content里的height屬性值this.mapW = parseInt(getComputedStyle(content).width); //同上含義this.mapDiv = content; //表示界面整體this.direct = 'right'; //初始時蛇的方向this.up = true; // 表示向上蛇可動this.down = true; //向下可動this.right = false; //向右邊不可動this.left = false; //向左邊不可動 //上述表示的具體意思是,當(dāng)蛇的運(yùn)動方向?yàn)橛視r,不能操作蛇的左右運(yùn)動,只能操作上下this.score = 0; //初始計(jì)分為0bindEvent(); //觸發(fā)bindEvent()函數(shù) }

設(shè)置完初始值后,開始設(shè)置蛇和食物的初始狀態(tài)

function food(){ //食物的設(shè)置var food = document.createElement('div'); //生成一個div的食物foodfood.style.width = this.foodW + 'px'; //設(shè)置食物的寬高,等于上述函數(shù)中已經(jīng)設(shè)置好的默認(rèn)食物寬高food.style.height = this.foodH + 'px'; //同上food.style.position = 'absolute'; //設(shè)置食物的位置為絕對定位this.foodX = Math.floor(Math.random()*this.mapW/20); //食物的x坐標(biāo)的隨機(jī)位置,表示0到(游戲界面的寬除以食物自己的寬)的隨機(jī)數(shù)this.foodY = Math.floor(Math.random()*this.mapH/20); //食物的y坐標(biāo)的隨機(jī)位置,同上food.style.top = this.foodY * 20 + 'px'; //表示食物的上邊距距離為食物的y坐標(biāo)乘以自己的高food.style.left = this.foodX * 20 + 'px'; //同上this.mapDiv.appendChild(food).setAttribute('class','food'); //給每個食物div都設(shè)置上名為food的class,再到css中設(shè)置食物的大小和載入圖片 }function snake(){ //蛇的設(shè)置for(var i = 0;i < this.snakeBody.length;i ++){ //用for循環(huán),i小于蛇身的長度,(初始時的length為3)var snake = document.createElement('div'); //生成一個div的蛇snakesnake.style.width = this.snakeW + 20 + 'px'; //設(shè)置生成的蛇的寬高snake.style.height = this.snakeH + 20 + "px";snake.style.position = 'absolute'; //設(shè)置蛇的絕對位置snake.style.top = this.snakeBody[i][1] * 20 + 'px'; //設(shè)置每節(jié)蛇的距離上邊距的位置snake.style.left = this.snakeBody[i][0] * 20 + 'px'; //設(shè)置每節(jié)蛇的距離左邊距的位置snake.classList.add(this.snakeBody[i][2]); //給每節(jié)蛇添加class,這里的class為上述的snakeBody中設(shè)置的第3個位置上的‘head’和’body‘,因此又需要對head和body設(shè)置css代碼,用來區(qū)分蛇頭和蛇身this.mapDiv.appendChild(snake).classList.add('snake'); //在html中添加上snake的div,并加上class = ‘snake’switch(this.direct){ //蛇頭的轉(zhuǎn)向(注:由于我找的蛇頭的方向默認(rèn)為右邊)case 'right': //由于默認(rèn)圖片蛇頭向右所以不需要改變操作break;case 'left' : //將蛇頭的方向轉(zhuǎn)向左邊snake.style.transform = 'rotate(180deg)';break;case 'up' : //將蛇頭方向旋轉(zhuǎn)到上邊snake.style.transform = 'rotate(270deg)';break;case 'down' : //將蛇頭方向旋轉(zhuǎn)到下方snake.style.transform = 'rotate(90deg)';break;default :break;}} }

食物和蛇的css代碼:

.food{background-image: url('img/pg.png'); //加入食物的圖片background-size: 100% 100%; }.head{background-image: url('img/s.png'); //加入蛇頭的圖片background-size: 100% 100%; }.body{background-image: url('img/she.png'); //加入蛇身的圖片background-size: 100% 100%; }

設(shè)置完蛇和食物的狀態(tài)后,設(shè)置游戲開始時的界面:

var startPage = document.getElementById('startPage'); //從html中獲取到id = startPage的元素節(jié)點(diǎn),startPage表示開始游戲的按鈕 var startP = document.getElementById('startP'); //同上,startP表示暫停的按鈕function startGame(){ //游戲開始startPage.style.display = 'none'; // 將該節(jié)點(diǎn)設(shè)置為不顯示startP.style.display = 'block'; //使該節(jié)點(diǎn)顯示food(); //調(diào)用food函數(shù)snake(); //調(diào)用snake函數(shù) }

接下來設(shè)置蛇的運(yùn)動狀態(tài)js:

var scoreBox = document.getElementById('score'); //獲取用于計(jì)分的節(jié)點(diǎn) function move(){for(var i = this.snakeBody.length-1;i > 0;i --){ //for循環(huán),表示蛇運(yùn)動時,后一節(jié)蛇的位置是前一節(jié)蛇之前所在的位置this.snakeBody[i][0] = this.snakeBody[i-1][0];this.snakeBody[i][1] = this.snakeBody[i-1][1];}switch(this.direct){ //表示蛇頭的轉(zhuǎn)動位置情況case 'right' :this.snakeBody[0][0] +=1; //右邊時,蛇頭的x位置加1break;case 'left' :this.snakeBody[0][0] -=1; //左邊時,蛇頭的x位置減1,break;case 'up' :this.snakeBody[0][1] -=1; //上邊時,蛇頭的y位置減1break;case 'down' :this.snakeBody[0][1] +=1; //下邊時,蛇頭的y位置加1default:break;}removeClass('snake'); //刪除class = ‘snake’的節(jié)點(diǎn)snake(); //重新調(diào)用snake函數(shù)if(this.snakeBody[0][0] == this.foodX && this.snakeBody[0][1] == this.foodY){ //當(dāng)蛇吃到食物時var snakeEndX = this.snakeBody[this.snakeBody.length-1][0]; //表示吃到食物后,蛇尾的x坐標(biāo)為蛇的長-1var snakeEndY = this.snakeBody[this.snakeBody.length-1][1]; //同上switch(this.direct){case 'right':this.snakeBody.push([snakeEndX ,snakeEndY,'body']); //蛇頭向右時,蛇尾的x位置需要+1break;case 'left':this.snakeBody.push([snakeEndX ,snakeEndY,'body']); //蛇頭向左時,蛇尾的x位置需要-1break;case 'up':this.snakeBody.push([snakeEndX,snakeEndY ,'body']); //蛇頭向上時,蛇尾的y位置需要-1break;case 'down':this.snakeBody.push([snakeEndX,snakeEndY ,'body']); //蛇頭向下時,蛇尾的y位置需要+1break;default:break;} //注:當(dāng)蛇吃到食物時,添加的尾巴會在原來的尾巴的位置上加上,直到蛇頭離開食物的位置,此時的尾巴就會變成真正的尾巴this.score += 1; //吃到食物,分?jǐn)?shù)+1scoreBox.innerHTML = this.score; //使html中的id = ‘scoreBox’的節(jié)點(diǎn)上加上此時的分?jǐn)?shù)removeClass('food'); //蛇吃到食物后,所吃的食物消失food(); //又重新出現(xiàn)新的食物的位置}if(this.snakeBody[0][0] < 0 || this.snakeBody[0][0] > this.mapW/20){ //當(dāng)蛇頭x碰到邊界時,游戲結(jié)束reloadGame(); //結(jié)束游戲,重新加載游戲}if(this.snakeBody[0][1] < 0 || this.snakeBody[0][1] > this.mapH/20){ //當(dāng)蛇頭y碰到邊界時,游戲結(jié)束reloadGame(); //結(jié)束游戲,重新加載游戲}var snakeHX = this.snakeBody[0][0]; //得到蛇頭xvar snakeHY = this.snakeBody[0][1]; //得到蛇頭yfor(var i = 1;i < this.snakeBody.length;i++){ //當(dāng)蛇頭碰到自己的身體時,游戲結(jié)束if(snakeHX == snakeBody[i][0] && snakeHY == snakeBody[i][1]){reloadGame();}} }

接下來是刪除節(jié)點(diǎn)的函數(shù):

function removeClass(className){ //給一個class類名var ele = document.getElementsByClassName(className); //用ele得到html中有該class類名的節(jié)點(diǎn)while(ele.length > 0){ //當(dāng)節(jié)點(diǎn)長度大于0時,即存在該節(jié)點(diǎn)ele[0].parentNode.removeChild(ele[0]); //刪除該節(jié)點(diǎn)} }

然后是重新加載游戲的js代碼:

var loseScore = document.getElementById('loseScore'); function reloadGame(){removeClass('snake'); //刪除class = ‘snake’的節(jié)點(diǎn),即刪除蛇removeClass('food'); //刪除食物,同上clearInterval(snakeMove); //清除snakeMove每隔時間間隔長度運(yùn)動this.snakeBody = [[4,1,'head'],[3,1,'body'],[2,1,'body']]; //再添加上默認(rèn)初始的蛇身坐標(biāo)this.direct = 'right'; //初始方向this.right = false; this.left = false;this.up = true;this.down = true;lose.style.display = 'block'; //使id = ‘lose’的節(jié)點(diǎn)出現(xiàn),即出現(xiàn)游戲結(jié)束后的圖片loseScore.innerHTML = this.score; //記錄游戲結(jié)束后的最終得分this.score = 0; //記錄后,清0scoreBox.innerHTML = this.score; //同時將游戲開始時的動態(tài)積分也清0startGameBool = true;startPauseBool = true;startP.setAttribute('src','./img/begin.png'); //改變id = ‘startP’節(jié)點(diǎn)的圖片內(nèi)容 }

關(guān)于操作蛇時的上下左右按鍵設(shè)置:

function setDirect(code){ //給該函數(shù)一個表示對應(yīng)按鍵數(shù)字switch(code){case 37: //表示左,方向?yàn)樽髸r,上下的按鍵可觸發(fā)但是左右的按鍵不可以觸發(fā)if(this.left){this.direct = 'left';this.left = false;this.right = false;this.up = true;this.down = true;}break;case 38: //上 ,同上if(this.up){this.direct = 'up';this.left = true;this.right = true;this.up = false;this.down = false;}break;case 39: //右 ,同上if(this.right){this.direct = 'right';this.left = false;this.right = false;this.up= true;this.down = true;}break;case 40: //下 ,同上if(this.down){this.direct = 'down';this.left = true;this.right = true;this.up = false;this.down = false;}break;default:break;} }

接下來是關(guān)于游戲的開始和暫停的設(shè)置:

var startGameBool = true; //表示該鑰匙是開著時 var startPauseBool = true; var snakeMove; var speed = 200;function startAndPush(){if(startPauseBool){ //關(guān)于暫停的鑰匙if(startGameBool){ //關(guān)于游戲剛開啟時的鑰匙startGame(); //游戲開始,啟動游戲開始的界面startGameBool = false; //游戲開始后,不需要再出現(xiàn)這個過程,將該鑰匙鎖住}startP.setAttribute('src','./img/kk.png'); //為html中的id = ‘startP’設(shè)置插入圖片document.onkeydown = function(e){ //觸發(fā)按鍵發(fā)生的時間var code = e.keyCode; //得到所觸發(fā)按鍵所表示的數(shù)字setDirect(code); //調(diào)用上述的按鍵方向函數(shù)}snakeMove = setInterval(function(){ 表示每隔speed時間啟用一次move(); 調(diào)用move函數(shù),表示每隔speed時間,執(zhí)行一次move函數(shù)事件},speed);startPauseBool = false; //執(zhí)行過后,需要上鎖,防止該事件在游戲過程中被啟用出錯}else{ //當(dāng)鑰匙關(guān)閉時,執(zhí)行的事件startP.setAttribute('src','./img/zanting.png'); //改變id = startP的節(jié)點(diǎn)中的圖片內(nèi)容clearInterval(snakeMove); //清除snakeMove每隔speed時間的執(zhí)行document.onkeydown = function(e){ //表示禁止按鍵啟用e.returnValue = false;return false;}startPauseBool = true; //執(zhí)行上述事件后,將鎖打開} }

之后是關(guān)于主體啟用鍵盤按鍵和鼠標(biāo)按鍵事件:

var lose = document.getElementById('lose'); var close = document.getElementById('close'); var startBtn = document.getElementById('startBtn');function bindEvent(){document.onkeydown = function(e){ //同上述描述,是按鍵的數(shù)字獲取和啟用方向事件var code = e.keyCode;setDirect(code)}close.onclick = function(){ //表示游戲結(jié)束后右上角的關(guān)閉按鍵的觸發(fā)事件lose.style.display = 'none'; //使游戲結(jié)束界面不顯示}startBtn.onclick = function(){ //表示剛啟動游戲時的開始按鈕startAndPush(); }startP.onclick = function(){ //表示游戲中的暫停和解除暫停的鼠標(biāo)按鍵事件startAndPush();} }

上述就是所有的js代碼。。。。
看下成果圖:

注:上述代碼如有解釋錯誤的,請大佬幫忙改善,謝謝,有不清楚的也可以留言,本人會盡量及時回復(fù)的

總結(jié)

以上是生活随笔為你收集整理的学写前端原生贪吃蛇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。