原生JS之貪吃蛇
阿新 • • 發佈:2018-10-31
注:本文章程式碼根據網上教程所編寫(略有改動)
html
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>貪吃蛇</title> <link rel="stylesheet" href="snake.css"> </head> <body> <div class="startPage" id="startPage"> <div class="startBtn" id="startBtn"></div> </div> <div class="wrapper"> <div class="left-side"> <img src="img/start.png" alt="" id="start"> <img src="img/pause.png" alt="" id="pause"> </div> <div class="main"> <div class="header"> <div class="score"> 分數: <span id="score"></span> </div> </div> <div class="content" id="content"> </div> </div> </div> <!-- 遊戲失敗的彈窗 --> <div class="loser" id="loser"> <div class="con"> <div class="close" id="close"></div> <span class="loserScore" id="loserScore"></span> </div> </div> <script src="snake.js"></script> </body> </html>
css
* { margin: 0; padding: 0; } .startPage { width: 100%; height: 100%; z-index: 999; position: absolute; top: 0; left: 0; /* display: none; */ } .startBtn { background-image: url("img/startGame.png"); height: 170px; width: 200px; background-size: 100% 100%; cursor: pointer; position: absolute; top: 0; left: 0; bottom: 0; right: 0; margin: auto; } .wrapper { width: 100%; height: 100%; background-image: url('img/bg.jpg'); background-size: 100% 100%; position: relative; } .left-side { width: 24%; position: absolute; height: 20%; /* border: 1px solid black; */ top: 65%; left: 38%; } .left-side img { display: none; float: left; margin-left: 50px; margin-top: 50px; cursor: pointer; } .main { position: absolute; left: 25%; width: 50%; height: 70%; /* border: 1px solid black; */ } .header { width: 100%; height: 80px; text-align: center; } .score { line-height: 80px; color: #dddddd; font-size: 20px; font-weight: bold; } .content { position: absolute; width: 79.5%; height: 48%; left: 10%; top: 43%; /* border: 1px solid black; */ } .loser { display: none; width: 100%; height: 1000px; top: 0; left: 0; } .con { background-image: url('img/startP.jpg'); background-size: 100% 100%; width: 400px; height: 300px; position: absolute; margin: auto; top: 0; left: 0; right: 0; bottom: 0; border-radius: 20px; } .close { background-image: url('img/closeBtn.png'); background-size: 100% 100%; position: absolute; top: 0; right: 0; height: 40px; width: 40px; cursor: pointer; } .loserScore { height: 30px; height: 40px; position: absolute; top: 42%; left: 40%; color: #222222; font-size: 30px; font-weight: bold; } .food { background-image: url('img/apple.png'); background-size: 100% 100%; } /* 蛇頭 */ .head { background-image: url('img/head.png'); background-size: 100% 100%; } /* 蛇身 */ .body { background-image: url('img/body.png'); background-size: 100% 100%; }
Js
程式碼設計思路
//點選開始遊戲--startPage消失--遊戲開始
//隨機出現食物、出現三節蛇開始運動
//上下左右---改變運動方向
//判斷是否吃到食物---食物消失,蛇身+1
//判斷遊戲結束--彈框
程式碼
var content = document.getElementById('content'); var startPage = document.getElementById('startPage'); var scoreBox = document.getElementById('score'); var loser = document.getElementById('loser'); var loseScore = document.getElementById('loserScore'); var closeBtn = document.getElementById('close'); var startBtn = document.getElementById('startBtn'); var start = document.getElementById('start'); var pause = document.getElementById('pause'); var startGameBool = true; var startPaushBool = true; var code; var snakeMove; var speed = 300; init(); //初始化函式 function init() { //地圖 this.mapW = parseInt(getComputedStyle(content).width); //取得地圖寬 this.mapH = parseInt(getComputedStyle(content).height); //取得地圖高 this.mapDiv = content; //食物 this.foodW = 20; //食物寬度 this.foodH = 20; //食物高度 this.foodX = 0; this.foodY = 0; //蛇 this.snakeW = 20; this.snakeH = 20; this.SnakeBody = [ [3, 1, 'head'], [2, 1, 'body'], [1, 1, 'body'] ]; //遊戲屬性 this.direct = 'right'; //當方向為右時 只能上/下操作 不能左/右操作 this.left = false; this.right = false; this.up = true; this.down = true; this.score = 0; } bindEvent(); function StartGame() { food(); snake(); bindEvent(); } //生成食物 function food() { var food = document.createElement('div'); food.style.width = this.foodW + 'px'; food.style.height = this.foodH + 'px'; food.style.position = 'absolute'; this.foodX = Math.floor(Math.random() * (this.mapW / 20)); this.foodY = Math.floor(Math.random() * (this.mapH / 20)); food.style.left = this.foodX * 20 + 'px'; food.style.top = this.foodY * 20 + 'px'; this.mapDiv.appendChild(food).setAttribute('class', 'food'); for(var i=0;i<this.SnakeBody.length;i++){ if(this.foodX==SnakeBody[i][0]&&this.foodY== SnakeBody[i][1]){ food(); } } } //生成蛇 function snake() { for (var i = 0; i < this.SnakeBody.length; i++) { var snake = document.createElement('div'); snake.style.width = this.snakeW + 'px'; snake.style.height = this.snakeH + 'px'; snake.style.position = 'absolute'; snake.style.left = this.SnakeBody[i][0] * 20 + 'px'; snake.style.top = this.SnakeBody[i][1] * 20 + 'px'; snake.classList.add(this.SnakeBody[i][2]); this.mapDiv.appendChild(snake).classList.add('snake'); switch (this.direct) { case 'right': break; case 'up': snake.style.transform = 'rotate(270deg)'; break; case 'left': snake.style.transform = 'rotate(180deg)'; break; case 'down': snake.style.transform = 'rotate(90deg)'; break; default: break; } } } //運動 function move() { for (var i = this.SnakeBody.length - 1; i > 0; i--) { this.SnakeBody[i][0] = this.SnakeBody[i - 1][0]; this.SnakeBody[i][1] = this.SnakeBody[i - 1][1]; } switch (this.direct) { case 'right': this.SnakeBody[0][0] += 1; break; case 'up': this.SnakeBody[0][1] -= 1; break; case 'left': this.SnakeBody[0][0] -= 1; break; case 'down': this.SnakeBody[0][1] += 1; break; default: break; } removeClass('snake'); snake(); //蛇吃到食物 if (this.SnakeBody[0][0] == this.foodX && this.SnakeBody[0][1] == this.foodY) { //獲取最後一個蛇身的位置 var snakeEndX = this.SnakeBody[this.SnakeBody.length - 1][0]; var snakeEndY = this.SnakeBody[this.SnakeBody.length - 1][1]; switch (this.direct) { case 'right': this.SnakeBody.push([snakeEndX + 1, snakeEndY, 'body']); break; case 'up': this.SnakeBody.push([snakeEndX, snakeEndY - 1, 'body']); break; case 'left': this.SnakeBody.push([snakeEndX - 1, snakeEndY, 'body']); break; case 'down': this.SnakeBody.push([snakeEndX, snakeEndY + 1, 'body']); break; default: break; } this.score += 1; scoreBox.innerHTML = this.score; removeClass('food'); food(); } //判斷邊界 //碰到左/右邊界 if (this.SnakeBody[0][0] < 0 || this.SnakeBody[0][0] >= this.mapW / 20) { // console.log("gg"); relodGame(); } //碰到上/下邊界 if (this.SnakeBody[0][1] < 0 || this.SnakeBody[0][1] >= this.mapH / 20) { // console.log("gg"); relodGame(); } //蛇頭的座標 var snakeHX = this.SnakeBody[0][0]; var snakeHY = this.SnakeBody[0][1]; for (var i = 1; i < this.SnakeBody.length; i++) { if (snakeHX == SnakeBody[i][0] && snakeHY == SnakeBody[i][1]) { // console.log("gg"); relodGame(); } } } //遊戲結束後 重置遊戲 function relodGame() { removeClass('snake'); removeClass('food'); clearInterval(snakeMove); this.SnakeBody = [ [3, 1, 'head'], [2, 1, 'body'], [1, 1, 'body'] ]; this.left = false; this.right = false; this.up = true; this.down = true; loser.style.display = 'block'; loseScore.innerHTML = this.score; this.score = 0; scoreBox.innerHTML = this.score; startGameBool = true; startPaushBool = true; } function removeClass(className) { var ele = document.getElementsByClassName(className); while (ele.length > 0) { ele[0].parentNode.removeChild(ele[0]); } } function setDirect(code) { switch (code) { case 37: 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; } } function bindEvent() { closeBtn.onclick = function () { loser.style.display = 'none'; startPage.style.display = 'block'; start.style.display = 'none'; pause.style.display = 'none'; } startBtn.onclick = function () { startPage.style.display = 'none'; start.style.display = 'block'; pause.style.display = 'block'; //此處初始化 為了防止當再次開始遊戲時的方向傳送改變 init(); StartGame(); document.onkeydown = function (e) { code = e.keyCode; setDirect(code); } snakeMove = setInterval(function () { move(); }, speed); } start.onclick = function () { startAgain(); } pause.onclick = function () { stop(); } } function startAgain() { document.onkeydown = function (e) { var code = e.keyCode; setDirect(code); } snakeMove = setInterval(function () { move(); }, speed); } function stop() { clearInterval(snakeMove); document.onkeydown = function (e) { e.returnValue = false; return false; }; }