如何基于javascript實(shí)現(xiàn)貪吃蛇游戲
這篇文章主要介紹了如何基于javascript實(shí)現(xiàn)貪吃蛇游戲,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
html代碼:
<div class="content"> <div class="btn startBtn"> <!-- 開(kāi)始按鈕 --> <button type="button"></button> </div> <div class="btn stopBtn"> <!-- 暫停按鈕 --> <button type="button"></button> </div> <div id="snakeWrap"></div> <!-- 主題內(nèi)容 --> </div>
css代碼:
* { margin: 0; padding: 0; } body { background-color: #565F65; width: 100%; height: 10vh; overflow: hidden; } .content { width: 500px; height: 500px; position: absolute; top: 50%; left: 50%; margin-top: -250px; margin-left: -250px; background-color: #565F65; border: 10px solid #E7E7E7; box-shadow: inset 0px 0px 5px 2px #000; } .btn { width: 100%; height: 100%; position: absolute; top: 0; left: 0; background-color: rgba(0, 0, 0, .3); /*游戲未開(kāi)始時(shí)和暫停時(shí)的遮罩*/ z-index: 2; } .btn button { background: none; border: none; background-size: 100% 100%; cursor: pointer; outline: none; position: absolute; left: 50%; top: 50%; } .startBtn button{ width: 170px; height: 80px; background-image: url(img/startbtn.png); margin-top: -40px; margin-left: -85px; } .stopBtn { display: none; } .stopBtn button{ width: 70px; height: 70px; background-image: url(img/stopbtn.png); margin-top: -35px; margin-left: -35px; } #snakeWrap { width: 500px; height: 500px; position: relative; } .snakeHead { /*蛇頭樣式*/ background-color: aqua; border-radius: 50%; } .snakeBody { /*蛇身樣式*/ background-color: navajowhite; border-radius: 50%; } .food { /*食物樣式*/ background-image: url(img/food.png); background-size: cover; }
javascript 代碼:
var sw = 20, //一個(gè)方塊的寬 sh = 20, //一個(gè)方塊的高 tr = 25, //行數(shù) td = 25; //列數(shù) var snake = null, //蛇的實(shí)例 food = null, //食物的實(shí)例 game = null; //游戲的實(shí)例 function Square(x, y, classname) { this.x = x * sw; //方塊實(shí)際的位置 this.y = y * sh; //方塊實(shí)際的位置 this.class = classname; this.viewContent = document.createElement('div'); //方塊對(duì)應(yīng)的DOM元素 this.viewContent.className = this.class; this.parent = document.getElementById('snakeWrap'); //方塊的父級(jí) } Square.prototype.create = function() { //創(chuàng)建方塊 DOM,并添加到頁(yè)面里 this.viewContent.style.position = 'absolute'; this.viewContent.style.width = sw + 'px'; this.viewContent.style.height = sh + 'px'; this.viewContent.style.left = this.x + 'px'; this.viewContent.style.top = this.y + 'px'; this.parent.appendChild(this.viewContent); }; Square.prototype.remove = function() { this.parent.removeChild(this.viewContent); } //蛇 function Snake() { this.head = null; //存一下蛇頭的信息 this.tail = null; //存一下蛇尾的信息 this.pos = []; //存儲(chǔ)蛇身上的每一個(gè)方塊的位置,二維數(shù)組 this.directionNum = { //存儲(chǔ)蛇走的方向,用一個(gè)對(duì)象來(lái)表示 left : { x : -1, y : 0, rotate : 180 }, right : { x : 1, y : 0, rotate : 0 }, up : { x : 0, y : -1, rotate : -90 }, down : { x : 0, y : 1, rotate : 90 } } } Snake.prototype.init = function() { //創(chuàng)建蛇頭 var snakeHead = new Square(2, 0, 'snakeHead'); snakeHead.create(); this.head = snakeHead; // 存儲(chǔ)蛇頭信息 this.pos.push([2, 0]); //把蛇頭的位置存起來(lái) //創(chuàng)建蛇身體 var snakeBody1 = new Square(1, 0, 'snakeBody'); snakeBody1.create(); this.pos.push([1, 0]); //把蛇身1的位置存起來(lái) var snakeBody2 = new Square(0, 0, 'snakeBody'); snakeBody2.create(); this.tail = snakeBody2; //把蛇尾的信息存起來(lái) this.pos.push([0, 0]); //把蛇身1的位置存起來(lái) //讓蛇頭蛇身形成鏈表關(guān)系 snakeHead.last = null; snakeHead.next = snakeBody1; snakeBody1.last = snakeHead; snakeBody1.next = snakeBody2; snakeBody2.last = snakeBody1; snakeBody2.next = null; //給蛇添加一條屬性,用來(lái)表示蛇走的方向 this.direction = this.directionNum.right; //默認(rèn)讓蛇往右走 } //這個(gè)方法用來(lái)獲取蛇頭的下一個(gè)位置對(duì)應(yīng)的元素, 要根據(jù)元素做不同的事情 Snake.prototype.getNextPos = function() { var nextPos = [ //蛇頭要走的下一個(gè)點(diǎn)的坐標(biāo) this.head.x/sw + this.direction.x, this.head.y/sh + this.direction.y ]; //下一個(gè)點(diǎn)是自己,代表撞到了自己,游戲結(jié)束 var selfCollind = false; //是否撞到自己 this.pos.forEach(function(value) { if(value[0] == nextPos[0] && value[1] == nextPos[1]) { //如果數(shù)組中的兩個(gè)數(shù)據(jù)都相等,就說(shuō)明下一個(gè)點(diǎn)在蛇身上里面能找到,代表撞到自己了 selfCollind = true; } }); if(selfCollind) { console.log('撞到自己了!'); this.strategies.die.call(this); return; } //下一個(gè)點(diǎn)是墻,游戲結(jié)束 if(nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > td - 1 || nextPos[1] > tr - 1) { console.log('撞墻了!'); this.strategies.die.call(this); return; } //下一個(gè)點(diǎn)是食物,吃 if(food && food.pos[0] == nextPos[0] && food.pos[1] == nextPos[1]) { //如果這個(gè)條件成立說(shuō)明現(xiàn)在蛇頭要走的下一個(gè)點(diǎn)是食物的那個(gè)點(diǎn) console.log('撞到食物了了!'); this.strategies.eat.call(this); return; } //下一個(gè)點(diǎn)什么都不是,走 this.strategies.move.call(this); }; //處理碰撞后要做的事 Snake.prototype.strategies = { move : function(format) { //這個(gè)參數(shù)用于決定要不要?jiǎng)h除最后一個(gè)方塊(蛇尾), 當(dāng)傳了這個(gè)參數(shù)后就表示要做的事情是吃 //創(chuàng)建新身體(在蛇頭位置) var newBody = new Square(this.head.x/sw, this.head.y/sh, 'snakeBody'); //更新鏈表關(guān)系 newBody.next = this.head.next; newBody.next.last = newBody; newBody.last = null; this.head.remove(); //舊舌頭從原來(lái)的位置刪除 newBody.create(); //創(chuàng)建一個(gè)新蛇頭(蛇頭下一個(gè)要走到的點(diǎn)) var newHead = new Square(this.head.x/sw + this.direction.x, this.head.y/sh + this.direction.y, 'snakeHead') //更新鏈表關(guān)系 newHead.next = newBody; newHead.last = null; newBody.last = newHead; newHead.viewContent.style.transform = 'rotate('+this.direction.rotate+'deg)'; newHead.create(); //蛇身上每一個(gè)方塊的坐標(biāo)也要更新 this.pos.splice(0,0, [this.head.x/sw + this.direction.x, this.head.y/sh + this.direction.y]); this.head = newHead; //還要把this.head的信息更新一下 if(!format) { //如何format 的值為 false, 表示需要?jiǎng)h除(除了吃之外的操作) this.tail.remove(); this.tail = this.tail.last; this.pos.pop(); } }, eat : function() { this.strategies.move.call(this, true); createFood(); game.score ++; }, die : function() { game.over(); } } snake = new Snake(); //創(chuàng)建食物 function createFood() { //食物小方塊的隨機(jī)坐標(biāo) var x = null; var y = null; var include = true; //循環(huán)跳出的條件, true表示食物的坐標(biāo)在蛇身上(需要繼續(xù)循環(huán)),false表示食物坐標(biāo)不在蛇身上(不循環(huán)了) while(include) { x = Math.round(Math.random() * (td - 1)); //0-29 y = Math.round(Math.random() * (tr - 1)); snake.pos.forEach(function(value) { if(x != value[0] && y != value[1]) { //這個(gè)條件成立說(shuō)明現(xiàn)在隨機(jī)出來(lái)的這個(gè)坐標(biāo),在蛇身上并沒(méi)有找到 include = false; } }); } //生成食物 food = new Square(x, y, 'food'); food.pos = [x,y]; //存儲(chǔ)一下生成食物的坐標(biāo),用于跟蛇頭要走的下一個(gè)點(diǎn)作對(duì)比 var foodDom = document.querySelector('.food'); if(foodDom) { foodDom.style.left = x*sw + 'px'; foodDom.style.top = y*sh + 'px'; }else { food.create(); } } //創(chuàng)建游戲邏輯 function Game() { this.timer = null; this.score = 0; this.speed = 200; } Game.prototype.init = function() { snake.init(); snake.getNextPos(); createFood(); document.onkeydown = function(ev) { //用戶按下方向鍵觸發(fā)事件 if(ev.which == 37 && snake.direction != snake.directionNum.right) { //用戶按下左鍵是,蛇不能是往右走 snake.direction = snake.directionNum.left; }else if(ev.which == 38 && snake.direction != snake.directionNum.dowm) { snake.direction = snake.directionNum.up; }else if(ev.which == 39 && snake.direction != snake.directionNum.left) { snake.direction = snake.directionNum.right; }else if(ev.which == 40 && snake.direction != snake.directionNum.up) { snake.direction = snake.directionNum.down; } } this.start(); } Game.prototype.start = function() { //開(kāi)始游戲 this.timer = setInterval(function() { snake.getNextPos(); }, this.speed); } Game.prototype.pause = function() { clearInterval(this.timer); } Game.prototype.over = function() { //開(kāi)始游戲 clearInterval(this.timer); alert('你的得分為' + this.score); //游戲回到最初的狀態(tài) var snakeWrap = document.getElementById('snakeWrap'); snakeWrap.innerHTML = ''; snake = new Snake(); game = new Game(); var startBtnWrap = document.querySelector('.startBtn'); startBtnWrap.style.display = 'block'; } //開(kāi)啟游戲 game = new Game(); var startBtn = document.querySelector('.startBtn button'); startBtn.onclick = function() { startBtn.parentNode.style.display = 'none'; game.init(); }; //暫停 var snakeWrap = document.getElementById('snakeWrap'); var puseBtn = document.querySelector('.stopBtn button') snakeWrap.onclick = function() { game.pause(); puseBtn.parentNode.style.display = 'block'; } puseBtn.onclick =function() { game.start(); puseBtn.parentNode.style.display = 'none'; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
小程序圓形進(jìn)度條及面積圖實(shí)現(xiàn)的方法
做微信小程序的朋友大都接觸過(guò)或自己動(dòng)手寫(xiě)過(guò)自定義組件,下面這篇文章主要給大家介紹了關(guān)于小程序圓形進(jìn)度條及面積圖實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05JavaScript實(shí)現(xiàn)簡(jiǎn)易計(jì)算器小功能
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡(jiǎn)易計(jì)算器小功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10js中鼠標(biāo)滾輪事件詳解(firefox多瀏覽器)
之前js 仿Photoshop鼠標(biāo)滾輪控制輸入框取值中已使用js對(duì)鼠標(biāo)滾輪事件進(jìn)行控制,滾輪事件其中考慮瀏覽器兼容性問(wèn)題2010-02-02JavaScript函數(shù)防抖動(dòng)debounce
這篇文章主要介紹了JavaScript函數(shù)防抖動(dòng)debounce,防抖動(dòng)作用防止在短時(shí)間內(nèi)過(guò)于頻繁的執(zhí)行相同的任務(wù),更多相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-06-06Webpack框架核心概念(知識(shí)點(diǎn)整理)
webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的模塊打包器(module bundler)。這篇文章主要介紹了Webpack框架核心概念(知識(shí)點(diǎn)整理),需要的朋友可以參考下2017-12-12JS實(shí)現(xiàn)懸浮移動(dòng)窗口(懸浮廣告)的特效
頁(yè)面加載完成之后向頁(yè)面插入窗口,之后向窗口插入關(guān)閉按鈕,使用setInterval()函數(shù)觸發(fā)moves()函數(shù)開(kāi)始動(dòng)畫(huà)2013-03-03