
本课程是通过 Javascript 结合 WebAPI DOM 实现的一版网页游戏---贪吃蛇的开发全过程,采用面向以象的思想设计开发。通过这个小游戏的开发, 不仅可以掌握 JS 的语法的应用,还可以学会 DOM 的使用, 更重要的是可以学习程序开发的业务逻辑,和项目开发过程,以及一些常用的游戏算法。
代码和课程来源(不是我做的): https://www.bilibili.com/video/BV1aE411K7Ga?from=search&seid=11376138008125697092
请访问 https://www.meitubk.com/my/demo2/
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>贪吃蛇桌面版小游戏</title> <link rel="icon" href="https://www.meitubk.com/my/avator.jpg" type="image/x-icon"/> <style type="text/css"> body{margin: 0; padding: 0;} div#main{margin: 40px;} input.btn{width: 100px;height: 40px;} span.gtitle{font-size: 25px;font-weight: bold;} span#gnum, span#glen, span#gspeed{color:red} </style> </head> <body> <div id="main"> <h1>贪吃蛇桌面版 -- 需 <span id="glen">1</span> 节 -- 第 <span id="gnum">1</span> 关 -- 速度间隔 <span id="gspeed">1</span></h1> <input class="btn" type="button" value="开始游戏" id="begin"/> <input class="btn" type="button" value="暂停游戏" id="pause"/> <input class="btn" type="button" value="我的博客" id="myblog"/> <input class="btn" type="button" value="视频教程" id="video"/> <script type="text/Javascript"> var main = document.getElementById("main"); //是否开启画布格子 var showcanvas = false; //地图对象构造方法 function Map(atom, xnum, ynum){ //原子、像素点 this.atom = atom; //地图宽度 this.xnum = xnum; //地图高度 this.ynum = ynum; this.canvas = null; //创建画布函数 this.create = function(){ this.canvas = document.createElement("div"); this.canvas.style.cssText = "position:absolute;top:170px;border:1px solid darkred;background:#FAFAFA;" this.canvas.style.width = this.atom * this.xnum + 'px'; this.canvas.style.height = this.atom * this.ynum + 'px'; main.appendChild(this.canvas); if(showcanvas){ for(var y=0; y<ynum; y++){ for(var x=0; x<xnum; x++){ var item = document.createElement("div"); item.style.cssText = "border:1px solid yellow;" item.style.width = this.atom + 'px'; item.style.height = this.atom + 'px'; item.style.backgroundColor = "green"; this.canvas.appendChild(item); item.style.position = "absolute"; item.style.left = x * this.atom + 'px'; item.style.top = y * this.atom + 'px'; } } } } } //创建食物函数 function Food(map){ this.width = map.atom; this.height = map.atom; this.bgColor = "rgb("+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+")"; //食物放在第几格 this.x = Math.floor(Math.random() * map.xnum); this.y = Math.floor(Math.random() * map.ynum); //设置食物的样式 this.flag = document.createElement("div"); this.flag.style.width = this.width + 'px'; this.flag.style.height = this.height + 'px'; this.flag.style.backgroundColor = this.bgColor; this.flag.style.position = "absolute"; this.flag.style.left = this.x * this.width + 'px'; this.flag.style.top = this.y * this.height + 'px'; map.canvas.appendChild(this.flag); } //创建蛇对象 function Snake(map){ //设置宽、高 this.width = map.atom; this.height = map.atom; //设置起始方向 this.direction = 'right'; this.body = [ {x: 2, y: 0}, //头 {x: 1, y: 0}, //身 {x: 0, y: 0} //尾 ] //显示蛇 this.display = function(){ for(var i=0;i < this.body.length; i++){ //当吃到食物时,要把 x 设置为 null if(this.body[i].x != null){ var item = document.createElement('div'); //将节点保存到一个状态变量中,以便以后删除使用 this.body[i].flag = item; //设置蛇的样式 item.style.width = this.width + 'px'; item.style.height = this.height + 'px'; item.style.backgroundColor = "rgb("+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+")"; item.style.position = "absolute"; item.style.left = this.body[i].x * this.width + 'px'; item.style.top = this.body[i].y * this.height + 'px'; map.canvas.appendChild(item); } } } //让蛇运动 this.run = function(){ for(var i=this.body.length-1; i>0 ; i--){ this.body[i].x = this.body[i-1].x; this.body[i].y = this.body[i-1].y; } //判断方向 switch(this.direction){ case "left": this.body[0].x -= 1; break; case "right": this.body[0].x += 1; break; case "up": this.body[0].y -=1; break; case "down": this.body[0].y += 1; break; } //判断蛇头吃到食物 if(this.body[0].x == food.x && this.body[0].y == food.y){ //蛇加一节,根据最后节点 this.body.push({x: null, y:null, flag: null}); //判断下一级别 if(this.body.length >= level.slength){ level.setlevel(); } map.canvas.removeChild(food.flag); food = new Food(map); } //判断是否出界 if(this.body[0].x < 0 || this.body[0].x > map.xnum - 1 || this.body[0].y < 0 || this.body[0].y > map.ynum - 1){ clearInterval(timer); alert("真笨呀,活活的撞墙死掉了!"); //重新开始游戏 restart(map, this, level); return false; } //判断是否吃到自己 for(var i=4; i<this.body.length;i++){ if(this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y){ alert("哎,把自己给咬死了!"); //重新开始游戏 restart(map, this, level); return false; } } for(var i=0; i < this.body.length; i++){ if(this.body[i].flag != null){ map.canvas.removeChild(this.body[i].flag); } } this.display(); } } //重新开始游戏 function restart(map, snake, level){ for(var i=0; i<snake.body.length;i++){ map.canvas.removeChild(snake.body[i].flag); } snake.body = [ {x: 2, y: 0}, //头 {x: 1, y: 0}, //身 {x: 0, y: 0} //尾 ] snake.direction = 'right'; snake.display(); map.canvas.removeChild(food.flag); food = new Food(map); level.num = 1; level.speed = 100; level.slength = 6; level = new Level(); level.display(); } //设置级别对象 function Level(){ this.num = 1; this.speed = 100; this.slength = 6; //通过目标长度 this.setlevel = function(){ this.num++; if(this.speed <= 20){ this.speed = 20; }else{ this.speed -= 20; } this.slength += 3; this.display(); start(); } this.display = function(){ document.getElementById("gnum").innerHTML = this.num; document.getElementById("gspeed").innerHTML = this.speed; document.getElementById("glen").innerHTML = this.slength; } } var level = new Level(); level.display(); var map = new Map(20, 40, 20); map.create() var food = new Food(map); var snake = new Snake(map); snake.display(); //键盘监听 window.Onkeydown= function(e){ var event = e || window.event; //上下左右 switch(event.keyCode){ case 38: if(snake.direction != "down"){ snake.direction = "up"; } break; case 40: if(snake.direction != "up"){ snake.direction = "down"; } break; case 37: if(snake.direction != "right"){ snake.direction = "left"; } break; case 39: if(snake.direction != "left"){ snake.direction = "right"; } break; } } function start(){ clearInterval(timer); timer = setInterval(function(){ snake.run(); }, level.speed); } var timer; document.getElementById('begin').Onclick=function(){ start(); } document.getElementById('pause').Onclick=function(){ clearInterval(timer); } document.getElementById('myblog').Onclick=function(){ location.href = "https://www.meitubk.com/"; } document.getElementById('video').Onclick=function(){ location.href = "https://www.bilibili.com/video/BV1aE411K7Ga"; } </script> </div> </body> </html> 1 zj1926 2020-04-25 12:34:48 +08:00 via iPhone 以前面试的时候我也写过一个 https://github.com/im6/vanilla-snake |
2 Liulang007 OP @zj1926 不错啊 |
3 ksedz 2020-04-25 13:29:03 +08:00 提个 bug:往左走的时候同时按下和右可能导致直接向右走或者把自己咬死 |
4 Liulang007 OP @ksedz 是不是按太快了,我这边不会这样 |
5 Liulang007 OP @ksedz 确实哈哈变得太长后会这样,之前都没发现= = |
6 jinmaoi 2020-04-26 10:14:49 +08:00 我也写过一个 C#版本的 https://www.seeull.com/archives/173.html |
7 不错,楼主还有自己的博客,厉害了! |