Змейка 2021

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск

Работу выполнили студенты гр. 3630103/00003 Корнелюк Алексей, Гришина Юлия.

Код программы[править]

Код программы на языке JavaScript:
  1 Описание кода JavaScript:
  2 
  3 <script type="text/javascript">
  4 
  5 	var isCrash = false; //если true, произошло столкновение
  6 	var IsClicked = false; //если true, за одно перемещение змейки нажата какая-то стрелка
  7 	//иначе, если нажать стрелку несколько раз, может случиться "столкновение" без реального столкновения
  8 	//связано с функцией, пропускающей несколько кадров (но не кликов) для замедления змейки
  9 	var canvas = document.getElementById('game');
 10 	var context = canvas.getContext('2d');
 11 	
 12 	var current = 3; //текущий счет, стартовый
 13 	
 14 	function reload () { //перегрузка страницы (кнопка «Play again»)
 15         window.location.reload();
 16     }
 17 	
 18 	function again(){ //запускается после Play again, воссоздает начальные условия
 19 		current = 3;
 20 		current1.innerHTML = current;
 21 		snake.x = 150;
 22 		snake.y = 150;
 23 		snake.cells = [];
 24 		snake.maxCells = 3;
 25 		snake.dx = grid;
 26 		snake.dy = 0;
 27 		//ставим яблоко в случайное место
 28 		apple.x = getRandomInt(0, 28) * grid;
 29 		apple.y = getRandomInt(0, 28) * grid;
 30 	}
 31 	
 32 	// генератор случайных чисел в заданном диапазоне
 33 	function getRandomInt(min, max) {
 34 	  return Math.floor(Math.random() * (max - min)) + min;
 35 	}
 36 		
 37 		
 38 	// размер одной клеточки — 25 пикселей
 39 	var grid = 25;
 40 	// переменная, которая отвечает за скорость змейки
 41 	var count = 0;
 42 
 43 	var snake = {
 44 	  // начальные координаты
 45 	  x: 150,
 46 	  y: 150,
 47 	  // скорость змейки — в каждом новом кадре змейка смещается по оси Х или У. 
 48 	  //изначально будет двигаться горизонтально, поэтому скорость по игреку равна нулю.
 49 	  dx: grid,
 50 	  dy: 0,
 51 	  // массив с координатами хвоста, изначально пустой
 52 	  cells: [],
 53 	  // стартовая длина змейки — 3 клеточки
 54 	  maxCells: 3
 55 	};
 56 	
 57 	var apple = {
 58 	  // начальные координаты яблока
 59 	  x: 300,
 60 	  y: 300
 61 	}
 62 	// игровой цикл — основной процесс, внутри которого будет всё происходить
 63 	function loop() {
 64 		// функция, которая замедляет скорость игры. 
 65 		// для этого она пропускает (stop-1) кадр, то есть срабатывает каждый кадр с номером stop
 66 		
 67 		if (!isCrash){ //но только в случае, если нет столкновения, иначе ничего не делать
 68 		requestAnimationFrame(loop);
 69 		}
 70 
 71 		//далее сам замедляющий механизм
 72 		if (current <= 15){ // замедляем до 7 кадров, не более
 73 		stop = 12 - Math.ceil(current / 3); 
 74 		}
 75 		count+= 1;
 76 
 77 		if (count < stop) {
 78 		return;
 79 		}	
 80 	  
 81 		// обнуляем переменную скорости кадров
 82 		count = 0;
 83 		// Очищаем игровое поле
 84 		context.clearRect(0, 0, canvas.width, canvas.height);
 85 		// Двигаем змейку с нужной скоростью
 86 		snake.x += snake.dx;
 87 		snake.y += snake.dy;
 88 		// Если змейка достигла края поля по — продолжаем её движение с противоположной стороны
 89 		if (snake.x < 0) {
 90 		  snake.x = canvas.width - grid; 
 91 		  } 
 92 		else if (snake.x >= canvas.width) {
 93 		  snake.x = 0; 
 94 		  }
 95 		if (snake.y < 0) {
 96 		  snake.y = canvas.height - grid; 
 97 		  } 
 98 		else if (snake.y >= canvas.height) {
 99 		  snake.y = 0; 
100 		  }
101 		  
102 		// Продолжаем двигаться в выбранном направлении. Голова всегда впереди, поэтому добавляем её координаты в начало массива, который отвечает за всю змейку.
103 		snake.cells.unshift({ x: snake.x, y: snake.y });
104 		// Сразу после этого удаляем последний элемент из массива змейки, потому что она движется и постоянно особождает клетки после себя
105 		if (snake.cells.length > snake.maxCells) {
106 		snake.cells.pop();
107 		}
108 		// Рисуем красное яблоко
109 		context.fillStyle = 'red';
110 		context.fillRect(apple.x, apple.y, grid - 1, grid - 1);
111 		// Одно движение змейки — один новый нарисованный квадратик 
112 		
113 		// Обрабатываем каждый элемент змейки
114 		snake.cells.forEach(function (cell, index) {
115 		// Чтобы создать эффект клеточек, делаем зелёные квадратики меньше на один пиксель, чтобы вокруг них образовалась чёрная граница
116 		context.fillStyle = 'green';
117 		context.fillRect(cell.x, cell.y, grid - 1, grid - 1);
118 
119 		// Если змейка добралась до яблока
120 		if (cell.x === apple.x && cell.y === apple.y) {
121 		current += 1;
122 		current1.innerHTML = current;
123 
124 		  // увеличиваем длину змейки
125 		  snake.maxCells++;
126 		  // Рисуем новое яблоко
127 		  // На поле умещается 28 ячеек
128 		  apple.x = getRandomInt(0, 28) * grid;
129 		  apple.y = getRandomInt(0, 28) * grid;
130 		  console.log(apple);
131 		}
132 		// Проверяем, не столкнулась ли змея сама с собой
133 		// Для этого перебираем весь массив и смотрим, есть ли у нас в массиве змейки две клетки с одинаковыми координатами 
134 		for (var i = index + 1; i < snake.cells.length; i++) {
135 		  // Если такие клетки есть — начинаем игру заново
136 		  if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
137 			xCrash = cell.x; //запомним координаты столкновения
138 			yCrash = cell.y;
139 			isCrash = true;
140 		  }
141 		}
142 		}); 
143 		
144 		if (isCrash){ //выделим место столкновения фиолетовым
145 			context.fillStyle = 'violet';
146 			context.fillRect(xCrash, yCrash, grid - 1, grid - 1);
147 			}
148 		isClicked = false; //обнулим счетчик кликов, чтобы можно было кликать в новом loop
149 		}  //the end of loop
150 		
151 		
152 		
153 	// Смотрим, какие нажимаются клавиши, и реагируем на них нужным образом
154 	document.addEventListener('keydown', function (e) {
155 	
156 	  // Стрелка влево
157 	  // Если нажата стрелка влево, и при этом змейка никуда не движется по горизонтали…
158 	  if (!isClicked){
159 		  if (e.which === 37 && snake.dx === 0) {
160 			// То даём ей движение по горизонтали, влево, а вертикальное — останавливаем
161 			// Та же самая логика будет и в остальных кнопках
162 			snake.dx = -grid;
163 			snake.dy = 0;
164 			isClicked = true; //больше в этом цикле кликать нельзя
165 		  }
166 		  // Стрелка вверх
167 		  else if (e.which === 38 && snake.dy === 0) {
168 			snake.dy = -grid;
169 			snake.dx = 0;
170 			isClicked = true;
171 		  }
172 		  // Стрелка вправо
173 		  else if (e.which === 39 && snake.dx === 0) {
174 			snake.dx = grid;
175 			snake.dy = 0;
176 			isClicked = true;
177 		  }
178 		  // Стрелка вниз
179 		  else if (e.which === 40 && snake.dy === 0) {
180 			snake.dy = grid;
181 			snake.dx = 0;
182 			isClicked = true;
183 		  }
184 	 }
185 	});
186 	requestAnimationFrame(loop); //запускаем бесконечный цикл
187 
188 </script>