/
DreamerOnMaybe
/
BrowserRPG
Обзор
Документация
Войти
/
DreamerOnMaybe
/
BrowserRPG
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
script.js
446 строк
17 KB
Павел Марфенко
upload files
22 янв 2026, 14:15
Верифицирован
22 янв 2026, 14:15
e5de2b6
Код
Авторство
О чём код?
let currentEnemy = null; let globalTimeout = null; // для отмены таймеров const locationDisplay = document.querySelector('[data-location]'); const logElement = document.getElementById('log'); const exitsContainer = document.getElementById('location-exits'); const battleControls = document.getElementById('battle-controls'); const enemyHealthBar = document.getElementById('enemy-health'); const attackBtn = document.getElementById('attack-btn'); const fleeBtn = document.getElementById('flee-btn'); const restartBtn = document.getElementById('restart-btn'); const gameModal = document.getElementById('game-modal'); const exitBtn = document.getElementById('exit-btn'); const player = { name: 'Талион', level: 1, health: 100, maxHealth: 100, baseDamage: 25, damageBonus: 1.0, }; const enemies = { orc: { name: 'Орк', health: 50, damage: 10 }, captain: { name: 'Урук Капитан', health: 100, damage: 20 }, leader: { name: 'Урук Вождь', health: 150, damage: 30 }, sauroon: { name: 'Саурон', health: 200, damage: 50, finalBoss: true } }; const locations = { udun: { name: 'Удун', description: 'Долина Удун - суровый край...', exits: ['orodrui'], }, orodrui: { name: 'Ородруин', description: 'Ородруин - величайший вулкан Средиземья, огненное сердце Мордора...', exits: ['udun', 'barad-dur'], hasArtifact: true, artifact: { name: 'Азбука следопытов', description: 'Следопыты Гондора — не только могучие воины: при необходимости любой из них может выступить в роли переговорщика, судьи, врача и иногда даже учителя.' }, onEnter() { if (this.hasArtifact) { const button = document.createElement('button'); button.textContent = `Подобрать: ${this.artifact.name}`; button.className = 'artifact-button'; button.addEventListener('click', () => { player.level += 1; player.maxHealth += 50; player.health += 50; player.damageBonus *= 1.05 log(`🎉 Ты подобрал: ${this.artifact.name}!`, 'artifact'); log(`📜 "${this.artifact.description}"`, 'artifact'); log(`🆙 Получен уровень! Теперь ты ${player.level} уровень.`, 'artifact'); log(`❤️ Здоровье увеличено на 50! Теперь у тебя ${player.health} ❤️`, 'artifact'); this.hasArtifact = false; button.remove(); updateStats(); }); logElement.appendChild(button); } if (Math.random() < 0.5) { const enemy = enemies.orc; log(`👹 Из пепла выскакивает ${enemy.name}! Готовься к бою!`, 'enemy'); startBattle('orc'); } else { log('Здесь тихо, слишком тихо'); } } }, 'barad-dur': { name: 'Барад-Дур', description: 'Барад-Дур лежит в руинах с тех самых пор, как войска Гондора разгромили армию Саурона в конце Второй Эпохи....', exits: ['orodrui', 'karah-angren'], }, 'karah-angren': { name: 'Карах-Ангрен', description: '"Железные челюсти" Карах-Ангрен образованы отрогами Эред-Литуи и Эфель-Дуат...', exits: ['barad-dur', 'gorthaur'] }, gorthaur: { name: 'Гортхаур', description: 'Одного взгляда на Гортхаур достаточно, чтобы вселить ужас в душу любого человека...', exits: ['karah-angren', 'uruchye-log'], hasArtifact: true, artifact: { name: 'Железные кандалы', description: 'Это оковы пленника - а точнее, ножные кандалы. Они относятся ко Второй Эпохе, и скорее всего, в них заковывали рабов Гондора, строивших Башни-Клыки на границе с Моранноном.' }, onEnter() { if (this.hasArtifact) { const button = document.createElement('button'); button.textContent = `Подобрать: ${this.artifact.name}`; button.className = 'artifact-button'; button.addEventListener('click', () => { player.level += 1; player.maxHealth += 50; player.health += 50; player.damageBonus *= 1.05 log(`🎉 Ты подобрал: ${this.artifact.name}!`, 'artifact'); log(`📜 "${this.artifact.description}"`, 'artifact'); log(`🆙 Получен уровень! Теперь ты ${player.level} уровень.`, 'artifact'); log(`❤️ Здоровье увеличено на 50! Теперь у тебя ${player.health} ❤️`, 'artifact'); this.hasArtifact = false; button.remove(); updateStats(); }); logElement.appendChild(button); } if (Math.random() < 0.5) { log('🔥Рык разрывает тишину! Перед тобой Урук-Капитан', 'enemy'); startBattle('captain'); } } }, 'uruchye-log': { name: 'Уручий лог', description: 'До возвращения Саурона в Уручьем логе располагался базарный городок, который изгои прозвали "Лавки"...', exits: ['gorthaur', 'black-road'], hasArtifact: true, artifact: { name: 'Рогатый шлем', description: 'Когда-то давно изгои Удуна использовали этот шлем в своих тайных ритуалах.' }, onEnter() { if (this.hasArtifact) { const button = document.createElement('button'); button.textContent = `Подобрать: ${this.artifact.name}`; button.className = 'artifact-button'; button.addEventListener('click', () => { player.level += 1; player.maxHealth += 50; player.health += 50; player.damageBonus *= 1.05 log(`🎉 Ты подобрал: ${this.artifact.name}!`, 'artifact'); log(`📜 "${this.artifact.description}"`, 'artifact'); log(`🆙 Получен уровень! Теперь ты ${player.level} уровень.`, 'artifact'); log(`❤️ Здоровье увеличено на 50! Теперь у тебя ${player.health} ❤️`, 'artifact'); this.hasArtifact = false; button.remove(); updateStats(); }); logElement.appendChild(button); } if (Math.random() < 0.9) { log('🔥Рык разрывает тишину! Перед тобой Урук-Вождь', 'enemy'); startBattle('leader'); } } }, 'black-road': { name: 'Черная дорога', description: 'Черная дорога - главный путь Мордора - проходит от Черных врат через долину Удун, пересекает равнины Горгорота и заканчивается у магической пелены, защищающей крепость Барад-Дур...', exits: ['uruchye-log', 'udun', 'barad-dur', 'mordor'] }, mordor: { name: 'Мордор', description: 'Мордор - страна Тени и Тьмы, где живет Саурон, второй Темный Властелин Средиземья, -привлекает силы зла и порождения мрака...', exits: ['udun'], onEnter() { log('Ты достиг сердца Мордора...'); log('Перед тобой-Саурон!', 'enemy'); startBattle('sauroon'); } } }; restartBtn.addEventListener('click', () => { gameModal.style.display = 'none' restartGame() }) exitBtn.addEventListener('click', () => { window.close() window.open('', '_self', '') setTimeout(() => { alert('Спасибо за игру! Теперь ты можешь закрыть вкладку') }, 500) }) let currentLocation = 'udun'; function updateLocation() { locationDisplay.textContent = locations[currentLocation].name; updateExits(); } function updateExits() { exitsContainer.innerHTML = ''; const exits = locations[currentLocation].exits; exits.forEach(exitKey => { const location = locations[exitKey]; if (location) { const button = document.createElement('button'); button.type = 'button'; button.textContent = `Идти в ${location.name}`; button.addEventListener('click', () => { moveToLocation(exitKey); }); exitsContainer.appendChild(button); } }); } function moveToLocation(locationKey) { if (!locations[locationKey]) { log('Ошибка: локация не существует'); return; } const canExit = locations[currentLocation].exits.includes(locationKey); if (!canExit) { log(`Нельзя попасть в ${locations[locationKey].name} отсюда`); return; } currentLocation = locationKey; updateLocation(); log(locations[locationKey].description); if (locations[locationKey].onEnter) { locations[locationKey].onEnter(); } const background = document.querySelector('.background'); const imgMap = { mordor: 'img/mordor.jpg', orodrui: 'img/orodrui.jpg', 'barad-dur': 'img/barad-dur.jpg', 'karah-angren': 'img/karah-angren.jpg', gorthaur: 'img/gorthaur.jpg', 'uruchye-log': 'img/uruchye-log.jpg', 'black-road': 'img/black-road.jpg', udun: 'img/udun.jpg' }; if (imgMap[locationKey]) { background.style.backgroundImage = `url('${imgMap[locationKey]}')`; } } const MAX_LOG_MESSAGE = 10; function log(message, type = '') { const p = document.createElement('p'); p.textContent = message; if (type === 'artifact') p.classList.add('log-artifact'); if (type === 'enemy') p.classList.add('log-enemy'); logElement.appendChild(p); if (logElement.children.length > MAX_LOG_MESSAGE) { logElement.removeChild(logElement.firstChild); } logElement.scrollTop = logElement.scrollHeight; } function startBattle(enemyKey) { const enemy = enemies[enemyKey]; if (!enemy) return; currentEnemy = { key: enemyKey, name: enemy.name, health: enemy.health, maxHealth: enemy.health, damage: enemy.damage }; exitsContainer.style.display = 'none'; battleControls.style.display = 'block'; updateEnemyHealth(); log(`👹 БОЙ НАЧАЛСЯ! Перед тобой — ${currentEnemy.name}!`, 'enemy'); log(`❤️ Его здоровье: ${currentEnemy.health}`, 'enemy'); attackBtn.onclick = () => { const minBase = player.baseDamage; const maxBase = player.baseDamage + 15; const randomDamage = minBase + Math.floor(Math.random() * (maxBase- minBase + 1)) const finalDamage = Math.floor(randomDamage * player.damageBonus) currentEnemy.health = Math.max(0, currentEnemy.health - finalDamage) updateEnemyHealth(); log(`⚔️ Ты атакуешь ${currentEnemy.name} и наносишь ${finalDamage} урона!`, 'artifact'); if (currentEnemy.health <= 0) { log(`🎉 Ты победил ${currentEnemy.name}!`, 'artifact'); endBattle('win'); } else { globalTimeout = setTimeout(() => { enemyAttack(); }, 800); } }; fleeBtn.onclick = () => { if (Math.random() < 0.5) { log(`🏃 Ты успешно сбежал от ${currentEnemy.name}!`, 'artifact'); endBattle('flee'); } else { log(`❌ Попытка побега не удалась!`, 'enemy'); globalTimeout = setTimeout(() => { enemyAttack(); }, 800); } }; } function enemyAttack() { if (!currentEnemy) return; const damage = currentEnemy.damage; player.health = Math.max(0, player.health - damage); log(`💀 ${currentEnemy.name} атакует! Ты получаешь ${damage} урона!`, 'enemy'); updateStats(); if (player.health <= 0) { endBattle('lose'); } } function endBattle(result) { clearTimeout(globalTimeout); globalTimeout = null; if (result === 'win') { player.health = player.maxHealth; player.damageBonus *= 1.15; log('❤️ Победа! Ты полностью восстановил здоровье!', 'artifact'); log('⚔️ Твой урон увеличен на 15% за победу!', 'artifact'); updateStats(); } if (result === 'win' && currentEnemy.key === 'sauroon') { log('🎉 Ты победил Саурона! Кольцо уничтожено! Мир спасён!', 'artifact'); globalTimeout = setTimeout(() => { battleControls.style.display = 'none'; exitsContainer.style.display = 'none'; showGameOver('win'); }, 2000); return; } if (result === 'lose') { log('💀 Ты погиб... Игра окончена.', 'enemy'); globalTimeout = setTimeout(() => { battleControls.style.display = 'none'; exitsContainer.style.display = 'none'; showGameOver('lose'); }, 2000); return; } battleControls.style.display = 'none'; exitsContainer.style.display = 'flex'; currentEnemy = null; } function updateEnemyHealth() { if (!currentEnemy) return; const percent = Math.max(0, Math.round((currentEnemy.health / currentEnemy.maxHealth) * 100)); enemyHealthBar.style.width = `${percent}%`; enemyHealthBar.textContent = `${currentEnemy.name}: ${percent}%`; enemyHealthBar.style.backgroundColor = percent > 50 ? '#d62828' : percent > 20 ? '#e95f2a' : '#c1121f'; } function updateStats() { const damageDisplay = Math.floor(player.baseDamage * player.damageBonus) document.querySelector('[data-stat="health"]').textContent = `${player.health}/${player.maxHealth} ❤️`; document.querySelector('[data-stat="level"]').textContent = `${player.level} ⭐`; } function restartGame() { clearTimeout(globalTimeout); globalTimeout = null; player.level = 1; player.health = 100; player.maxHealth = 100; locations.orodrui.hasArtifact = true; locations.gorthaur.hasArtifact = true; locations['uruchye-log'].hasArtifact = true; battleControls.style.display = 'none'; exitsContainer.style.display = 'flex'; currentLocation = 'udun'; updateLocation(); updateStats(); const background = document.querySelector('.background'); background.style.backgroundImage = "url('img/udun.jpg')"; logElement.innerHTML = ''; log(`Добро пожаловать! Вы начинаете игру в ${locations.udun.name}`); } function showGameOver(type) { const modal = document.getElementById('game-modal'); const modalTitle = document.querySelector('#game-modal h2'); const modalText = document.querySelector('#game-modal p'); if (type === 'win') { modalTitle.textContent = 'Победа! 🎉'; modalText.textContent = 'Ты уничтожил Кольцо и спас Средиземье!'; } else { modalTitle.textContent = 'Игра окончена 💀'; modalText.textContent = 'Ты погиб в глубинах Мордора...'; } modal.style.display = 'flex'; } restartGame() updateLocation(); updateStats();