JS實(shí)現(xiàn)簡單貪吃蛇小游戲
本文實(shí)例為大家分享了JS實(shí)現(xiàn)簡單貪吃蛇游戲的具體代碼,供大家參考,具體內(nèi)容如下
1、使用語言 HTML+CSS+JavaScript
2、使用工具 visual studio code
3、GitHub項目地址:貪吃蛇
4、項目運(yùn)行截圖:

5、項目功能分析:主要使用數(shù)組來存儲蛇的位置,地圖和蛇都是一個二維數(shù)組,對于有蛇的地方,地圖的CSS就會發(fā)生改變,同時添加了添加了一個音樂播放按鈕,通過CSS動畫實(shí)現(xiàn)旋轉(zhuǎn)。
6、項目代碼:(項目代碼有詳細(xì)的注釋)
snake.html
<!--
* @Author: CSU_XZY
* @Date: 2020-10-13 22:06:51
* @LastEditors: CSU_XZY
* @LastEditTime: 2020-10-18 17:08:54
* @FilePath: \第二天\貪吃蛇\(yùn)snake.html
* @Description: just to play
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>eatSnake</title>
<head>
<style type="text/css">
*{
margin:0;
padding:0;
border: 0px;
}
body{
background: #444;
}
table{
border-collapse:collapse;
overflow: hidden;
border:1px solid #ddd;
margin:10px auto 10px auto;
}
td{
display: table-cell;
width:20px;
height:20px;
background: #fff;
border:1px #eeeeee solid;
}
.snake{
background: #3388ee;
}
.notsnake{
background: #fff;
}
.food{
background: #33aa33;
}
.snake_head{
background: #dd4444;
}
.notice{
width:450px;
text-align: center;
margin:50px auto;
color:#fff;
font-size: 14px;
}
</style>
</head>
<body>
<p class="notice">提示:空格鍵控制開始/ 暫停,方向鍵控制蛇的移動方向,F(xiàn)5刷新</p>
<script type="text/javascript" src="snake.js"></script>
</body>
</html>
snake.js
/*
* @Author: CSU_XZY
* @Date: 2020-10-17 12:38:26
* @LastEditors: CSU_XZY
* @LastEditTime: 2020-10-18 22:40:24
* @FilePath: \第二天\snake\snake.js
* @Description: just to play
*/
window.onload = function(){
var snake = function(width,height,snakeId,speed){
this.width = width || 10;
this.height = height || 10;
this.snakeId = snakeId || "snake";
this.goX = 0;
this.goY = 0;
this.speed = this.oldSpeed = speed || 10;
this.Grid = []; //存放td的二維數(shù)組
this.snakeGrid = []; //存放蛇的數(shù)組
this.foodGrid = [];
this.snakeTimer = null;
this.derectkey = 39;
this.stop = true;
this.init();
document.getElementById("myAudio").play();
box.style.animationPlayState = 'running'
}
snake.prototype = {
//創(chuàng)建二維數(shù)組
multiArray : function(m , n)
{
var array = new Array(m); //長
for(let i = 0; i < m; i++)
{
array[i] = new Array(n); //寬
}
return array;
},
//函數(shù)修正this
bind : function(fn,context)
{
return function(){
return fn.apply(context,arguments);
}
},
//移動的主函數(shù)
move:function(){
var _this = this;
if(_this.snakeTimer){clearInterval(_this.snakeTimer);}
_this.snakeTimer = setInterval(_this.bind(_this.main,_this),Math.floor(3000/this.speed));
},
//重來
reset()
{
this.goX = 0;
this.goY = 0;
this.speed = this.oldSpeed;
this.derectkey = 39;
this.stop = true;
this.init();
},
//確定鍵盤事件
keyDown : function(e)
{
var e = e || window.event;
var keycode = e?e.keyCode:0;
if(keycode == 116 )
window.location.reload();
if(keycode == 32)
{
if(this.stop)
{
this.move();
this.stop = false;
}
else{
if(this.snakeTimer)
clearInterval(this.snakeTimer);
this.stop = true;
}
}
if(keycode>=37 && keycode <= 40)
{
if(!this.stop)
this.derectkey = keycode;
}
return false;
},
//創(chuàng)建地圖
creatMap : function()
{
var table = document.createElement("table");
var tbody = document.createElement("tbody");
for(let i = 0; i < this.width; i++)
{
var tr = document.createElement("tr");
for(let j = 0; j < this.height; j++)
{
var td = document.createElement("td");
this.Grid[i][j] = tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(tbody);
table.id = this.snakeId;
document.body.appendChild(table);
},
//產(chǎn)生隨機(jī)點(diǎn)
randomPoint : function(initX,initY,endX,endY)
{
var p = []; //用來存放產(chǎn)生的隨機(jī)點(diǎn)的數(shù)組
var initX = initX || 0;
var initY = initY || 0;
var endX = endX || this.width;
var endY = endY || this.height;
p[0] = Math.floor(Math.random()*(endX - initX)) + Math.floor(initX);
p[1] = Math.floor(Math.random()*(endY - initY)) + Math.floor(initY)
return p;
},
//初始化食物的位置
initFood : function()
{
this.foodGrid = this.randomPoint();
if(this.isInSnake(this.foodGrid))
{
this.initFood();
return false;
}
this.Grid[this.foodGrid[0]][this.foodGrid[1]].className = "food";
},
//判斷點(diǎn)是否在蛇身上
isInSnake : function(point,pos)
{
var snakeGrid = this.snakeGrid;
if(point instanceof Array)
{
let n = snakeGrid.length;
for(let i = pos || 0; i < n; i++)
{
if(point[0] == snakeGrid[i][0] && point[1] == snakeGrid[i][1])
return true;
}
}
return false;
},
//給蛇涂顏色
paintSnake : function(){
var snakeGrid = this.snakeGrid;
for(let i = 0; i < snakeGrid.length; i++)
{
this.Grid[snakeGrid[i][0]][snakeGrid[i][1]].className = "snake_body";
}
},
//初始化蛇的位置
initSnake : function()
{
this.snakeGrid = [];
this.snakeGrid.push([1,3]);
this.snakeGrid.push([1,2]);
this.snakeGrid.push([1,1]);
this.paintSnake();
this.Grid[this.snakeGrid[0][0]][this.snakeGrid[0][1]].className = "snake_head";
this.Grid[this.snakeGrid[this.snakeGrid.length-1][0]][this.snakeGrid[this.snakeGrid.length-1][1]].className = "snake_tail";
},
//判斷蛇是否撞墻
isInWall : function(point){
if(point instanceof Array){
if(point[0] < 0 || point[0] > this.width1 - 1 || point[1] < 0 || point[1] > this.height - 1)
return true;
}
return false;
},
//初始化條件
//控制函數(shù)運(yùn)行的主函數(shù)
main : function(){
var snakeGrid = this.snakeGrid;
var temp = snakeGrid[snakeGrid.length-1],
isEnd = false;
headX = snakeGrid[0][0];
headY = snakeGrid[0][1];
msg = "";
switch(this.derectkey)
{
case 37:
if(this.goY!=1){this.goY=-1;this.goX=0} //防止控制蛇往相反反方向走
break;
case 38:
if(this.goX!=1){this.goX=-1;this.goY=0}
break;
case 39:
if(this.goY!=-1){this.goY=1;this.goX=0}
break;
case 40:
if(this.goX!=-1){this.goX=1;this.goY=0}
}
headX += this.goX;
headY += this.goY;
if(headX == this.foodGrid[0] && headY == this.foodGrid[1])
{
this.snakeGrid.unshift(this.foodGrid);
this.initFood();
if(this.snakeGrid.length>4){ //控制蛇加速
if(this.snakeGrid.length==5){
this.speed += 5;
}
else if(this.snakeGrid.length==10){
this.speed += 3;
}
else if(this.snakeGrid.length==20){
this.speed += 3;
}
else if(this.snakeGrid.length==30){
this.speed += 3;
}
this.move();
}
}
else
{
for(var i=this.snakeGrid.length-1;i>0;i--){
this.snakeGrid[i] = this.snakeGrid[i-1] ;
}
this.snakeGrid[0] = [headX,headY];
if(this.isInSnake(this.snakeGrid[0],1)){
isEnd=true;
msg = "哈皮,吃到自己啦!!";
}
//判斷是否撞墻
else if(this.isInWall(this.snakeGrid[0])){
isEnd =true;
msg = "撒比偉哥,撞墻了?。?;
}
if(isEnd)
{
if(this.snakeTimer)
clearInterval(this.snakeTimer);
var score;
let len = this.snakeGrid.length;
if(len <= 5)
score = len-3;
else if(len>5 && len<=10)
{
score = 2 + 2*(len-5)
}
else if(len>10 && len <= 20)
score = 12 + 3*(len-10);
else
score = 27 + 5*(len - 15);
if(confirm(msg+"你的分?jǐn)?shù)是:"+score+"! 是否重新開始?")){
this.reset();
}
return false;
}
this.Grid[temp[0]][temp[1]].className = "notSnake";
}
this.paintSnake();
this.Grid[headX][headY].className = "snake_head";
this.Grid[this.snakeGrid[this.snakeGrid.length-1][0]][this.snakeGrid[this.snakeGrid.length-1][1]].className = "snake_tail";
},
init : function(){
var _this = this;
snake_id = document.getElementById(_this.snakeId)||0 ;
if(snake_id){
document.body.removeChild(snake_id);
}
_this.Grid = _this.multiArray(_this.width,_this.height);
_this.creatMap();
_this.initSnake();
_this.initFood();
document.onkeydown = _this.bind(_this.keyDown,_this);
}
}
new snake(20,20,"snake",10);
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript計算值然后把值嵌入到html中的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄狫avaScript計算值然后把值嵌入到html中的實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10
微信小程序?qū)崿F(xiàn)打開并下載服務(wù)器上面的pdf文件到手機(jī)
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)打開并下載服務(wù)器上面的pdf文件到手機(jī),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09
JS循環(huán)遍歷JSON數(shù)據(jù)的方法
這篇文章主要介紹了JS 循環(huán)遍歷JSON數(shù)據(jù)的方法,需要的朋友可以參考下2014-07-07
typescript中 declare global 關(guān)鍵字用法示例小結(jié)
在TypeScript中,declare global 用于在模塊內(nèi)部擴(kuò)展全局作用域,本文重點(diǎn)介紹typescript中 declare global 關(guān)鍵字用法示例小結(jié),感興趣的朋友跟隨小編一起看看吧2024-04-04
JavaScript設(shè)計模式之職責(zé)鏈模式應(yīng)用示例
這篇文章主要介紹了JavaScript設(shè)計模式之職責(zé)鏈模式,結(jié)合實(shí)例形式分析了javascript責(zé)任鏈模式的概念、原理、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下2018-08-08

