canvas贪吃蛇游戏

用canvas做了一个贪吃蛇小游戏

 

开始界面
开始界面

 

 

游戏界面
游戏界面

 

 

结束界面
结束界面

 

  1. <!DOCTYPE html> 
  2. <html> 
  3. <head> 
  4. <meta charset="UTF-8"> 
  5. <title>贪吃蛇</title> 
  6. <style> 
  7. body{background: #666;text-align: center;} 
  8. canvas{margin: 50px auto 0;/*border: 2px solid green;*/} 
  9. </style> 
  10. </head> 
  11. <body> 
  12. <canvas id="snake" width="800" height="500"></canvas> 
  13. <script> 
  14. /** 
  15. * Created by linyufeng on 2017/7/26. 
  16. */ 
  17. var width = 800;//游戏宽度 
  18. var height = 500;//游戏高度 
  19. var flag = false;//控制游戏是否结束 
  20. var snakeArr;//存放身体坐标 
  21. var food;//指定食物 
  22. var direction;//运动方向 
  23. var snakeMove;//自动运动(定时器) 
  24. var size = 20;//食物和蛇大小 
  25. var speed = 1000;//运动速度 
  26. var highScore = 0;//最高分数 
  27. var snake = document.getElementById('snake').getContext('2d');//获取canvas对象 
  28. //重置游戏 
  29. function reset(){ 
  30. flag = true;//开始游戏 
  31. snakeArr = [{x:size*10,y:size*10},{x:size*10,y:size*10+size},{x:size*10,y:size*10+2*size}];//生成身体 
  32. food = createFood();//随机食物 
  33. direction = 39;//指定默认运动方向: 37左 38上 39右 40下 
  34. } 
  35. //开始游戏 
  36. function start(){ 
  37. drawRect({x:0,y:0,w:width,h:width}); 
  38. drawText({text:'贪 吃 蛇',x:width/2,y:150,font:'64px 微软雅黑'}); 
  39. drawText({text:'开 始 游 戏',x:width/2,y:250,font:'34px 微软雅黑'}); 
  40. drawText({text:'最高分数: '+highScore,x:width/2,y:350,font:'24px 微软雅黑'}); 
  41. drawText({text:'按Enter键开始游戏',x:width/2,y:width/2,font:'24px 微软雅黑'}); 
  42. } 
  43. //结束游戏 
  44. function end(){ 
  45. clearInterval(snakeMove); 
  46. flag = false; 
  47. var score = snakeArr.length-3; 
  48. highScore = highScore<score?score:highScore; 
  49. drawText({text:'游 戏 结 束',x:width/2,y:150,font:'64px 微软雅黑'}); 
  50. drawText({text:'游戏分数: '+score,x:width/2,y:250,font:'34px 微软雅黑'}); 
  51. drawText({text:'最高分数: '+highScore,x:width/2,y:350,font:'24px 微软雅黑'}); 
  52. drawText({text:'按Enter键开始游戏',x:width/2,y:width/2,font:'24px 微软雅黑'}); 
  53. } 
  54. //初始化游戏 
  55. function init(){ 
  56. reset(); 
  57. draw(); 
  58. snakeMove = setInterval(function(){ 
  59. update(direction); 
  60. },speed); 
  61. } 
  62. //画游戏界面 
  63. function draw(){ 
  64. snake.clearRect(0,0,width,height);//清屏 
  65. drawRect({x:0,y:0,w:width,h:width});//画背景 
  66. drawSnake(snakeArr);//画蛇 
  67. drawCircle(food.x,food.y);//画食物 
  68. drawText({text:'分数: '+(snakeArr.length-3),x:10,y:10,font:'24px 微软雅黑',baseline:'top',align:'left'});//画分数 
  69. } 
  70. //随机产生食物 
  71. function createFood(){ 
  72. var x = parseInt(Math.random()*(width/size))*size; 
  73. var y = parseInt(Math.random()*(height/size))*size; 
  74. return {x:x, y:y}; 
  75. } 
  76. //身体运动和碰撞检测 
  77. function update(direction){ 
  78. var head = snakeArr[0]; 
  79. if(!flag){ 
  80. return;//结束游戏 
  81. } 
  82. var newHead = {}; 
  83. if(direction == 37){//左 
  84. newHead = {x:head.x-size,y:head.y}; 
  85. }else if(direction == 38){//上 
  86. newHead = {x:head.x,y:head.y-size}; 
  87. }else if(direction == 39){//右 
  88. newHead = {x:head.x+size,y:head.y}; 
  89. }else if(direction == 40){//下 
  90. newHead = {x:head.x,y:head.y+size}; 
  91. } 
  92. //身体自身碰撞检测 
  93. for (var i = 0; i < snakeArr.length; i++) { 
  94. var snake = snakeArr[i]; 
  95. if(snake.x==newHead.x && snake.y==newHead.y){ 
  96. end(); 
  97. return; 
  98. } 
  99. } 
  100. //墙壁碰撞检测 
  101. if(head.x<=0 || head.x>=width || head.y<=0 || head.y>=height){ 
  102. end(); 
  103. return; 
  104. }else{ 
  105. //食物碰撞检测 
  106. if(newHead.x==food.x && newHead.y==food.y){ 
  107. snakeArr.unshift(food);//添身体 
  108. food = createFood(); 
  109. }else{ 
  110. snakeArr.unshift(newHead);//添头 
  111. snakeArr.pop();//去尾 
  112. } 
  113. draw(); 
  114. } 
  115. } 
  116. //游戏开始画面 
  117. start(); 
  118. //绑定鼠标控制事件 
  119. document.addEventListener('keydown',function(e){ 
  120. e.preventDefault(); 
  121. /******************************************* 
  122. * 37 Left(左箭头) 
  123. * 38 Up(上箭头) 
  124. * 39 Right(右箭头) 
  125. * 40 Down(下箭头) 
  126. * ******************************************/ 
  127. var code = e.keyCode || e.which; 
  128. /*************************************** 
  129. * 只对上下左右键和Enter键生效,屏蔽其他键! 
  130. * *************************************/ 
  131. if(code==37 || code==38 || code==39 || code==40 || code==13){ 
  132. /******************************************** 
  133. * 如果游戏未开始或者已结束,此时按下Enter键开始游戏 
  134. * ******************************************/ 
  135. if(code==13){ 
  136. if(flag==false){ 
  137. init(); 
  138. } 
  139. }else{ 
  140. /****************************************** 
  141. * 如果蛇的运动方向是上,那么不能向下运动 
  142. * 如果蛇的运动方向是下,那么不能向上运动 
  143. * 如果蛇的运动方向是左,那么不能向右运动 
  144. * 如果蛇的运动方向是右,那么不能向左运动 
  145. * ****************************************/ 
  146. if(Math.abs(code-direction)==2){ 
  147. return;//不允许这种移动方式 
  148. } 
  149. direction = code; 
  150. update(direction); 
  151. } 
  152. } 
  153. }); 
  154. /****************************************************************** 
  155. * 封装公共方法: 
  156. * 1. 画矩形 
  157. * 2. 写文字 
  158. * 3. 画小方块 
  159. * ****************************************************************/ 
  160. /** 
  161. * @func: 画矩形 
  162. * @params: {x} x坐标 
  163. * @params: {y} y坐标 
  164. * @params: {w} 宽度 
  165. * @params: {h} 高度 
  166. * @color: {color} 颜色 
  167. * */ 
  168. function drawRect(option){ 
  169. /************************************************************** 
  170. * 说明:canvas对象应该从外部传入,但是为了避免每次调用方法时都要传入,就固定写死了! 
  171. * ************************************************************/ 
  172. snake.beginPath(); 
  173. snake.fillStyle = option.color || '#000'; 
  174. snake.fillRect(option.x,option.y,option.w,option.h); 
  175. snake.closePath(); 
  176. } 
  177. /** 
  178. * @func: 写文字 
  179. * @params: {x} x坐标 
  180. * @params: {y} y坐标 
  181. * @params: {w} 宽度 
  182. * @params: {h} 高度 
  183. * @params: {color} 颜色 
  184. * @params: {baseline} 文字上下对齐方式 
  185. * @params: {align} 文字左右对齐方式 
  186. * */ 
  187. function drawText(option){ 
  188. snake.beginPath(); 
  189. snake.fillStyle = option.color || '#fff'; 
  190. snake.fontFamily = '微软雅黑'; 
  191. snake.font = option.font; 
  192. snake.textBaseline = option.baseline || 'middle'; 
  193. snake.textAlign = option.align || 'center'; 
  194. snake.fillText(option.text,option.x,option.y); 
  195. snake.closePath(); 
  196. } 
  197. /** 
  198. * @func: 画小方块 
  199. * @params: {x} x坐标 
  200. * @params: {y} y坐标 
  201. * */ 
  202. function drawSquare(x,y){ 
  203. snake.beginPath(); 
  204. snake.fillStyle = '#fff'; 
  205. snake.fillRect(x+1,y+1,size-2,size-2); 
  206. snake.closePath(); 
  207. } 
  208. /** 
  209. * @func: 画食物 
  210. * @params: {x} x坐标 
  211. * @params: {y} y坐标 
  212. * */ 
  213. function drawCircle(x,y){ 
  214. snake.beginPath(); 
  215. snake.arc(x+size/2, y+size/2, size/2, 0, Math.PI*2,true); 
  216. snake.fillStyle = '#0f0'; 
  217. snake.fill(); 
  218. snake.closePath(); 
  219. } 
  220. /** 
  221. * @func: 画蛇 
  222. * @params: {arr} 蛇身体坐标 
  223. * */ 
  224. function drawSnake(arr){ 
  225. for (var i = 0; i < arr.length; i++) { 
  226. var snake = arr[i]; 
  227. drawSquare(snake.x,snake.y) 
  228. } 
  229. } 
  230.  
  231. </script> 
  232. </body> 
  233. </html> 
posted @ 2018-09-06 20:33  林宇风  阅读(220)  评论(0编辑  收藏  举报