NEBULA CALC | СЕКРЕТНАЯ ИГРА
by SparkHawk26577 lines20.2 KB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>NEBULA CALC | СЕКРЕТНАЯ ИГРА</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
min-height: 100vh;
background: radial-gradient(circle at 30% 10%, #0c0a1a, #020105);
display: flex;
justify-content: center;
align-items: center;
font-family: 'Segoe UI', 'Courier New', monospace;
padding: 20px;
transition: all 0.3s;
}
/* КАЛЬКУЛЯТОР (виден по умолчанию) */
.calculator-wrapper {
width: 100%;
max-width: 450px;
margin: 0 auto;
transition: 0.3s;
}
body.game-mode .calculator-wrapper {
display: none;
}
body.game-mode .game-container {
display: block;
}
.calculator {
background: linear-gradient(145deg, #1e1a2f, #0f0b1a);
border-radius: 56px;
padding: 24px 20px 30px 20px;
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.6);
border: 1px solid rgba(156, 80, 255, 0.35);
}
.screen {
background: #07050e;
padding: 25px 20px;
border-radius: 48px;
margin-bottom: 30px;
border: 1px solid #3c2a6e;
}
.previous-operand {
min-height: 32px;
font-size: 1.2rem;
color: #b58eff;
text-align: right;
}
.current-operand {
font-size: 3rem;
font-weight: 700;
color: #f0e6ff;
text-align: right;
word-break: break-all;
text-shadow: 0 0 6px #9b4dff;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
}
button {
background: #15102a;
border: none;
padding: 18px 0;
font-size: 1.6rem;
font-weight: bold;
border-radius: 48px;
color: #e2d6ff;
cursor: pointer;
transition: 0.08s linear;
box-shadow: 0 6px 0 #0a0720;
border: 1px solid rgba(128, 90, 240, 0.4);
}
button:active {
transform: translateY(3px);
box-shadow: 0 2px 0 #0a0720;
}
.operator {
background: #2a1a55;
color: #dbbaff;
font-size: 1.9rem;
}
.equals {
background: #9b4dff;
color: #1a0f2e;
box-shadow: 0 6px 0 #5c2ab3;
}
.clear, .delete {
background: #3d1f5e;
}
.delete {
background: #5a2a82;
}
.secret-hint {
text-align: center;
margin-top: 20px;
font-size: 0.75rem;
color: #8a6fcf;
}
/* ИГРОВОЙ КОНТЕЙНЕР (скрыт) */
.game-container {
display: none;
width: 100%;
max-width: 900px;
background: #0c0820;
border-radius: 56px;
padding: 20px;
border: 2px solid #9b4dff;
}
.game-header {
display: flex;
justify-content: space-between;
background: #180e2e;
padding: 12px 20px;
border-radius: 60px;
margin-bottom: 18px;
color: #f2dd9f;
font-weight: bold;
flex-wrap: wrap;
gap: 10px;
}
canvas {
display: block;
margin: 0 auto;
border-radius: 24px;
background: #0d0a1a;
width: 100%;
height: auto;
cursor: pointer;
}
.secret-controls {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 20px;
}
.sec-btn {
background: #2d1f53;
padding: 10px 20px;
font-size: 1.4rem;
border-radius: 48px;
color: #ffd966;
box-shadow: 0 4px 0 #0e0820;
}
.back-btn {
background: #671b5e;
}
.cheat-info {
text-align: center;
margin-top: 12px;
color: #ffdc97;
background: #00000088;
padding: 6px;
border-radius: 60px;
font-size: 0.8rem;
}
@media (max-width: 560px) {
button { padding: 12px 0; font-size: 1.3rem; }
.sec-btn { font-size: 1rem; padding: 8px 16px; }
}
</style>
</head>
<body>
<!-- КАЛЬКУЛЯТОР -->
<div class="calculator-wrapper">
<div class="calculator">
<div class="screen">
<div class="previous-operand" id="previousOperand"></div>
<div class="current-operand" id="currentOperand">0</div>
</div>
<div class="buttons">
<button class="clear" data-action="clear">C</button>
<button class="delete" data-action="delete">⌫</button>
<button class="operator" data-operator="%">%</button>
<button class="operator" data-operator="/">÷</button>
<button data-number="7">7</button>
<button data-number="8">8</button>
<button data-number="9">9</button>
<button class="operator" data-operator="*">×</button>
<button data-number="4">4</button>
<button data-number="5">5</button>
<button data-number="6">6</button>
<button class="operator" data-operator="-">−</button>
<button data-number="1">1</button>
<button data-number="2">2</button>
<button data-number="3">3</button>
<button class="operator" data-operator="+">+</button>
<button data-number="0">0</button>
<button data-number=".">.</button>
<button class="equals" id="equalsBtn">=</button>
</div>
<div class="secret-hint">
🔮 СЕКРЕТ: нажми = при числе 258425 или введи 25+84+25=
</div>
</div>
</div>
<!-- СЕКРЕТНАЯ ИГРА SUBVS -->
<div class="game-container" id="secretGame">
<div class="game-header">
<span>🌀 SUBVS: SUBWAY SURFERS STYLE 🐹</span>
<span>🏆 СЧЁТ: <span id="gameScore">0</span></span>
<span>🐹 ХОМЯКИ: <span id="gameCoins">0</span></span>
<span>⚡ РЕКОРД: <span id="gameBest">0</span></span>
</div>
<canvas id="gameCanvas" width="800" height="500" style="width:100%; max-width:800px; aspect-ratio:800/500"></canvas>
<div class="secret-controls">
<button class="sec-btn" id="leftBtn">◀ ЛЕВО</button>
<button class="sec-btn" id="rightBtn">ПРАВО ▶</button>
<button class="sec-btn back-btn" id="exitBtn">🔒 ВЫЙТИ</button>
</div>
<div class="cheat-info">✨ ЧИТЫ АКТИВИРОВАНЫ! Уклоняйся от поездов, собирай хомяков ✨</div>
</div>
<script>
// ========== КАЛЬКУЛЯТОР С АКТИВАЦИЕЙ ПО КОДУ ==========
const previousOperandEl = document.getElementById('previousOperand');
const currentOperandEl = document.getElementById('currentOperand');
let current = "0";
let previous = "";
let operation = null;
let resetScreen = false;
function formatNumber(num) {
let str = num.toString();
let parts = str.split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, " ");
return parts.join('.');
}
function updateDisplay() {
currentOperandEl.innerText = formatNumber(current);
if (operation && previous !== "") {
previousOperandEl.innerText = `${formatNumber(previous)} ${operation}`;
} else {
previousOperandEl.innerText = previous ? formatNumber(previous) : "";
}
}
function appendNumber(num) {
if (resetScreen) {
current = "";
resetScreen = false;
}
if (num === '.' && current.includes('.')) return;
if (current === "0" && num !== '.') current = num;
else current += num;
updateDisplay();
}
function chooseOperation(op) {
if (current === "") return;
if (previous !== "" && !resetScreen) compute();
operation = op;
previous = current;
current = "";
resetScreen = false;
updateDisplay();
}
function compute() {
if (!operation || previous === "" || current === "") return;
let a = parseFloat(previous.replace(/\s/g, ''));
let b = parseFloat(current.replace(/\s/g, ''));
if (isNaN(a) || isNaN(b)) return;
let result;
switch (operation) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '×': result = a * b; break;
case '÷': result = b === 0 ? "Ошибка" : a / b; break;
case '%': result = a % b; break;
default: return;
}
if (result === "Ошибка") {
current = "∞";
previous = "";
operation = null;
resetScreen = true;
updateDisplay();
return;
}
result = parseFloat(result.toFixed(8));
current = result.toString();
operation = null;
previous = "";
resetScreen = true;
updateDisplay();
// ⭐⭐⭐ АКТИВАЦИЯ СЕКРЕТА ⭐⭐⭐
let rawResult = current.replace(/\s/g, '');
// Если результат равен 258425 (после вычисления 25+84+25 или 258425=)
if (rawResult === "258425") {
openSecretGame();
}
}
function clearAll() {
current = "0";
previous = "";
operation = null;
resetScreen = false;
updateDisplay();
}
function deleteLast() {
if (resetScreen) return;
if (current.length === 1 || current === "0") current = "0";
else current = current.slice(0, -1);
updateDisplay();
}
// При нажатии = сначала вычисляем, а потом проверяем
document.getElementById('equalsBtn').addEventListener('click', () => {
compute();
});
document.querySelectorAll('[data-number]').forEach(btn => {
btn.addEventListener('click', () => appendNumber(btn.dataset.number));
});
document.querySelectorAll('[data-operator]').forEach(btn => {
btn.addEventListener('click', () => chooseOperation(btn.dataset.operator));
});
document.querySelector('[data-action="clear"]').addEventListener('click', clearAll);
document.querySelector('[data-action="delete"]').addEventListener('click', deleteLast);
updateDisplay();
// ========== ОТКРЫТИЕ СЕКРЕТНОЙ ИГРЫ ==========
function openSecretGame() {
if (document.body.classList.contains('game-mode')) return;
document.body.classList.add('game-mode');
startGame();
}
function closeSecretGame() {
document.body.classList.remove('game-mode');
if (gameLoopId) cancelAnimationFrame(gameLoopId);
gameActive = false;
}
// ========== 2D ИГРА SUBWAY STYLE (хомяки, поезда, бегун) ==========
let canvas = document.getElementById('gameCanvas');
let ctx = canvas?.getContext('2d');
let gameActive = true;
let score = 0;
let coins = 0;
let best = localStorage.getItem('subwayBestHam') ? parseInt(localStorage.getItem('subwayBestHam')) : 0;
let playerLane = 1;
let trainsList = [];
let hamstersList = [];
let gameFrame = 0;
let speed = 4.2;
const LANE_W = 110;
const BASE_X = 180;
const PLAY_W = 40, PLAY_H = 50;
const TRAIN_W = 48, TRAIN_H = 58;
const HAM_W = 34, HAM_H = 34;
function updateGameUI() {
document.getElementById('gameScore').innerText = Math.floor(score);
document.getElementById('gameCoins').innerText = coins;
document.getElementById('gameBest').innerText = best;
}
function spawnTrain() {
let lane = Math.floor(Math.random() * 3);
trainsList.push({ lane, y: -TRAIN_H - Math.random() * 50 });
}
function spawnHamster() {
let lane = Math.floor(Math.random() * 3);
hamstersList.push({ lane, y: -HAM_H - Math.random() * 60, rot: Math.random() * Math.PI * 2 });
}
function updateGamePhysics() {
if (!gameActive) return;
speed = 4 + Math.floor(score / 500) * 0.7;
if (speed > 11) speed = 11;
for (let t of trainsList) t.y += speed;
trainsList = trainsList.filter(t => t.y < canvas.height + 100);
for (let h of hamstersList) {
h.y += speed;
h.rot = (h.rot + 0.1) % (Math.PI * 2);
}
hamstersList = hamstersList.filter(h => h.y < canvas.height + 100);
let trainRate = Math.max(22, 45 - Math.floor(score / 120));
let hamRate = Math.max(14, 32 - Math.floor(score / 100));
if (gameFrame % trainRate === 0) spawnTrain();
if (gameFrame % hamRate === 0) spawnHamster();
let playerX = BASE_X + playerLane * LANE_W + LANE_W/2 - PLAY_W/2;
let playerY = canvas.height - PLAY_H - 18;
let playerRect = { x: playerX, y: playerY, w: PLAY_W, h: PLAY_H };
// поезда
for (let i=0; i<trainsList.length; i++) {
let t = trainsList[i];
let tx = BASE_X + t.lane * LANE_W + LANE_W/2 - TRAIN_W/2;
if (playerRect.x < tx + TRAIN_W && playerRect.x + PLAY_W > tx &&
playerRect.y < t.y + TRAIN_H && playerRect.y + PLAY_H > t.y) {
gameActive = false;
if (Math.floor(score) > best) {
best = Math.floor(score);
localStorage.setItem('subwayBestHam', best);
}
updateGameUI();
return;
}
}
// хомяки
for (let i=0; i<hamstersList.length; i++) {
let h = hamstersList[i];
let hx = BASE_X + h.lane * LANE_W + LANE_W/2 - HAM_W/2;
if (playerRect.x < hx + HAM_W && playerRect.x + PLAY_W > hx &&
playerRect.y < h.y + HAM_H && playerRect.y + PLAY_H > h.y) {
coins++;
hamstersList.splice(i,1);
i--;
updateGameUI();
}
}
score += 0.25;
updateGameUI();
gameFrame++;
}
function drawGame() {
if (!ctx) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#130c24";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// рельсы
for (let i=0; i<=3; i++) {
let rx = BASE_X + i * LANE_W - 5;
ctx.beginPath();
ctx.strokeStyle = "#b37bff";
ctx.lineWidth = 3;
for (let s=0; s<canvas.height+40; s+=35) {
ctx.beginPath();
ctx.moveTo(rx, s);
ctx.lineTo(rx+8, s+18);
ctx.stroke();
}
}
// поезда
for (let t of trainsList) {
let x = BASE_X + t.lane * LANE_W + LANE_W/2 - TRAIN_W/2;
ctx.fillStyle = "#4a2b7a";
ctx.fillRect(x, t.y, TRAIN_W, TRAIN_H);
ctx.fillStyle = "#dcaaff";
ctx.fillRect(x+8, t.y+12, TRAIN_W-16, 10);
ctx.fillStyle = "#ffbc6e";
ctx.beginPath();
ctx.arc(x+TRAIN_W/2, t.y+14, 7, 0, Math.PI*2);
ctx.fill();
}
// хомяки вращающиеся
for (let h of hamstersList) {
let x = BASE_X + h.lane * LANE_W + LANE_W/2 - HAM_W/2;
ctx.save();
ctx.translate(x+HAM_W/2, h.y+HAM_H/2);
ctx.rotate(h.rot);
ctx.fillStyle = "#bc8a5a";
ctx.beginPath();
ctx.ellipse(0, 0, HAM_W/2.2, HAM_H/2.2, 0, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = "#4f2d15";
ctx.beginPath();
ctx.ellipse(-6, -5, 4, 5, 0, 0, Math.PI*2);
ctx.ellipse(6, -5, 4, 5, 0, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(-5, -7, 2, 0, Math.PI*2);
ctx.arc(5, -7, 2, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = "#ffad60";
ctx.font = "20px monospace";
ctx.fillText("🐹", -10, -6);
ctx.restore();
}
// игрок
let px = BASE_X + playerLane * LANE_W + LANE_W/2 - PLAY_W/2;
let py = canvas.height - PLAY_H - 18;
ctx.fillStyle = "#bf6eff";
ctx.fillRect(px, py, PLAY_W, PLAY_H);
ctx.fillStyle = "#ffce70";
ctx.beginPath();
ctx.ellipse(px+PLAY_W/2, py-6, 14, 10, 0, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = "#2c1c42";
ctx.fillRect(px+10, py+28, 7, 12);
ctx.fillRect(px+PLAY_W-17, py+28, 7, 12);
if (!gameActive) {
ctx.font = "bold 28monospace";
ctx.fillStyle = "#ffbf7a";
ctx.fillText("💀 ИГРА ОКОНЧЕНА", canvas.width/2-140, canvas.height/2);
}
}
let gameLoopId = null;
function gameLoop() {
if (!ctx) return;
if (gameActive) updateGamePhysics();
drawGame();
gameLoopId = requestAnimationFrame(gameLoop);
}
function startGame() {
if (!canvas) canvas = document.getElementById('gameCanvas');
if (!ctx) ctx = canvas?.getContext('2d');
gameActive = true;
score = 0;
coins = 0;
trainsList = [];
hamstersList = [];
playerLane = 1;
gameFrame = 0;
speed = 4.2;
updateGameUI();
if (gameLoopId) cancelAnimationFrame(gameLoopId);
gameLoop();
}
// управление
document.getElementById('leftBtn')?.addEventListener('click', () => { if (gameActive && playerLane > 0) playerLane--; });
document.getElementById('rightBtn')?.addEventListener('click', () => { if (gameActive && playerLane < 2) playerLane++; });
document.getElementById('exitBtn')?.addEventListener('click', closeSecretGame);
window.addEventListener('keydown', (e) => {
if (document.body.classList.contains('game-mode')) {
if (e.key === 'ArrowLeft') { if (gameActive && playerLane > 0) playerLane--; e.preventDefault(); }
if (e.key === 'ArrowRight') { if (gameActive && playerLane < 2) playerLane++; e.preventDefault(); }
}
});
// Запасной способ: если ввели 258425 и нажали =
window.openSecretGame = openSecretGame;
</script>
</body>
</html>Game Source: NEBULA CALC | СЕКРЕТНАЯ ИГРА
Creator: SparkHawk26
Libraries: none
Complexity: complex (577 lines, 20.2 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: nebula-calc-sparkhawk26" to link back to the original. Then publish at arcadelab.ai/publish.