Слоты сайты
Создайте игровые автоматы внутри заголовка сайта
Приветствую, в этой статье мы создадим игру «Слоты» внутри заголовка сайта (пример TitleRun). Механика игры будет очень простой. нажмите кнопку - получите случайные слоты, если все слоты совпадут - выиграйте.
Зачем вообще делать игры в заголовке сайта?
Да, возможно, это звучит как нечто совершенно странное, но тем не менее, это довольно интересно. По крайней мере, интереснее, чем делать игру обычным способом.
Анимации
Анимацию можно реализовать разными способами:
setIntervalфункция анимации()< let i = 0; setInterval(() =>< document.title = `Таймер - $`; i++; >); >
setTimeout
пусть часы = 0; функция анимации()< document.title = `Таймер - $`; timer++; setTimeout(animation, 1000) >
пока и жду
функция сна (мс)< return new Promise((r) =>setTimeout(r, мс)); & gt; асинхронная функция анимации()< let i = 0; while(true) < document.title = `Таймер - $`; await sleep(1000); > >
Механика
В качестве подсказки я буду использовать эмодзи (смайлики, эмодзи, что вы предпочитаете):
Вот как я хочу иметь возможность получать случайные треки:
const getSlot = () => < const slot = Math.ceil(Math.random()*slots.length-1); return slots[slot]; >; const getSlots = () => < return slots.map(getSlot); >;
При нажатии на кнопку будет происходить анимация разных треков, скорость которых будет постепенно увеличиваться:
const spin = document.getElementById('spin'); const slotsAnimation = async () => < let speed = 20; while (true) < //получаю слоты const slotsRandom = getSlots(); //вывожу document.title = slotsRandom.join(''); if(speed >= 1000)< checkWin(slotsRandom); break; >скорость += 50; дождаться сна(скорость); & gt; >; spin. addEventListener('клик', StartGame);
checkWin — функция для проверки выигрыша:
const checkWin = (slots) => < for(let i=0;i& gt; Предупреждение('ПОБЕДА!!!'); >;
Теперь уже играбельно.
Но я хотел бы добавить больше анимаций (например, анимации победы и главного меню). Это можно сделать, введя глобальные переменные, такие как:
пусть играет = ложь; пусть победа = ложь;
и отображать анимацию на их основе:
const slotsAnimation = async () => < playing = true let speed = 20; while (playing) < const slotsRandom = getSlots(); document.title = slotsRandom.join(''); if(speed >= 1000)< checkWin(slotsRandom); playing = false >speed += 50; await sleep(speed); > >; const winAnimation = async () => < win = true; while(win && !playing) < document.title = 'WIN!*'; await sleep(1000); document.title = '*WIN!'; await sleep(1000); >>; //Эта анимация будет просто циклично дублировать слоты const mainAnimation = async () => < playing = false let i = 0; while (!playing && !win) < if(i === slots.length - 1) i = 0; else i++; document.title = slots[i].repeat(slots.length); await sleep(1000); >>;
Сделайте это удобнее
Первое, что я хочу сделать, это создать функцию, которая заменяет логику winAnimation. Он выдаст сообщение, а затем запустит другую функцию. В качестве аргументов он будет принимать объект с текстом, количеством итераций, скоростью и обратным вызовом.
const message = async () => < if(!text[0]) throw new Error('need array for text'); let i = 0; let textIndex = 0; while(true) < if(count if(textIndex >= text. length) textIndex = 0; // На каждой итерации цикла мы будем отображать 1 сообщение из массива сообщений document. title = text[textIndex]; я++; текстИндекс++; ожидайте сна (скорость) & gt; >; // Использование сообщения()
Я также хочу создать менеджер анимации, который можно использовать для запуска и управления анимацией. Это будет класс со слоем анимации и несколькими методами.
Класс Анимации< animations = []; setAnimation(animation, args = <>) < // Выключаем все анимации for(const item of this.animations) < item.play = false >// Находим анимацию, активируем и запускаем const Animation = this. animations. find(item =& gt; item. name === анимация); if(! Анимация) return; Анимация. play = правда; Animation. callback(args) & gt;; isPlay (анимация)< return this.animations.find(item =>item. name === анимация). play & gt; createAnimation (имя, обратный вызов)< this.animations.push(< play: false, name, callback, >) > >
Описание метода: setAnimation — вызывает анимацию. isPlay — условная функция, проверяющая, «играет» ли анимация. createAnimation — добавляет анимацию в репозиторий.
Теперь код будет выглядеть так:
const checkWin = (slots) => < for(let i=0;i> alert('WIN!!'); animations.setAnimation('message', animations.setAnimation('main')>) >; const slotsAnimation = async () => < let speed = 20; while (animations.isPlay('game')) < const slotsRandom = getSlots(); document.title = slotsRandom.join(''); if(speed >= 1000)< checkWin(slotsRandom); >speed += 50; await sleep(speed); > >; const mainAnimation = async () => < let i = 0; while (animations.isPlay('main')) < if(i === slots.length - 1) i = 0; else i++; document.title = slots[i].repeat(slots.length); await sleep(1000); >>; // Добавляем анимацию анимации. createAnimation('main', mainAnimation); анимации. createAnimation('игра', slotsAnimation); анимации. createAnimation('сообщение', сообщение); // Запуск анимации. setAnimation('main');
Возможность добавить слот
Давайте на этот раз добавим возможность добавления случайного слота. (Здесь мы просто берем эмодзи из API, добавляем его в массив и активируем основную анимацию).
const AddSlot = async () => < // Показываем сообщение пока ждём ответа от API animations.setAnimation('message', ); try < const data = await fetch(`https://emoji-api.com/emojis?access_key=КЛЮЧ`); const body = await data.json(); const emoji = await body[Math.floor(Math.random() * body.length -1)]; slots.push(emoji.character); >улов(ы)< // Если не получилось console.log(e); animations.setAnimation('none'); document.title = 'Error, try again'; await sleep(800); >окончательно< animations.setAnimation('main'); >>;
Вот и все. Надеюсь, вы узнали что-то новое.
Репозиторий на GitHub — ссылка. Пример ссылки на сайт.