Щёлкай гроссов верно и без промаха
На самом деле, мне снова нужен был небольшой шаблончик для яваскрипт-игрушки, связанной с установкой соответствий между словами и картинками, но не перетаскиванием, как в задаче о расстановке фамилий по позициям или в более старой "корзине истории", а простой последовательностью кликов по картинкам.
Правда, пример, как и по первой ссылке, получился опять шахматный, нужно правильно щёлкнуть по портретам участников скоро начинающегося Ставангера-2019.
Фамилия-вопрос будет появляться под лентой с портретами. Если Вы сделали правильно все 10 шагов, в конце увидите общее время игры в формате ЧЧ:ММ:СС.МС, где МС - сотые доли секунды.
Ниже можно попробовать свои и силы и посмотреть исходники.
Что примечательного в коде и может ещё пригодиться:
- Более-менее современный вариант предзагрузки изображений с проверкой.
Сначала на загрузку страницы вызывается функция
preloadImages
, которая получает аргументами массив с URL-адресами картинок и имя callback-функции. После загрузки всех изображений callback-функцияcheckImgLoaded
проверяет, всё ли в порядке (складывая ширину всех картинок, которая для простоты предполагается одинаковой). Если всё хорошо, устанавливается флажокplayGameFlag
. - "Верные ответы" ставятся как скрытые атрибуты тегов
img
рисунков (с именемanswer
). - Функция
difftime
ищет разницу времени между двумя объектамиDate
и возвращает строку с найденным временем, проведённым в игре (время считается от первого клика, а не от загрузки страницы). Строка времени оформляется по указанному выше формату. - Для совместимости с Internet Explorer (по крайней мере, 11-м) пришлось переписать функцию случайного перемешивания элементов массива с красивого
function shuffle (array) { array.sort(() => Math.random() - 0.5); }
на то, что сейчас в коде.
- Если использовать для рисунков формат
.gif
с прозрачным фоном, можно уже отмеченные картинки просто выделять фоновым цветом, что и сделано. Поэтому шаблон обходится без каких-либо стилевых указаний и дополнительных элементов разметки.
Вот исходник на момент написания и без HTML-обрамления, предполагается, что он будет работать из файла .html
в кодировке Юникода UTF-8, а исходные картинки находятся в одной папке с документом и имеют имена 1.gif
, ..., 10.gif
(в коде онлайн-скрипта эти пути изменены).
<a name="gameStartLabel"></a> <div align="center" id="picturebox"></div> <div align="center" id="questionbox"></div> <script> var imagesDiv = document.getElementById("picturebox"); var questionDiv = document.getElementById("questionbox"); var playGameFlag = false; var cnt, step, startTime, endTime; var imgSources = [ //адреса картинок "1.gif", "2.gif", "3.gif", "4.gif", "5.gif", "6.gif", "7.gif", "8.gif", "9.gif", "10.gif" ]; for (var i = 0; i < imgSources.length; i++) imgSources[i] += '?' + Math.random(); var imgArray = []; //массив рисунков var width_1 = 111; //ширина одной картинки var names = [ //подписи "Аронян", "Карлсен", "Ананд", "Вашье-Лаграв", "Дин Лижэнь", "Со", "Мамедьяров", "Юй Янъи", "Грищук", "Каруана" ]; function difftime (t1,t2) { var msec = t2 - t1; var hh = Math.floor(msec / 1000 / 60 / 60); if (hh < 9) hh = '0' + hh; msec -= hh * 1000 * 60 * 60; var mm = Math.floor(msec / 1000 / 60); if (mm < 9) mm = '0' + mm; msec -= mm * 1000 * 60; var ss = Math.floor(msec / 1000); if (ss < 9) ss = '0' + ss; msec -= ss * 1000; msec = Math.floor (msec/10); //сотые доли сек. if (msec < 9) msec = '0' + msec; return '' + hh + ':' + mm + ':' + ss + '.' + msec; } function playInGame () { //клик на картинке if (playGameFlag) { if (startTime == 0) startTime = new Date(); if (this.getAttribute('answer') === names[step]) { cnt++; this.style.backgroundColor = 'lightgreen'; questionDiv.innerHTML = names[++step] + '?'; if (cnt == 10) { endTime = new Date(); var t = difftime (startTime, endTime); questionDiv.innerHTML = "Вы победили! Время игры = " + t; playGameFlag = false; } } else { this.style.backgroundColor = 'pink'; questionDiv.innerHTML = "К сожалению, Вы ошиблись, попробуйте ещё раз!"; playGameFlag = false; } } else { questionDiv.innerHTML = "Вы не в игре, пожалуйста, " + "<a href=\"#gameStartLabel\" onclick=\"reloadGame();\">начните новую игру</a>"; } } function preloadImages (imgSources, callback) { //предзагрузка картинок var counter = 0; function onLoadGame () { counter++; if (counter == imgSources.length) callback(); } for (var i = 0; i < imgSources.length; i++) { imgArray[i] = document.createElement('img'); imgArray[i].onload = imgArray.onerror = onLoadGame; //выполнять 1-м imgArray[i].onclick = playInGame; imgArray[i].setAttribute('answer', names[i]); imgArray[i].src = imgSources[i]; //выполнять 2-м } shuffle (imgArray); for (var i = 0; i < imgSources.length; i++) imagesDiv.appendChild (imgArray[i]); } function shuffle (array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } } function startGame () { shuffle (names); cnt = step = startTime = 0; questionDiv.innerHTML = names[step] + '?'; playGameFlag = true; } function reloadGame () { while (imagesDiv.firstChild) { imagesDiv.removeChild (imagesDiv.firstChild); } shuffle (imgArray); for (var i = 0; i < imgSources.length; i++) { if (imgArray[i].style.backgroundColor === 'lightgreen') imgArray[i].style.backgroundColor = ''; imagesDiv.appendChild (imgArray[i]); } startGame(); } function checkImgLoaded () { //Проверка - находим общую ширину всех картинок var widthSum = 0; for (var i = 0; i < imgSources.length; i++) { var img = document.createElement('img'); img.src = imgSources[i]; widthSum += img.width; } if (widthSum == imgSources.length * width_1) { startGame(); } } window.addEventListener('load', function (e) { preloadImages (imgSources, checkImgLoaded); }, false); </script> <noscript><p align="center">Включите Javascript для работы приложения!</p></noscript>
Вот все гроссы на одном полотне (где Сирожа? А Сирожи не видать):
Участники Ставангера-2019, шаржик
02.06.2019, 19:05 [1770 просмотров]