Литературный клуб
by NeonPanther57284 lines11.4 KB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Литературный клуб</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; user-select:none; -webkit-tap-highlight-color:transparent; }
body {
background: #0a0a0a;
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Courier New', monospace;
touch-action: none;
}
#container {
position: relative;
width: 100%;
height: 100%;
background: #000;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#message {
color: #888;
font-size: 4vmin;
letter-spacing: 0.5vmin;
text-align: center;
z-index: 2;
animation: pulse 2s infinite alternate;
}
@keyframes pulse {
0% { opacity: 0.3; }
100% { opacity: 1; }
}
/* Моника (скример) */
#monika {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 10;
display: none;
filter: contrast(1.8) brightness(0.9) saturate(0.3);
animation: glitch 0.15s infinite alternate;
}
#monika.active {
display: block;
}
@keyframes glitch {
0% { transform: translate(0,0) scale(1.02); }
25% { transform: translate(-10px,6px) scale(1.06); }
50% { transform: translate(10px,-6px) scale(0.96); }
75% { transform: translate(-5px,10px) scale(1.04); }
100% { transform: translate(0,0) scale(1); }
}
/* Вспышка */
#flash {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: #fff;
z-index: 5;
opacity: 0;
pointer-events: none;
transition: opacity 0.05s;
}
#flash.active {
opacity: 1;
}
/* Затемнение */
#overlay {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: #000;
z-index: 15;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s;
}
#overlay.dark {
opacity: 0.6;
}
/* Запасной экран (если картинка не загрузилась) */
#fallback {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: #8b0000;
display: none;
align-items: center;
justify-content: center;
z-index: 10;
color: #fff;
font-size: 20vmin;
font-weight: bold;
text-shadow: 0 0 30px #000;
animation: glitch 0.2s infinite alternate;
}
#fallback.active {
display: flex;
}
/* Скрытый выход */
#info {
position: fixed;
bottom: 2vmin;
left: 2vmin;
color: #111;
font-size: 2vmin;
opacity: 0.05;
z-index: 20;
pointer-events: none;
}
@media (orientation: portrait) {
body::after {
content: "Поверни телефон горизонтально";
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: #000;
color: #888;
display: flex;
align-items: center;
justify-content: center;
font-size: 5vmin;
z-index: 999;
font-family: 'Courier New', monospace;
}
}
</style>
</head>
<body>
<div id="container">
<div id="message">Добро пожаловать в литературный клуб...</div>
<!-- Музыка (ссылка на 'Your Reality' с freemusicarchive) -->
<audio id="bgm" src="https://files.freemusicarchive.org/storage-files/music/uncategorized/Your_Reality.mp3" preload="auto" loop></audio>
<!-- Изображение Моники (ссылка с imgur, но если не загрузится – сработает fallback) -->
<img id="monika" src="https://i.imgur.com/1nJ4l4j.png" alt="Monika" crossorigin="anonymous" />
<div id="fallback">MONIKA</div>
<div id="flash"></div>
<div id="overlay"></div>
<div id="info">•</div>
</div>
<script>
(function() {
const bgm = document.getElementById('bgm');
const monika = document.getElementById('monika');
const fallback = document.getElementById('fallback');
const flash = document.getElementById('flash');
const overlay = document.getElementById('overlay');
const message = document.getElementById('message');
let isTriggered = false;
let scareTimer = null;
// Генерация звука скримера (громкий шум + писк)
function playScareSound() {
try {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// Белый шум
const bufferSize = audioCtx.sampleRate * 0.5;
const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < bufferSize; i++) {
data[i] = (Math.random() * 2 - 1) * 0.9;
}
const noise = audioCtx.createBufferSource();
noise.buffer = buffer;
const gain = audioCtx.createGain();
gain.gain.setValueAtTime(0, audioCtx.currentTime);
gain.gain.linearRampToValueAtTime(0.8, audioCtx.currentTime + 0.02);
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.5);
noise.connect(gain);
gain.connect(audioCtx.destination);
noise.start();
noise.stop(audioCtx.currentTime + 0.5);
// Писк
const osc = audioCtx.createOscillator();
osc.type = 'square';
osc.frequency.setValueAtTime(4000, audioCtx.currentTime);
osc.frequency.exponentialRampToValueAtTime(1000, audioCtx.currentTime + 0.4);
const gain2 = audioCtx.createGain();
gain2.gain.setValueAtTime(0, audioCtx.currentTime);
gain2.gain.linearRampToValueAtTime(0.6, audioCtx.currentTime + 0.02);
gain2.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.45);
osc.connect(gain2);
gain2.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + 0.45);
} catch(e) { /* тихо */ }
}
// Запуск скримера
function triggerScare() {
if (isTriggered) return;
isTriggered = true;
if (scareTimer) { clearTimeout(scareTimer); scareTimer = null; }
// Останавливаем музыку
bgm.pause();
bgm.currentTime = 0;
// Вспышка
flash.classList.add('active');
setTimeout(() => { flash.classList.remove('active'); }, 300);
// Показываем Монику (или fallback) через 300 мс
setTimeout(() => {
// Если картинка Моники загрузилась – показываем её, иначе fallback уже показан
if (monika.complete && monika.naturalWidth > 0) {
monika.classList.add('active');
} else {
fallback.classList.add('active');
}
overlay.classList.add('dark');
// Звук скримера
playScareSound();
// Вибрация
if (navigator.vibrate) {
navigator.vibrate([100, 50, 200, 80, 300, 100, 500, 100, 300]);
}
// Полноэкранный режим
try {
const el = document.documentElement;
if (el.requestFullscreen) el.requestFullscreen().catch(() => {});
else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();
else if (el.msRequestFullscreen) el.msRequestFullscreen();
} catch(e) {}
}, 300);
}
// Запускаем музыку при загрузке (автоплей с обработкой ошибок)
bgm.play().catch(() => {
// Если автоплей заблокирован, запустим по первому касанию
document.addEventListener('click', function playOnce() {
bgm.play().catch(() => {});
document.removeEventListener('click', playOnce);
}, { once: true });
});
// Таймер на 7 секунд
scareTimer = setTimeout(triggerScare, 7000);
// Если пользователь кликнет до скримера – не мешаем, но музыку запускаем
document.addEventListener('click', function() {
if (bgm.paused) {
bgm.play().catch(() => {});
}
});
// Если картинка Моники не загрузилась – показываем fallback
monika.onerror = function() {
monika.style.display = 'none';
// fallback уже есть в DOM
};
// Скрытый выход: двойное касание после скримера перезагружает страницу
let tapCount = 0, tapTimer = null;
document.addEventListener('click', function(e) {
if (!isTriggered) return;
tapCount++;
if (tapCount === 1) {
tapTimer = setTimeout(() => { tapCount = 0; }, 500);
} else if (tapCount >= 2) {
location.reload();
}
});
document.addEventListener('touchstart', function(e) {
if (!isTriggered) return;
document.click(); // эмуляция для мобильных
}, { passive: true });
})();
</script>
</body>
</html>Game Source: Литературный клуб
Creator: NeonPanther57
Libraries: none
Complexity: complex (284 lines, 11.4 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-neonpanther57-msrfc4hn" to link back to the original. Then publish at arcadelab.ai/publish.