其中,主要的难点是第二步,如何让蛇移动,这里大致讲解一些实现思路。首先需要把蛇和地图画出来。这里我设置地图大小为600px。然后取每一格子大小为15px。即地图总格子数为40×40。
<!DOCTYPE html> <html> <head> <title>贪吃蛇</title> <meta charset="utf-8"> <style type="text/css"> .container{ width: 600px; height: 600px; border: solid 1px black; position: relative; } .snakeBody{ width: 13px; height: 13px; border: 1px solid white; background-color: black; position: absolute; } #snakeHead{ width: 13px; height: 13px; border: 1px solid white; background-color: blue; position: absolute; } </style> </head> <body> <div align="center"> <div class="container"> <div class="snakeBody" style="left: 0;top: 0;" id="1"></div> <div class="snakeBody" style="left: 15px;top: 0;" id="2"></div> <div class="snakeBody" style="left: 30px;top: 0;" id="3"></div> <div class="snakeBody" style="left: 45px;top: 0;" id="4"></div> <div id="snakeHead" style="left: 60px;top: 0;"></div> </div> </div> </body> </html>其次,需要编写js函数。实际上蛇的运动方式实现十分简单。操作起来只需要两步。第一步,将蛇头往运动方向前进一格。第二步,将蛇尾的div移动到蛇头移动前的位置。那么,要如何获得蛇尾的div呢?我采用的方法是使用队列存放蛇身div的id。经过排序之后,能够每一次从队列取出的id都是蛇尾的id。使用完之后将该id再次放入队列中
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script type="text/javascript"> //队列用来储存snakeBody var queue = new Array(); var front =0; var rear =0; //蛇头运动方向,0,1,2,3代表上下左右。初始默认向右走 var direction = 1; $(document).ready(function () { //将蛇身的id放入队列 queue[rear++]=4; queue[rear++]=3; queue[rear++]=2; queue[rear++]=1; setTimeout(move,300); }) //蛇运动的函数 //每一次运动,将蛇头往运动方向移动一格。并将蛇尾的div移动到蛇头的位置 function move() { //得到蛇头的位置 var snakeHeadtop = parseInt($('#snakeHead').css('top')); var snakeHeadLeft = parseInt($('#snakeHead').css('left')); //得到处在蛇尾div的id,并将该id重新加入队列 var id = queue[front++]; queue[rear++]=id; //将蛇尾的div移动到蛇头位置 $('#'+id).css('top',snakeHeadtop+'px') ; $('#'+id).css('left',snakeHeadLeft+'px') ; //将蛇头往运动方向移动一格 if (direction == 0) { $('#snakeHead').css('top',(snakeHeadtop-15)+"px"); }else if (direction == 1) { $('#snakeHead').css('left',(snakeHeadLeft+15)+"px"); }else if (direction == 2) { $('#snakeHead').css('top',(snakeHeadtop+15)+"px"); }else if (direction == 3) { $('#snakeHead').css('left',(snakeHeadLeft-15)+"px"); } setTimeout(move,300); } </script>下面为完整的代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>贪吃蛇</title> <style type="text/css"> .container{ width: 520px; height: 520px; border: 1px solid black; margin: 20px 100px; position: relative; } .snakeBody{ width: 11px; height: 11px; border: 1px solid white; background-color: black; position: absolute; } #snakeHead{ width: 11px; height: 11px; border: 1px solid white; background-color: blue; position: absolute; } #food{ width: 11px; height: 11px; border: 1px solid white; background-color: red; position: absolute; } </style> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script type="text/javascript"> // 初始化地图,size为一行或一列的格数,520为container的大小,cell为每一个格子的大小 var size = 40; var cell = 520/size; var map = new Array(); var timeController ; //初始化蛇 //snakeLength为蛇初始长度 //direction为蛇的运动方向0,1,2,3为上右下左 var direction; var preDirection; var snakeLength = 5; //初始化队列 //队列用来储存snakeBody var queue = new Array(); var front =0; var rear =0; //游戏状态 var game=false; $(document).ready(function () { // map 中 0为空地,1为蛇所占位置,2为食物 for (var i = 0; i<=size; i++) { map[i] = new Array(); for(var j = 0; j<=size; j++){ map[i][j]=0; } } //初始化蛇的位置 for(var i=0; i<snakeLength-1; i++){ map[0][i]=1; var left = i * cell; $('.container').append('<div class="snakeBody" style="left: '+left+'px;top: 0" id ='+i+'></div>') } map[0][i]=1; left = i * cell; $('.container').append('<div id="snakeHead" style="left: '+left+'px;top: 0"></div>') for(var i=0;i<snakeLength-1;i++){ putQueue(i); } }) //移动函数 function move(){ //蛇头移动前的位置信息 var preSnakeHeadleft = parseInt($('#snakeHead').css("left")); var preSnakeHeadtop = parseInt($('#snakeHead').css("top")); //将蛇头朝着方向前进一格 if(direction == 0 ){ //如果运动方向和之前方向相反,则继续往之前方向运动 if (preDirection != 2) { $('#snakeHead').css('top',(preSnakeHeadtop-cell)+"px"); } else{ $('#snakeHead').css('top',(preSnakeHeadtop+cell)+"px"); direction = preDirection; } }else if(direction == 1 ){ if ( preDirection != 3) { $('#snakeHead').css('left',(preSnakeHeadleft+cell)+"px"); } else{ $('#snakeHead').css('left',(preSnakeHeadleft-cell)+"px"); direction = preDirection; } }else if(direction == 2 ){ if (preDirection != 0) { $('#snakeHead').css('top',(preSnakeHeadtop+cell)+"px"); }else{ $('#snakeHead').css('top',(preSnakeHeadtop-cell)+"px"); direction = preDirection; } }else if(direction == 3 ){ if (preDirection != 1) { $('#snakeHead').css('left',(preSnakeHeadleft-cell)+"px"); }else{ $('#snakeHead').css('left',(preSnakeHeadleft+cell)+"px"); direction = preDirection; } } preDirection=direction; //判断蛇头前进的格子状态 snakeHeadtop = parseInt($('#snakeHead').css('top')); snakeHeadleft = parseInt($('#snakeHead').css('left')); if(snakeHeadtop<0||snakeHeadtop>=520||snakeHeadleft<0||snakeHeadleft>=520){ game=false; gameover('游戏结束:蛇撞到墙壁'); } if (game) { var mapStatus = map[snakeHeadtop/cell][snakeHeadleft/cell]; if (mapStatus == 0) { //在map中将蛇头所在位置设为1 setMap('snakeHead',1); //将队列的头出队列,然后再插入队尾 var i = outQueue(); putQueue(i); //在map中,将蛇尾所在位置设为0 setMap(i,0); //将蛇尾移动到移动前蛇头位置 $('#'+i).css('left',preSnakeHeadleft+"px"); $('#'+i).css('top',preSnakeHeadtop+"px"); timeController = setTimeout(move,120); }else if (mapStatus == 1) { //撞到了自己。游戏结束 gameover('游戏结束:蛇撞到自己'); }else if (mapStatus == 2) { //吃到食物 //在map中将蛇头所在位置设为1 setMap('snakeHead',1); //得到新增snakeBody的id var id = snakeLength-1; putQueue(id); $('.container').append('<div class="snakeBody" style="left: '+preSnakeHeadleft+'px;top: '+preSnakeHeadtop+'px;" id ="'+id+'"></div>') snakeLength++; //生成食物 $('#food').remove(); createFood(); timeController = setTimeout(move,120); } } } //游戏开始 function start(){ //游戏为结束状态,才可以开始游戏 resetting(); if (!game) { direction = 1; preDirection = 1; createFood(); game = true; //初始化暂停功能 $("#pause").val(1); //游戏状态 $('#msg').html("游戏中"); timeController = setTimeout(move,1000); } } //监听按键事件 $(document).keydown(function(event){ //38上,39右,40下,37左 if(event.keyCode == 38){ direction = 0; } if(event.keyCode == 39){ direction = 1; } if(event.keyCode == 40){ direction = 2; } if(event.keyCode == 37){ direction = 3; } }); //创建食物 function createFood(){ while(true){ var x = random(0,size); var y = random(0,size); if (map[x][y]==0) { $('.container').append('<div style="left: '+y*cell+'px;top: '+x*cell+'px;" id="food"></div>') map[x][y] = 2; break; } } } //得到随机数 function random(min, max) { return Math.floor(Math.random() * (max - min)) + min; } //通过id设置其在map中的值 function setMap(id,num){ var left = $('#'+id).css("left"); var top = $('#'+id).css("top"); map[parseInt(top)/cell][parseInt(left)/cell]=num; } //重置游戏 function resetting(){ //停掉move函数 clearTimeout(timeController); $('.container').html(""); $('#msg').html("点击按钮开始游戏"); game = false; front =0; rear =0; snakeLength = 5; // map 中 0为空地,1为蛇所占位置,2为食物 for (var i = 0; i<=size; i++) { map[i] = new Array(); for(var j = 0; j<=size; j++){ map[i][j]=0; } } //初始化蛇的位置 for(var i=0; i<snakeLength-1; i++){ map[0][i]=1; var left = i * cell; $('.container').append('<div class="snakeBody" style="left: '+left+'px;top: 0" id ='+i+'></div>') } map[0][i]=1; left = i * cell; $('.container').append('<div id="snakeHead" style="left: '+left+'px;top: 0"></div>') for(var i=0;i<snakeLength-1;i++){ putQueue(i); } } function gameover(message){ message = message+"---------" +"蛇长度为"+snakeLength; $('#msg').html(message); } //出队列 function outQueue(){ if (front >= size*size) { front = 0; } var i = queue[front]; front++; return i; } //进队列s function putQueue(i){ if(rear >= size*size){ rear = 0; } queue[rear]=i; rear++; } //暂停 function pause(obj){ //游戏进行才可以暂停 if(game){ var value = $(obj).val(); if(value == 1 ){ $(obj).val(0); $('#msg').html("游戏暂停"); clearTimeout(timeController); }else{ $(obj).val(1); $('#msg').html("游戏中"); timeController = setTimeout(move,1000); } } } </script> </head> <body style="overflow: hidden;"> <div align="center"> <h1 style="margin-bottom: 10px;margin-top: 0;">贪吃蛇</h1> <span id="msg" style="color: red;">点击按钮开始游戏</span> <div class="container"></div> <button onclick="start()">开始</button> <button onclick="resetting()">重置</button> <button onclick="pause(this)" id="pause">暂停/继续</button> </div> </body> </html>