Задача
Изучая условные операторы, вы делали маленький проект "Дом с привидениями", используя ввод/вывод данных при помощи alert() и prompt(). Сделайте похожий проект, используя canvas и выбор номера двери кликом по ней.Видео с готовым результатом
Ход работы
1. Создание и подготовка проекта.
1.1. Создайте в вашей папке с сайтами новую папку "3 House with ghosts" и в ней создайте такую структуру файлов и папок:--js
----script.js
--css
----style.css
--index.html
1.2. Заполните файлы базовым содержимым:
Файл разметки index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/style.css">
<title>Дом с привидениями</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="js/script.js"></script>
</body>
</html>
Файл со стилями style.css
body, html {
margin:0;
width: 100%;
height: 100%;
background-color: #2d2d2d;
}
Файл со скриптами script.js
const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let WIDTH = canvas.width;
let HEIGHT = canvas.height;
const ctx = canvas.getContext('2d');
Обратите внимание, что мы начали использовать константы const. В отличии от переменных let, константы – это то, что не изменяется при выполнении программы, в них нельзя присвоить новые значения.
2. Отрисовка текста об игре и двери
2.1. Добавим текст на холст, чтобы пользователю было понятно, что ему делать.ctx.font = "20px Arial";
ctx.textBaseline = "top";
ctx.fillStyle = "White";
ctx.fillText("Перед вами 3 двери. За одной из них привидение. Кликните на дверь, за которой привидения нет.",20,20);
ctx.fillText("Если вам повезёт, вы заработаете очки и пройдёте дальше. Если нет - привидение вас съест!",20,44);
2.2. Отрисуем первую дверь.
ctx.fillStyle = "Green";
ctx.fillRect(100,100,100,240);
ctx.beginPath();
ctx.fillStyle = "White";
ctx.arc(180,220,10,0,2*Math.PI);
ctx.closePath();
ctx.fill();
Запустите программу, у вас должна быть отрисована дверь и текст приветствия.
2.3. Посмотрите ещё раз на видео. Обратите внимание, что все 3 двери очень похожи друг на друга. У них отличаются только координаты и цвет двери и ручки. Если мы видим похожие объекты, это означает, что для их создания необходимо использовать функцию. Создадим её:
// в качестве параметров функции используем координаты x, y, цвет двери colorDoor и цвет дверной ручки colorDoorHandle
const drawDoor = function(x,y,colorDoor,colorDoorHandle) {
ctx.fillStyle = colorDoor;
ctx.fillRect(x,y,100,240);
ctx.beginPath();
ctx.fillStyle = colorDoorHandle;
ctx.arc(x+80,y+120,10,0,2*Math.PI);
ctx.closePath();
ctx.fill();
}
2.4. Теперь чтобы создать дверь нам нужно просто вызвать эту функцию несколько раз с разными параметрами.
ctx.fill();
}
drawDoor(100,100,"Red","Black");
drawDoor(240,100,"Green","White");
drawDoor(380,100,"Blue","Orange");
3. Кликабельность дверей
3.1. Добавим событие клика мышки по холсту. Добудем координаты курсора мышки при клике.canvas.onmousedown = function(e){
let mouseX = e.clientX;
let mouseY = e.clientY;
}
3.2. При каждом клике будет случайно генерироваться число – номер двери, за которым может оказаться привидение! Мы добудем случайное число от 1 до 3.
let mouseY = e.clientY;
let ghostChoose = Math.ceil(Math.random()*3);
3.3. Теперь нужно проверить, в какую именно дверь тыкнул игрок. Добавим переменную playerChoose, которая будет хранить в себе номер двери. Далее будем проверять область клика на попадание по той или
let ghostChoose = Math.ceil(Math.random()*3);
let playerChoose = null;
if(mouseX>=100 && mouseX<=200 && mouseY >=100 && mouseY<=340) {
playerChoose = 1;
} else if(mouseX>=240 && mouseX<=340 && mouseY >=100 && mouseY<=340) {
playerChoose = 2;
} else if(mouseX>=380 && mouseX<=480 && mouseY >=100 && mouseY<=340) {
playerChoose = 3;
}
3.4. Совершим проверку: если игрок тыкнул на дверь, номер которой равен номеру двери привидения, то выведем в консоль сообщение о проигрыше. Иначе – сообщение о выигрыше.
if(playerChoose === ghostChoose) {
console.log("Вы проиграли");
} else if (playerChoose!==ghostChoose && playerChoose !== null) {
console.log("Вам повезло, играете дальше");
}
3.5*. Ответьте на вопрос: зачем мы проверяем условие playerChoose !== null ?
4. Программируем путь выигрыша
После того, как игрок кликает на дверь, где нет привидения, его очки должны увеличиться и это должно отобразиться на экране.4.1. Добавим глобальную переменную score, в которой будем хранить счёт игры. При запуске программы её следует обнулять. Все глобальные переменные мы обычно храним вначале программы.
const ctx = canvas.getContext('2d');
let score = 0;
ctx.font = "20px Arial";
4.2. Напишем функцию drawScore(), которая будет отвечать за вывод количества очков на экране. Вызываем её после отрисовки дверей.
ctx.fill()
}
const drawScore = function() {
ctx.font = "20px Arial";
ctx.textBaseline = "top";
ctx.fillStyle = "green";
ctx.fillText("Счёт: "+score,100,360);
}
drawDoor(100,100,"Red","Black");
drawDoor(240,100,"Green","White");
drawDoor(380,100,"Blue","Orange");
drawScore();
4.3. Изменим команды в выигрышном варианте:
} else if (playerChoose!==ghostChoose && playerChoose !== null) {
score++;
drawScore();
}
4.4. Запустите программу. При успешной ситуации, вылезает один баг: надпись с количеством очков рисуется множество раз, накладываясь одна на другую. Исправим это, очищая холст в том месте, где у нас вывод очков.
const drawScore = function() {
ctx.clearRect(0,340,400,100);
ctx.font = "20px Arial";
5. Программируем вариант проигрыша
В случае, если игрок попадает на дверь, за которой есть привидение, игра должна окончиться и на экран должно вывестись общее количество очков.5.1. Напишем функцию, отвечающую за конец игры.
const finishGame = function() {
ctx.clearRect(0,0,WIDTH,HEIGHT);
ctx.font = "40px Arial";
ctx.textBaseline = "top";
ctx.textAlign = "center";
ctx.fillStyle = "Red";
ctx.fillText("За дверью привидение! Игра окончена.",WIDTH/2,HEIGHT/2-40);
ctx.fillStyle = "White";
ctx.fillText("Ваш общий счёт: "+score,WIDTH/2,HEIGHT/2+40);
}
const drawScore = function() {
5.2. Не забудьте вызвать эту функцию в нужном месте программы.
6. Усовершенствование дверей.
Сейчас от игры до игры двери не изменяются, а было бы здорово сделать их динамичнее, чтобы каждый клик игрока вызывал ответное действие. Давайте сделаем так, чтобы двери брали свой цвет и цвет дверной ручки случайно.6.1. Добавим массив цветов:
const colors = ["Brown","Red","Black","Blue","White","Green","Navy","Orange","DarkRed"];
const ctx = canvas.getContext('2d');
let score = 0;
6.2. Для того, чтобы добыть случайный цвет из массива мы будем пользоваться примерно такой записью:
colors[randomNumber], где randomNumber будем добывать при помощи функции-помощника, которую пропишем далее.
const getRandom = function(number) {
return Math.floor(Math.random()*number); // возвращает число от 0 до number
}
6.3. Изменим код создания дверей:
drawDoor(100,100,colors[getRandom(9)],colors[getRandom(9)]);
drawDoor(240,100,colors[getRandom(9)],colors[getRandom(9)]);
drawDoor(380,100,colors[getRandom(9)],colors[getRandom(9)]);
6.4. Теперь нам нужно перерисовывать все эти 3 двери при каждом удачном клике на дверь. То есть, делать множество раз. Поэтому, код создания дверей лучше записать в функцию и вызывать её в случае успеха.
const drawDoors = function() {
drawDoor(100,100,colors[getRandom(9)],colors[getRandom(9)]);
drawDoor(240,100,colors[getRandom(9)],colors[getRandom(9)]);
drawDoor(380,100,colors[getRandom(9)],colors[getRandom(9)]);
}
6.5. Не забудьте вызвать эту функцию в нужных местах.
В конспект
Горизонтальное выравнивание текста
ctx.textAlign = "center"; // left, center, rightВертикальное выравнивание текста
ctx.textBaseline = "top"; // top, center, bottomКонстанты
const – это то, что не изменяется при выполнении программыЗадания
Задание 1***. Добавьте переменную с очками здоровья. Выведите её на экран ниже счёта. Пусть вначале их будет 3. При каждом неудачном попадании по двери, уменьшайте очки здоровья на 1. Когда они закончатся, игра завершается.Задание 2**. 3 двери – это неимоверно мало для того, чтобы интересно поиграть. Добавьте ещё 2 двери.
Задание 3**. Добавьте нарисованную на холсте кнопку "Начать заново". При нажатии на неё выполните команду window.location.reload(); Страница перезагрузится и игра начнётся заново.
Комментарии
Отправить комментарий