Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
− | Работу выполнили студенты гр. 3630103/00003 [[Корнелюк Алексей|Корнелюк Алексей]], [[Гришина Юлия|Гришина Юлия]].
| + | {{#widget:Iframe |url=https://jlg8457.github.io/Zmeyka2021/Snake.html |width=900 |height=900 |border=0 }} |
− | | |
− | {{#widget:Iframe |url=https://jlg8457.github.io/Zmeyka2021/Snake.html |width=1525 |height=900 |border=0 }} | |
− | | |
− | ==Код программы==
| |
− | <div class="mw-collapsible mw-collapsed">
| |
− | '''Код программы на языке JavaScript:''' <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="javascript" line start="1" enclose="div">
| |
− | | |
− | Описание кода JavaScript:
| |
− | | |
− | <script type="text/javascript">
| |
− | | |
− | var isCrash = false; //если true, произошло столкновение
| |
− | var IsClicked = false; //если true, за одно перемещение змейки нажата какая-то стрелка
| |
− | //иначе, если нажать стрелку несколько раз, может случиться "столкновение" без реального столкновения
| |
− | //связано с функцией, пропускающей несколько кадров (но не кликов) для замедления змейки
| |
− | var canvas = document.getElementById('game');
| |
− | var context = canvas.getContext('2d');
| |
− |
| |
− | var current = 3; //текущий счет, стартовый
| |
− |
| |
− | function reload () { //перегрузка страницы (кнопка «Play again»)
| |
− | window.location.reload();
| |
− | }
| |
− |
| |
− | function again(){ //запускается после Play again, воссоздает начальные условия
| |
− | current = 3;
| |
− | current1.innerHTML = current;
| |
− | snake.x = 150;
| |
− | snake.y = 150;
| |
− | snake.cells = [];
| |
− | snake.maxCells = 3;
| |
− | snake.dx = grid;
| |
− | snake.dy = 0;
| |
− | //ставим яблоко в случайное место
| |
− | apple.x = getRandomInt(0, 28) * grid;
| |
− | apple.y = getRandomInt(0, 28) * grid;
| |
− | }
| |
− |
| |
− | // генератор случайных чисел в заданном диапазоне
| |
− | function getRandomInt(min, max) {
| |
− | return Math.floor(Math.random() * (max - min)) + min;
| |
− | }
| |
− |
| |
− |
| |
− | // размер одной клеточки — 25 пикселей
| |
− | var grid = 25;
| |
− | // переменная, которая отвечает за скорость змейки
| |
− | var count = 0;
| |
− | | |
− | var snake = {
| |
− | // начальные координаты
| |
− | x: 150,
| |
− | y: 150,
| |
− | // скорость змейки — в каждом новом кадре змейка смещается по оси Х или У.
| |
− | //изначально будет двигаться горизонтально, поэтому скорость по игреку равна нулю.
| |
− | dx: grid,
| |
− | dy: 0,
| |
− | // массив с координатами хвоста, изначально пустой
| |
− | cells: [],
| |
− | // стартовая длина змейки — 3 клеточки
| |
− | maxCells: 3
| |
− | };
| |
− |
| |
− | var apple = {
| |
− | // начальные координаты яблока
| |
− | x: 300,
| |
− | y: 300
| |
− | }
| |
− | // игровой цикл — основной процесс, внутри которого будет всё происходить
| |
− | function loop() {
| |
− | // функция, которая замедляет скорость игры.
| |
− | // для этого она пропускает (stop-1) кадр, то есть срабатывает каждый кадр с номером stop
| |
− |
| |
− | if (!isCrash){ //но только в случае, если нет столкновения, иначе ничего не делать
| |
− | requestAnimationFrame(loop);
| |
− | }
| |
− | | |
− | //далее сам замедляющий механизм
| |
− | if (current <= 15){ // замедляем до 7 кадров, не более
| |
− | stop = 12 - Math.ceil(current / 3);
| |
− | }
| |
− | count+= 1;
| |
− | | |
− | if (count < stop) {
| |
− | return;
| |
− | }
| |
− |
| |
− | // обнуляем переменную скорости кадров
| |
− | count = 0;
| |
− | // Очищаем игровое поле
| |
− | context.clearRect(0, 0, canvas.width, canvas.height);
| |
− | // Двигаем змейку с нужной скоростью
| |
− | snake.x += snake.dx;
| |
− | snake.y += snake.dy;
| |
− | // Если змейка достигла края поля по — продолжаем её движение с противоположной стороны
| |
− | if (snake.x < 0) {
| |
− | snake.x = canvas.width - grid;
| |
− | }
| |
− | else if (snake.x >= canvas.width) {
| |
− | snake.x = 0;
| |
− | }
| |
− | if (snake.y < 0) {
| |
− | snake.y = canvas.height - grid;
| |
− | }
| |
− | else if (snake.y >= canvas.height) {
| |
− | snake.y = 0;
| |
− | }
| |
− |
| |
− | // Продолжаем двигаться в выбранном направлении. Голова всегда впереди, поэтому добавляем её координаты в начало массива, который отвечает за всю змейку.
| |
− | snake.cells.unshift({ x: snake.x, y: snake.y });
| |
− | // Сразу после этого удаляем последний элемент из массива змейки, потому что она движется и постоянно особождает клетки после себя
| |
− | if (snake.cells.length > snake.maxCells) {
| |
− | snake.cells.pop();
| |
− | }
| |
− | // Рисуем красное яблоко
| |
− | context.fillStyle = 'red';
| |
− | context.fillRect(apple.x, apple.y, grid - 1, grid - 1);
| |
− | // Одно движение змейки — один новый нарисованный квадратик
| |
− |
| |
− | // Обрабатываем каждый элемент змейки
| |
− | snake.cells.forEach(function (cell, index) {
| |
− | // Чтобы создать эффект клеточек, делаем зелёные квадратики меньше на один пиксель, чтобы вокруг них образовалась чёрная граница
| |
− | context.fillStyle = 'green';
| |
− | context.fillRect(cell.x, cell.y, grid - 1, grid - 1);
| |
− | | |
− | // Если змейка добралась до яблока
| |
− | if (cell.x === apple.x && cell.y === apple.y) {
| |
− | current += 1;
| |
− | current1.innerHTML = current;
| |
− | | |
− | // увеличиваем длину змейки
| |
− | snake.maxCells++;
| |
− | // Рисуем новое яблоко
| |
− | // На поле умещается 28 ячеек
| |
− | apple.x = getRandomInt(0, 28) * grid;
| |
− | apple.y = getRandomInt(0, 28) * grid;
| |
− | console.log(apple);
| |
− | }
| |
− | // Проверяем, не столкнулась ли змея сама с собой
| |
− | // Для этого перебираем весь массив и смотрим, есть ли у нас в массиве змейки две клетки с одинаковыми координатами
| |
− | for (var i = index + 1; i < snake.cells.length; i++) {
| |
− | // Если такие клетки есть — начинаем игру заново
| |
− | if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
| |
− | xCrash = cell.x; //запомним координаты столкновения
| |
− | yCrash = cell.y;
| |
− | isCrash = true;
| |
− | }
| |
− | }
| |
− | });
| |
− |
| |
− | if (isCrash){ //выделим место столкновения фиолетовым
| |
− | context.fillStyle = 'violet';
| |
− | context.fillRect(xCrash, yCrash, grid - 1, grid - 1);
| |
− | }
| |
− | isClicked = false; //обнулим счетчик кликов, чтобы можно было кликать в новом loop
| |
− | } //the end of loop
| |
− |
| |
− |
| |
− |
| |
− | // Смотрим, какие нажимаются клавиши, и реагируем на них нужным образом
| |
− | document.addEventListener('keydown', function (e) {
| |
− |
| |
− | // Стрелка влево
| |
− | // Если нажата стрелка влево, и при этом змейка никуда не движется по горизонтали…
| |
− | if (!isClicked){
| |
− | if (e.which === 37 && snake.dx === 0) {
| |
− | // То даём ей движение по горизонтали, влево, а вертикальное — останавливаем
| |
− | // Та же самая логика будет и в остальных кнопках
| |
− | snake.dx = -grid;
| |
− | snake.dy = 0;
| |
− | isClicked = true; //больше в этом цикле кликать нельзя
| |
− | }
| |
− | // Стрелка вверх
| |
− | else if (e.which === 38 && snake.dy === 0) {
| |
− | snake.dy = -grid;
| |
− | snake.dx = 0;
| |
− | isClicked = true;
| |
− | }
| |
− | // Стрелка вправо
| |
− | else if (e.which === 39 && snake.dx === 0) {
| |
− | snake.dx = grid;
| |
− | snake.dy = 0;
| |
− | isClicked = true;
| |
− | }
| |
− | // Стрелка вниз
| |
− | else if (e.which === 40 && snake.dy === 0) {
| |
− | snake.dy = grid;
| |
− | snake.dx = 0;
| |
− | isClicked = true;
| |
− | }
| |
− | }
| |
− | });
| |
− | requestAnimationFrame(loop); //запускаем бесконечный цикл
| |
− | | |
− | </script>
| |
− | </syntaxhighlight>
| |
− | </div>
| |