Задача
На экране в случайном месте появляется прямоугольная область – регион. Кликнув по ней мышкой, игрок получает +1 очко, а прямоугольная область перемещается в новое случайное место. У игрока есть 20 секунд чтобы успеть набрать наибольшее количество очков.Видео с готовым результатом
Ход работы
1. Создание и подготовка проекта.
1.1. Создайте в вашей папке с сайтами новую папку "canvas-clicker" и в ней создайте такую структуру файлов и папок:canvas-clicker
--js
----script.js
--css
----style.css
--index.html
1.2. Заполните файлы базовым содержимым:
Файл разметки index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Аркада на canvas</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<canvas id="canvas-main"></canvas>
<script src="js/script.js"></script>
</body>
</html>
Файл со стилями style.css
body, html {
margin:0;
width: 100%;
height: 100%;
background-color: #2d2d2d;
}
Файл со скриптами script.js
var canvas = document.getElementById("canvas-main");
canvas.width = window.innerWidth; // ширина холста занимает всю ширину экрана
canvas.height = window.innerHeight; // высота холста занимает всю высоту экрана
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var ctx = canvas.getContext('2d');
2. Понятие игрового цикла
В работе с canvas мы используем анимацию. Для того, чтобы что-то изменилось на холсте, необходимо проводить такой цикл:1) очистить весь холст
2) отрисовать объекты в их координатах
И делать это столько раз в секунду, чтобы человеку казалось это плавным. Например, базово это можно делать 25 кадров в секунду (то есть, с интервалом в 1000/25 = 40 миллисекунд).
2.1. Напишем игровой цикл в конце программы:
var ctx = canvas.getContext('2d');
setInterval(function(){
},40);
3. Добавление объекта – региона.
3.1. Для создания региона будем использовать функцию-конструкторvar ctx = canvas.getContext('2d');
// Объявляем переменные, характеризующие свойства региона – координаты и размеры
var regionX,regionY,regionW,regionH;
function createRegion() {
regionX = Math.random()*WIDTH;
regionY = Math.random()*HEIGHT;
regionW = 20;
regionH = 20;
}
// Сразу же вызываем эту функцию
createRegion();
setInterval(function(){
3.2. Напишем функцию для отрисовки региона и будем вызывать её в игровом цикле.
createRegion();
function update() {
// Очищаем холст
ctx.clearRect(0,0,WIDTH,HEIGHT);
// Отрисовываем прямоугольник
ctx.fillStyle="green";
ctx.fillRect(regionX,regionY,regionW,regionH);
}
setInterval(function(){
update();
},40);
3.3. Запустите index.html и пообновляйте её несколько раз. Если всё было написано без ошибок, то вы увидите небольшой прямоугольник зелёного цвета, который каждый раз появляется в новых координатах.
4. Программируем событие нажатия мышки
setInterval(function(){update();
},40);
document.onmousedown = function(event) {
var mouseX = event.clientX;
var mouseY = event.clientY;
if(mouseX>=regionX && mouseX<=regionX+regionW) {
if(mouseY>=regionY && mouseY<=regionY+regionH) {
// Если попали мышкой по региону, то генерируем новый регион
createRegion();
}
}
}
5. Добавление очков за клик по региону
5.1. Сейчас у нас за клики ничего не даётся. Негоже. Пора добавить очки. Вначале игры они равны нулю:var ctx = canvas.getContext('2d');
var score = 0;
5.2. При каждом удачном клике по региону будем увеличивать очки на 1.
if(mouseY>=regionY && mouseY<=regionY+regionH) {
createRegion();
score = score + 1;
}
5.3. Набранные очки хранятся в памяти, но было бы круто вывести их на экран, не так ли? Всё, что мы выводим, прописываем в функции update. Дополним эту функцию.
function update() {
// Очищаем холст
ctx.clearRect(0,0,WIDTH,HEIGHT);
// Отрисовываем прямоугольник
ctx.fillStyle="green";
ctx.fillRect(regionX,regionY,regionW,regionH);
// Выводим количество очков
ctx.font = "20px Arial"
ctx.fillStyle="white";
ctx.fillText(score,30,40);
}
6. Добавление таймера
6.1. Чтобы ограничить время игры и увеличить её интересность, добавим таймер. Объявим переменную, которая будет хранить количество времени.var ctx = canvas.getContext('2d');
var score = 0;
var time = 0;
6.2. Теперь рассмотрим, каким образом можно увеличивать таймер. Мы сделали так, чтобы игровой цикл повторялся каждые 40 миллисекунд – это 25 кадров в секунду. Найдите место в коде, где это прописано. Идея в том, что если нам нужно что-то повторять с какой-нибудь периодичностью, мы можем это делать каждые N кадров. Например, если нам что-то нужно повторять каждые 3 секунды (например, генерировать врагов или пищу в игре), то мы проверяем, прошло ли 75 кадров (25 кадров * 3 секунды = 75).
С таймером увеличение будет каждые 25 кадров. Для проверки, прошло ли 25 кадров мы используем операцию остатка от деления на это количество кадров
// Объявляем переменную с кадрами, вначале их 0
var frames = 0;
setInterval(function(){
frames++; // увеличиваем количество кадров на 1
if(frames%25==0) { // Если прошло 25 кадров, то
time = time + 1;
}
update();
},40);
6.3. Как и со счётом, нам нужно выводить время на экран. Сделайте это самостоятельно.
7. Финал игры
Добавим ограничение в 20 секунд. Если проходит 20 секунд, то на экран выведется количество набранных очков и игра окончится (кликать больше будет нельзя)7.1. Добавим функцию проверки времени. Если время закончится, будем выводить alert (это пока что).
function checkTime() {
if(time>=10) {
alert("Game over! You have " + score + " scores!");
}
}
Вызываем эту функцию в игровом цикле:
if(frames%25==0) {
time = time + 1; // Увеличили время
checkTime(); // Проверили, не закончилось ли оно
}
7.2. Рассмотрим два состояния игры:
1) игра не окончена (на экране регион, на который можно кликать, увеличиваются очки и время)
2) игра окончена (больше очки не добавляются, на экране надпись об окончании игры)
За эти состояния будет отвечать переменная булева переменная isGameOver, которая вначале будет равной false, а в момент, когда время выйдет, сделаем её true.
var score = 0;
var time = 0;
var isGameOver = false;
7.3. Теперь поправим код с учётом этих двух состояний – игровой цикл будет увеличивать фреймы и осуществлять перерисовку только если игра не окончена.
setInterval(function(){
if(isGameOver===false){
frames++;
if(frames%25==0) {
time = time + 1;
checkTime();
}
update();
} else {
ctx.clearRect(0,0,WIDTH,HEIGHT);
}
},40);
7.4. Добавим изменение состояния игры – это происходит в момент, когда время заканчивается
function checkTime() {
if(time>=10) {
alert("Game over! You have " + score + " scores!");
isGameOver=true;
}
}
if(time>=10) {
isGameOver=true;
}
}
7.5. Выведем на экран надпись об окончании игры и количестве очков
else {
ctx.clearRect(0,0,WIDTH,HEIGHT);
ctx.font = "40px Arial"
ctx.fillStyle="red";
ctx.fillText("The end",WIDTH/2-100,HEIGHT/2);
ctx.fillStyle="green";
ctx.fillText("You've got " + score + " scores",WIDTH/2-100,HEIGHT/2+50);
}
Задания
Задание 1*. Сделайте так, чтобы каждый новый регион создавался не только в случайных координатах х и у, но и со случайной шириной и высотой.
Задание 2***. Увеличьте время игры до 20 секунд. Добавьте в конце объявления результата игры, какого успеха достиг игрок:
если он набрал до 3 очков, добавить сообщение "Надо качать скилл управления мышкой"
от 4 до 10 – "Я в детстве в 1 классе и то больше набирал"
от 11 до 20 – "Норм так"
от 21 до 30 – "А ты хорош!"
выше 31 – изменить цвет холста на другой и начать выводить на холст надписи "Красавчег" в случайной позиции.
Задание 3*. Сделайте так, чтобы регион реагировал не на клики мышки по нему, а на попадание курсора по нему при движении мышки.
Задание 4****. Добавьте ещё один регион жёлтого цвета. Пусть он тоже появляется в случайном месте раз в 4 секунд и пропадает после 1 секунды. Клик по этой области даёт плюс 4 к очкам.
если он набрал до 3 очков, добавить сообщение "Надо качать скилл управления мышкой"
от 4 до 10 – "Я в детстве в 1 классе и то больше набирал"
от 11 до 20 – "Норм так"
от 21 до 30 – "А ты хорош!"
выше 31 – изменить цвет холста на другой и начать выводить на холст надписи "Красавчег" в случайной позиции.
Задание 3*. Сделайте так, чтобы регион реагировал не на клики мышки по нему, а на попадание курсора по нему при движении мышки.
Задание 4****. Добавьте ещё один регион жёлтого цвета. Пусть он тоже появляется в случайном месте раз в 4 секунд и пропадает после 1 секунды. Клик по этой области даёт плюс 4 к очкам.
Комментарии
Отправить комментарий