jquery实现简单的贪吃蛇游戏

2017年12月4日21:28:14 发表评论 17

贪吃蛇游戏,我想大家以前都玩过吧,我还记得我第一次玩贪吃蛇的时候用的是诺基亚,当时也是我玩的最刺激的一个游戏,我最喜欢玩快速度的蛇,很有刺激的感觉,现在我长大了,试着用学习的前端语言Jquery来实现贪吃蛇游戏,我还记得当时我看的那个帖子,我现在就给大家介绍下具体的实现思路。

 

构思游戏

  1. 需要一个对象:蛇本身
  2. 如何控制蛇移动:用定时器周期性移动
  3. 蛇的方向控制:全局定义一个对象,分别是上下左右
  4. 碰撞检测:一、吃到食物;二、碰到自己身体;三、碰到边界

 

前期准备

我们首先要搭建一个蛇的活动场景,我们用table,然后定两种样式,.body表示蛇身体,.food代表食物。

  1. <style type="text/css">
  2. #pannel table{
  3. border-collapse:collapse;
  4. }
  5. #pannel td{
  6. width10px;
  7. height10px;
  8. border1px solid #000;
  9. }
  10. #pannel td.food{
  11. backgroundgreen;
  12. }
  13. #pannel td.body{
  14. background#f60;
  15. }
  16. </style>
  17. <div id="pannel">
  18. </div>
  19. <select name="" id="palSize">
  20. <option value="10">10*10</option>
  21. <option value="20">20*20</option>
  22. <option value="40">30*30</option>
  23. </select>
  24. <select name="" id="palSpeed">
  25. <option value="500">速度-慢</option>
  26. <option value="250">速度-正常</option>
  27. <option value="100">速度-快</option>
  28. </select>
  29. <button id="startBtn">开始</button>
  30. var settings = {
  31.   // pannel面板的长度
  32.   pannelSize: 10,
  33.   // 贪吃蛇移动的速度
  34.   speed: 500,
  35.   // 贪吃蛇工作线程
  36.   workThread: null,
  37. };
  38. function setPannel(size){
  39.   var content = [];
  40.   content.push('<table>');
  41.   for(let i=0;i<size;i++){
  42.     content.push('<tr>');
  43.     for(let j=0;j<size;j++){
  44.       content.push('<td class="td_'+i+'_'+j+'"></td>');
  45.     }
  46.     content.push('</tr>');
  47.   }
  48.   content.push('</table>');
  49.   $('#pannel').html(content.join(''));
  50. }
  51. setPannel(settings.pannelSize);

我们定义一个全局的settings用来存放全局的变量,幕布大小,蛇移动速度等,最终的效果就是下图这样的:

 

jquery实现简单的贪吃蛇游戏

接下来我们要做的是方向上的移动、构建食物对象和贪吃蛇对象,写一个移动处理函数,再做碰撞检测函数,然后绘制出来,最终我们我设定游戏控制器来控制游戏的开始暂停各方面的东西。

最终的代码是这样的:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>jQuery实现贪吃蛇效果</title>
  6. <style type="text/css">
  7. #pannel table{
  8. border-collapse:collapse;
  9. margin-bottom10px;
  10. }
  11. #pannel td{
  12. width10px;
  13. height10px;
  14. border1px solid #000;
  15. }
  16. #pannel td.food{
  17. backgroundgreen;
  18. }
  19. #pannel td.body{
  20. background#f60;
  21. }
  22. </style>
  23. </head>
  24. <body>
  25. <div id="pannel">
  26. </div>
  27. <select name="" id="palSize">
  28. <option value="10">10*10</option>
  29. <option value="20">20*20</option>
  30. <option value="40">30*30</option>
  31. </select>
  32. <select name="" id="palSpeed">
  33. <option value="500">速度-慢</option>
  34. <option value="250">速度-正常</option>
  35. <option value="100">速度-快</option>
  36. </select>
  37. <button id="startBtn">开始</button>
  38. </body>
  39. <script type="text/javascript" src="http://www.zcbboke.com/js/jquery-3.2.1.min.js"></script>
  40. <script type="text/javascript">
  41. var settings = {
  42. pannelSize: 10,
  43. speed: 500,
  44. // 贪吃蛇工作线程
  45. workThread: null,
  46. };
  47. var Direction = {
  48. UP: 38,
  49. DOWN: 40,
  50. LEFT: 37,
  51. RIGHT: 39,
  52. // W: 87,
  53. // S: 83,
  54. // A: 65,
  55. // D: 68,
  56. };
  57. function setPannel(size){
  58. var content = [];
  59. content.push('<table>');
  60. for(let i=0;i<size;i++){
  61. content.push('<tr>');
  62. for(let j=0;j<size;j++){
  63. content.push('<td class="td_'+i+'_'+j+'"></td>');
  64. }
  65. content.push('</tr>');
  66. }
  67. content.push('</table>');
  68. $('#pannel').html(content.join(''));
  69. }
  70. function Snake(myFood){
  71. this.body = [];
  72. this.dir = Direction.DOWN;
  73. this.food = myFood;
  74. this.Over = function(){
  75. clearInterval(settings.workThread);
  76. console.log('Game Over');
  77. };
  78. this.Create = function(){
  79. let isOk = true;
  80. while(isOk){
  81. let x = parseInt(Math.random()*(settings.pannelSize - 2)) + 1,
  82. y = parseInt(Math.random()*(settings.pannelSize - 2)) + 1;
  83. console.log(x,y)
  84. if(!$('.td_'+x+'_'+y).hasClass('food')){
  85. isOk = false;
  86. let pos = new Position(x, y);
  87. this.handleDot(true, pos, 'body')
  88. this.body.push(pos);
  89. }
  90. }
  91. };
  92. this.Move = function(){
  93. let oldHead = Object.assign(new Position(), this.body[0]),
  94. oldTail = Object.assign(new Position(), this.body[this.body.length - 1]),
  95. newHead = Object.assign(new Position(), oldHead);
  96. switch(this.dir){
  97. case Direction.UP:
  98. newHead.X = newHead.X - 1;
  99. break;
  100. case Direction.DOWN:
  101. newHead.X = newHead.X + 1;
  102. break;
  103. case Direction.LEFT:
  104. newHead.Y = newHead.Y - 1;
  105. break;
  106. case Direction.RIGHT:
  107. newHead.Y = newHead.Y + 1;
  108. break;
  109. default:
  110. break;
  111. }
  112. this.body.unshift(newHead);
  113. this.body.pop();
  114. if(this.eatFood()){
  115. this.body.push(oldTail);
  116. this.food.Create();
  117. this.rePaint(true, newHead, oldTail);
  118. } else if(this.konckWall() || this.konckBody()) {
  119. this.Over();
  120. } else {
  121. this.rePaint(false, newHead, oldTail);
  122. }
  123. };
  124. this.eatFood = function(){
  125. let newHead = this.body[0];
  126. if(newHead.X == this.food.pos.X && newHead.Y == this.food.pos.Y){
  127. return true;
  128. } else {
  129. return false;
  130. }
  131. };
  132. this.konckWall = function(){
  133. let newHead = this.body[0];
  134. if(newHead.X == -1 || newHead.Y == -1 || newHead.X == settings.pannelSize || newHead.Y == settings.pannelSize){
  135. return true;
  136. } else {
  137. return false;
  138. }
  139. };
  140. this.konckBody = function(){
  141. let newHead = this.body[0],
  142. flag = false;
  143. this.body.map(function(elem, index){
  144. if(index == 0)
  145. return;
  146. if(elem.X == newHead.X && elem.Y == newHead.Y){
  147. flag = true;
  148. }
  149. });
  150. return flag;
  151. };
  152. this.rePaint = function(isEatFood, newHead, oldTail){
  153. if(isEatFood){
  154. // 加上头
  155. this.handleDot(true, newHead, 'body');
  156. } else {
  157. // 加头
  158. this.handleDot(true, newHead, 'body');
  159. // 去尾
  160. this.handleDot(false, oldTail, 'body');
  161. }
  162. };
  163. this.handleDot = function(flag, dot, className){
  164. if(flag){
  165. $('.td_'+dot.X+'_'+dot.Y).addClass(className);
  166. } else {
  167. $('.td_'+dot.X+'_'+dot.Y).removeClass(className);
  168. }
  169. };
  170. }
  171. function Food(){
  172. this.pos = null;
  173. this.Create = function(){
  174. if(this.pos){
  175. this.handleDot(false, this.pos, 'food');
  176. }
  177. let isOk = true;
  178. while(isOk){
  179. let x = parseInt(Math.random()*settings.pannelSize),
  180. y = parseInt(Math.random()*settings.pannelSize);
  181. if(!$('.td_'+x+'_'+y).hasClass('body')){
  182. isOk = false;
  183. let pos = new Position(x, y);
  184. this.handleDot(true, pos, 'food');
  185. this.pos = pos;
  186. }
  187. }
  188. },
  189. this.handleDot = function(flag, dot, className){
  190. if(flag){
  191. $('.td_'+dot.X+'_'+dot.Y).addClass(className);
  192. } else {
  193. $('.td_'+dot.X+'_'+dot.Y).removeClass(className);
  194. }
  195. }
  196. }
  197. function Position(x,y){
  198. // 距离X轴长度,取值范围0~pannelSize-1
  199. this.X = x || 0;
  200. // 距离Y轴长度,取值范围0~pannelSize-1
  201. this.Y = y || 0;
  202. }
  203. function Control(){
  204. this.snake = null;
  205. this.bindClick = function(){
  206. var that = this;
  207. $(document).on('keydown', function(e){
  208. if(!that.snake)
  209. return;
  210. var canChangrDir = true;
  211. switch(e.keyCode){
  212. case Direction.DOWN:
  213. if(that.snake.dir == Direction.UP){
  214. canChangrDir = false;
  215. }
  216. break;
  217. case Direction.UP:
  218. if(that.snake.dir == Direction.DOWN){
  219. canChangrDir = false;
  220. }
  221. break;
  222. case Direction.LEFT:
  223. if(that.snake.dir == Direction.RIGHT){
  224. canChangrDir = false;
  225. }
  226. break;
  227. case Direction.RIGHT:
  228. if(that.snake.dir == Direction.LEFT){
  229. canChangrDir = false;
  230. }
  231. break;
  232. default:
  233. canChangrDir = false;
  234. break;
  235. }
  236. if(canChangrDir){
  237. that.snake.dir = e.keyCode;
  238. }
  239. });
  240. $('#palSize').on('change',function(){
  241. settings.pannelSize = $(this).val();
  242. setPannel(settings.pannelSize);
  243. });
  244. $('#palSpeed').on('change',function(){
  245. settings.speed = $(this).val();
  246. });
  247. $('#startBtn').on('click',function(){
  248. $('.food').removeClass('food');
  249. $('.body').removeClass('body');
  250. that.startGame();
  251. });
  252. };
  253. this.init = function(){
  254. this.bindClick();
  255. setPannel(settings.pannelSize);
  256. };
  257. this.startGame = function(){
  258. var food = new Food();
  259. food.Create();
  260. var snake = new Snake(food);
  261. snake.Create();
  262. this.snake =snake;
  263. settings.workThread = setInterval(function(){
  264. snake.Move();
  265. },settings.speed);
  266. }
  267. this.init();
  268. }
  269. new Control();
  270. </script>
  271. </html>

文件下载

广告也精彩
猿梦

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: