JavaScript 练手项目--实现贪吃蛇小游戏

mac2024-11-13  9

HTML+CSS+JavaScript

(很早以前写写玩的小游戏,今日偶然发现,分享出来。)

整体功能:

点击开始游戏运行游戏–》开始游戏按钮消失–》游戏开始动态随机出现食物,出现三节蛇开始运动暂停、继续游戏功能上下左右–》改变方向运动判断是否吃到食物–》食物消失,蛇长度加一判断游戏结束,弹出游戏结束

源码下载:https://github.com/wuhaolun/Retro-Snaker-JS- 首先是HTML+CSS显示部分:

HTML:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="css/index.css"> </head> <body> <div id="container"> <!--背景区域--> <div class="backgroundGame"> <!-- 左区域暂停开始按钮 --> <div class="leftSide" id="start_Pause"> <img src="img/start-walk.png" alt="" id="start-walk"> <img src="img/pause-walk.png" alt="" id="pause-walk"> </div> <!-- 中间区域 --> <div class="cotent"> <!-- 实时分数 --> <div class="nowScore"> <p>分数:</p> <span id="now_score"></span> </div> <!-- 游戏区域 646*298--> <div class="backgroundPlayGame"> <!-- 蛇活动区域 --> <div class="run" id="Run"> </div> </div> </div> </div> <!-- 开始游戏 --> <div class="beginGame"> <!-- 开始游戏按钮 --> <div class="gameBtn" id="GameBtn"> <!-- <img src="" alt=""> --> </div> </div> <!-- 游戏结束 --> <div class="gameOver"> <div class="overScore"> <!-- 游戏结束图片 --> <div class="Score" id='lose'></div> <!-- 游戏结束分数 --> <span id="over_score" ></span> <!-- 关闭图片按钮 --> <div class="close" id='close_table'></div> </div> </div> </div> <script src="js/index.js"></script> </body> </html>

CSS:

*{ margin: 0; padding: 0; } img{ display: inline-block; } .container{ } /*背景*/ .backgroundGame{ width: 100%; height: 656px; position: relative; background-color: #333333; } #start-walk{ width: 50px; height: 50px; position: absolute; background-color: #e5e5e5; cursor:pointer; margin:0 auto; top: 20px; left: 35px; display: none; } #pause-walk{ width: 50px; height: 50px; position: absolute; background-color: #e5e5e5; cursor:pointer; margin:0 auto; top: 20px; left: 35px; display: none; } .nowScore{ width: 100%; height: 100%; /*position: absolute;*/ } /*分数样式*/ .nowScore p{ /*margin:0 auto;*/ position: absolute; /*display: inline-block;*/ font-size:24px; color:white; z-index:10; top:10px; left: 270px; } /*实时分数*/ #now_score{ position:absolute; font-size:24px; z-index:10; color:white; top:10px; left: 335px; } /*游戏区域*/ .backgroundPlayGame{ width: 825px; height: 635px; background:url("../img/bg-img.png") no-repeat 0px 0px; position: absolute; margin: 0 auto; display:inline-block; /*text-align: center;*/ left: 260px; } /*蛇活动区域*/ .run{ width: 648px; height: 298px; position:absolute; border:1px solid green; left: 89px; top:168px; } /*游戏开始*/ .gameBtn{ width: 290px; height: 150px; z-index:999; background:url("../img/start.png") no-repeat 0px 0px; position: absolute; cursor:pointer; left: 536px; top:236px; /*display:none;*/ } /*游戏结束*/ .Score{ width: 300px; height: 248px; z-index:900; background:url("../img/gameover.png") no-repeat 0px 0px; position:absolute; left: 536px; top:206px; cursor:pointer; display:none; } /*关闭按钮*/ .close{ width: 30px; height: 30px; z-index:999; background:url("../img/close.png") no-repeat 0px 0px; position:absolute; cursor:pointer; left:765px; top:210px; display:none; } /*结束分数*/ #over_score{ position:absolute; color:black; font-size:30px; z-index:999; left:569px; top:388px; } .food{ background:url("../img/apple.png") no-repeat 0px 0px; background-size:100% 100%; } .head{ background:url("../img/snake.png") no-repeat 0px 0px; background-size:100% 100%; } .body{ background:url("../img/pink.png") no-repeat 0px 0px; background-size:100% 100%; }

逻辑部分:

JavaScript

//点击开始游戏运行游戏--》开始游戏按钮消失--》游戏开始 //动态随机出现食物,出现三节蛇开始运动 //上下左右--》改变方向运动 //判断是否吃到食物--》食物消失,蛇长度加一 //判断游戏结束,弹出游戏结束 //蛇活动区域 var run = document.getElementById('Run'); //开始游戏按钮 var gameBtn = document.getElementById('GameBtn'); //实时分数 var scoreBox = document.getElementById('now_score'); //游戏结束图片 var lose= document.getElementById('lose'); //游戏结束分数 var loserScore= document.getElementById('over_score'); //关闭结束界面按钮 var close= document.getElementById('close_table'); // var startAndPause = document.getElementById('start_Pause'); //左上角开始按钮 var startWalk = document.getElementById('start-walk'); //左上角暂停按钮 var pauseWalk = document.getElementById('pause-walk'); //触发蛇向前移动的计时器 var snakeMove; //触发间隔时间200ms var speed = 200; //判断游戏是否继续或停止 var beginGame = true; var pauseGame = true; start(); function start(){ if (beginGame === true){ gameBtn.onclick = function (){ init();//初始化的参数,这里直接调用init() startGame(); show(); } } } startWalk.onclick = function (){ if(beginGame === true){ pauseWalk.style.display='inline-block'; startWalk.style.display='none'; clearInterval(snakeMove); } } pauseWalk.onclick = function(){ if(pauseGame === true){ pauseWalk.style.display='none'; startWalk.style.display='inline-block'; snakeMove = setInterval(function(){ move(); },speed); } } function init(){ //地图 this.mapW = parseInt(getComputedStyle(run).width); this.mapH = parseInt(getComputedStyle(run).height); this.mapDiv = run; //食物 this.foodW = 24; this.foodH = 24; //x,y初始坐标 this.foodX = 0; this.foodY = 0; //蛇(用数组来代表,数组的每一位分别存储蛇头蛇身) this.snakeW = 24; this.snakeH = 24; this.snakeBody = [[4,2,'head'],[3,2,'body'],[2,2,'body']]; //3是因为蛇头应该在最前面,后面的2,1紧接蛇身,这些数字修改的话,蛇的位置也会改变 //游戏属性 this.direct = "right"; this.right = false; this.left = false; this.up = true; this.down = true; this.score = 0; } function show(){ //开始游戏按钮消失 gameBtn.style.display = 'none'; // startAndPause.style.display = 'inline-block'; //暂停键出现 startWalk.style.display = 'inline-block'; } //每次开始时,随机生成一个苹果和一条固定的蛇 function startGame(){ food(); snake(); snakeMove = setInterval(function(){ move(); },speed); 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 / 24)); this.foodY = Math.floor(Math.random() * (this.mapH / 24)); //食物对应的坐标 food.style.left = this.foodX * 24 + 'px'; food.style.top = this.foodY * 24 + 'px'; this.mapDiv.appendChild(food).setAttribute('class','food'); } function snake(){ for(var i = 0;i < this.snakeBody.length; i++){ var snake = document.createElement('div'); //以下都是新添div中的属性 snake.style.width = this.snakeW + 'px'; snake.style.height = this.snakeH + 'px'; snake.style.position = 'absolute' ; //横坐标 snake.style.left = this.snakeBody[i][0] * 24 + 'px'; // 纵坐标 snake.style.top = this.snakeBody[i][1] * 24 + 'px'; // 向run的div中添加蛇头或蛇身图片属性 //这句和.classList.add('snake')达到一样的效果,下句的.classList.add('snake')可以不添加 snake.classList.add(this.snakeBody[i][2]); this.mapDiv.appendChild(snake).classList.add('snake'); //上面两句可以合并成this.mapDiv.appendChild(snake).classList.add(this.snakeBody[i][2]); //根据方向旋转蛇头 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/24){ reloadGame(); } //碰到上下 if(this.snakeBody[0][1] < 0 || this.snakeBody[0][1] >= this.mapH/24){ reloadGame(); } //碰到身体 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]){ reloadGame(); } } } function reloadGame(){ removeClass('snake'); removeClass('food'); clearInterval(snakeMove); this.snakeBody = [[4,2,'head'],[3,2,'body'],[2,2,'body']]; this.direct = "right"; this.right = false; this.left = false; this.up = true; this.down = true; close.style.display = 'inline-block'; lose.style.display = 'inline-block'; loserScore.style.display = 'inline-block'; loserScore.innerHTML ='最终得分:'+ this.score; this.score = 0; scoreBox.innerHTML = this.score; pauseWalk.style.display='none'; startWalk.style.display='none'; } 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(){ document.onkeydown = function(e){ var code = e.keyCode; setDirect(code); } close.onclick = function(){ lose.style.display = 'none'; close.style.display = 'none'; loserScore.style.display = 'none'; //重置界面 gameBtn.style.display = 'inline-block'; pauseWalk.style.display='none'; startWalk.style.display='none'; } }
最新回复(0)