一个初初初初级前端民工
主要是记录一下写过的东西,复习用
大佬们如果看到代码哪里不符合规范,或者有更好写法的,欢迎各位批评指正
十分感谢
实现一个贪吃蛇游戏需要几步?
1.有地图
2.有蛇
3.有食物
4.有游戏规则
----->面向对象的思想:
完整代码:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <style> 7 #map{ 8 width: 800px; 9 height: 600px; 10 background-color: #e6e6e6; 11 position: relative; 12 } 13 #talk{ 14 color: red; 15 position: absolute; 16 right: -20px; 17 top: 20px; 18 } 19 #scoreList{ 20 border: 1px solid cadetblue; 21 border-left: none; 22 box-shadow: 1px 1px 1px #A9A9A9; 23 width: 200px; 24 height: 400px; 25 overflow-y: auto; 26 position: absolute; 27 right: -200px; 28 } 29 #scoreList h3{ 30 text-align: center; 31 } 32 .name,.score{ 33 display: inline-block; 34 width: 45%; 35 text-align: center; 36 } 37 #start{ 38 position: absolute; 39 right: -200px; 40 bottom: 20px; 41 background-color: cornflowerblue; 42 color: white; 43 box-shadow: 2px 2px 3px #d6d6d6; 44 padding: 5px; 45 cursor: pointer; 46 } 47 </style> 48 </head> 49 <body> 50 <div id="map"> 51 <div id="scoreList"> 52 <h3>排行榜</h3> 53 <hr /> 54 <div id="container"></div> 55 </div> 56 <div id="start" onclick="start()">开始游戏</div> 57 </div> 58 <script> 59 var name = ‘‘; 60 var scoreList = []; 61 var result = {}; 62 function my$(id){ 63 return document.getElementById(id); 64 } 65 if(document.cookie){ 66 // listShow(); 67 } 68 function listShow(){ 69 var scoreStr=‘‘; 70 console.log(document.cookie); 71 var cookies = document.cookie.split(‘,‘); 72 for(var i = 0;i<cookies.length;i++){ 73 var item = JSON.parse(cookies[i]); 74 scoreStr += ‘<span class="name">‘+item.userName+‘</span><span class="score">‘+item.userScore+‘</span>‘; 75 } 76 my$(‘container‘).innerHTML = scoreStr; 77 } 78 //食物 79 (function(){ 80 var elements = []; 81 //用来存储食物【实例对象】的数组,在被蛇‘吃掉‘之后,可以通过数组来找到这个对象,进而实现在html中删除相应结点。 82 83 //食物的构造函数 84 function Food(x,y,width,height,color){ 85 this.x = x||0; //没有传入值时横坐标默认为0 86 this.y = y||0; 87 this.width = width||20; 88 this.height = height||20; 89 this.color = color||‘#a0c9fb‘; 90 } 91 //初始化,将设置好的属性值转化为样式 92 Food.prototype.init = function(map){ 93 remove(); //将之前的所有食物删除 94 var div = document.createElement(‘div‘); //创建一个div元素 95 div.style.position = ‘absolute‘; 96 div.style.width = this.width + ‘px‘; 97 div.style.height = this.height + ‘px‘; 98 div.style.backgroundColor = this.color; 99 this.x = parseInt(Math.random()*(map.offsetWidth/this.width))*this.width; 100 this.y = parseInt(Math.random()*(map.offsetHeight/this.height))*this.height; 101 div.style.left = this.x + ‘px‘; 102 div.style.top = this.y + ‘px‘; 103 map.appendChild(div); //将div添加到地图中 104 elements.push(div); //将div对象追加到数组当中 105 } 106 //删除食物 107 function remove(){ 108 for(var i=0;i<elements.length;i++){ 109 var ele = elements[i]; 110 ele.parentNode.removeChild(ele); 111 elements.splice(i,1); 112 } 113 } 114 window.Food = Food; //Food构造函数是在自调用函数中写的(目的是避免变量重名的问题),这里用Food构造函数来创建window对象的Food方法,使其可以在自调用函数之外被调用 115 }()); 116 //蛇 117 (function(){ 118 var elements = []; 119 function Snake(width,height,direction){ 120 this.width = width||20; 121 this.height = height||20; 122 this.direction = direction||‘right‘; 123 this.currentDir = this.direction; 124 this.score = 0; 125 this.body = [ 126 {x:3,y:2,color:‘red‘}, 127 {x:2,y:2,color:‘orange‘}, 128 {x:1,y:2,color:‘orange‘} 129 ] //蛇的每一块身体是一个div,通过它们坐标的改变来实现蛇的移动. 130 } 131 //初始化, 132 Snake.prototype.init = function(map){ 133 remove(); 134 for(var i=0;i<this.body.length;i++){ //body的每一块都有相应的坐标,颜色,宽高等,要通过循坏为每一块进行初始化 135 var obj = this.body[i]; 136 var div = document.createElement(‘div‘); 137 map.appendChild(div); 138 div.style.position = ‘absolute‘; 139 div.style.width = this.width + ‘px‘; 140 div.style.height = this.height + ‘px‘; 141 div.style.backgroundColor = obj.color; 142 div.style.left = obj.x*this.width + ‘px‘; 143 div.style.top = obj.y*this.height + ‘px‘; 144 elements.push(div); 145 } 146 } 147 //让蛇动起来(改变body每一块的坐标 每次调用整体动一下) 148 Snake.prototype.move = function(food,map){ //food参数在用来判断蛇是否吃掉食物时使用,map参数在对food进行初始化时使用 149 var i = this.body.length-1; //判断蛇的body中 最后一块的下标 150 for(;i>0;i--){ //Step1: 从最后一块开始到第二块的坐标值改变 151 this.body[i].x = this.body[i-1].x; 152 this.body[i].y = this.body[i-1].y; 153 } 154 switch(this.direction){ //Step2: 根据之前设定的方向来判断蛇头(第一块)的坐标变化 155 case ‘right‘:this.body[0].x+=1;break; 156 case ‘left‘:this.body[0].x-=1;break; 157 case ‘top‘:this.body[0].y-=1;break; 158 case ‘bottom‘:this.body[0].y+=1;break; 159 } 160 161 //判断是否吃到 蛇头的坐标 == 食物的坐标 即为吃到 162 var headX = this.body[0].x*this.width; 163 var headY = this.body[0].y*this.height; 164 if(headX == food.x && headY == food.y){ 165 var last = this.body[this.body.length-1]; 166 this.body.push({ 167 x:last.x, 168 y:last.y, 169 color:last.color 170 }); //在body最后增加一个对象,坐标等于最后一块的坐标即可 171 this.score = this.score+1; 172 food.init(map); //重新初始化一个食物出来 173 } 174 } 175 function remove(){ 176 var i = elements.length-1; 177 for(;i>=0;i--){ 178 elements[i].parentNode.removeChild(elements[i]); 179 elements.splice(i,1); 180 } 181 } 182 window.Snake = Snake; 183 }()); 184 //游戏 185 (function(){ 186 var that; //setInterval中的this是window,所以先定义一个that,将我们要使用的this对象存在that中,这样就可以在setInterval中使用了 187 function Game(map){ 188 that = this; //this是新的实例对象 189 this.food = new Food(); //创建food实例对象 190 this.snake = new Snake(); //创建snake实例对象 191 this.map = map; //将这些都作为game实例对象的属性 192 } 193 Game.prototype.init = function(){ 194 this.food.init(this.map); 195 this.snake.init(this.map); 196 this.run(); 197 this.bindKey(); 198 } 199 200 // 之前的snake.move是让蛇动一下,在这里放在setInterval中让它一直移动. 201 Game.prototype.run = function(){ 202 var timeId = setInterval(function(){ //timeId用于clearInterval 203 this.snake.move(this.food,this.map); //1.蛇的坐标改变 204 this.snake.init(this.map); //2.画出蛇 205 var xMax = this.map.offsetWidth/this.snake.width; //横坐标最大值 206 var yMax = this.map.offsetHeight/this.snake.height;//纵坐标最大值 207 var headX = this.snake.body[0].x; 208 var headY = this.snake.body[0].y; 209 if(headX>=xMax||headX<0||headY>=yMax||headY<0){ //判断是否撞墙 210 this.scoreFunction(timeId); 211 //尝试变色 212 // var i=0; 213 // setInterval(function(){ 214 // this.snake.body[i].color = ‘red‘; 215 // this.snake.init(); 216 // i++; 217 // }.bind(that),500) 218 //本来想写一个 蛇撞墙之后身体都变成红色的效果 emmm失败了 219 } 220 for(var i=1;i<this.snake.body.length;i++){ //判断是否撞自己 221 if(headX==this.snake.body[i].x&&headY==this.snake.body[i].y){ 222 this.scoreFunction(timeId); 223 } 224 } 225 }.bind(that),150); //bind的作用是将bind后面括号中的值作为函数中this的值 226 } 227 //分数结算函数 228 Game.prototype.scoreFunction = function(timeId){ 229 alert(‘啊啊啊wsl!!!!‘); 230 name = prompt(‘请问高手尊姓大名?‘); 231 result.userName = name; 232 result.userScore = this.snake.score; 233 scoreList.push(JSON.stringify(result)); 234 scoreList.sort(function(a,b){ 235 var a = JSON.parse(a); 236 var b = JSON.parse(b); 237 return b.userScore - a.userScore; 238 }) //排行榜排序功能 239 var cookieStr = JSON.stringify(scoreList); 240 cookieStr = cookieStr.replace(‘,‘,‘;‘); 241 document.cookie = ‘list = ‘+cookieStr; //尝试写在cookie中并没有成功 嘤 242 //将分数写入scoreList盒子 243 var scoreStr=‘‘; 244 for(var i in scoreList){ 245 var item = JSON.parse(scoreList[i]); 246 scoreStr += ‘<span class="name">‘+item.userName+‘</span><span class="score">‘+item.userScore+‘</span>‘; 247 } 248 my$(‘container‘).innerHTML = scoreStr; 249 clearInterval(timeId); //清除定时器 蛇停止移动 250 } 251 252 //按下键盘相应键,给蛇的direction赋值,需要注意的是蛇不可以掉头 253 Game.prototype.bindKey = function(){ 254 document.addEventListener(‘keydown‘,function(e){ 255 switch(e.keyCode){ 256 case 37: 257 if(this.snake.currentDir!=‘right‘){ 258 this.snake.direction=‘left‘; 259 this.snake.currentDir=‘left‘; 260 } 261 break; 262 case 38: 263 if(this.snake.currentDir!=‘bottom‘){ 264 this.snake.direction=‘top‘; 265 this.snake.currentDir=‘top‘; 266 } 267 break; 268 case 39: 269 if(this.snake.currentDir!=‘left‘){ 270 this.snake.direction=‘right‘; 271 this.snake.currentDir=‘right‘; 272 } 273 break; 274 case 40: 275 if(this.snake.currentDir!=‘top‘){ 276 this.snake.direction=‘bottom‘; 277 this.snake.currentDir=‘bottom‘; 278 } 279 break; 280 } 281 }.bind(that),false) 282 } 283 //把Game暴露给window 284 window.Game = Game; 285 }()) 286 //创建游戏对象并初始化 287 function start(){ 288 var game = new Game(my$(‘map‘)); 289 game.init(my$(‘map‘)); 290 } 291 292 </script> 293 </body> 294 </html>
1.自调用函数除了避免变量重名外还有其他的作用吗?
2.原型的作用是共享数据,节约内存空间。
3.setInterval 中的this是window。
4.bind的作用是将bind后面括号中的值作为函数中this的值。
原文:https://www.cnblogs.com/palover-0416/p/11358224.html