Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Glyph Garden Gladiator</title>
- <style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
- }
- body {
- background: linear-gradient(135deg, #1a2a3a, #0d1b2a);
- color: #e0e0e0;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px;
- }
- header {
- text-align: center;
- margin-bottom: 30px;
- width: 100%;
- max-width: 1200px;
- }
- h1 {
- font-size: 3.5rem;
- margin-bottom: 10px;
- background: linear-gradient(45deg, #8bc34a, #4caf50);
- -webkit-background-clip: text;
- background-clip: text;
- color: transparent;
- text-shadow: 0 0 10px rgba(139, 195, 74, 0.3);
- }
- .subtitle {
- font-size: 1.2rem;
- margin-bottom: 20px;
- color: #a5d6a7;
- }
- .game-container {
- display: flex;
- flex-wrap: wrap;
- gap: 30px;
- justify-content: center;
- width: 100%;
- max-width: 1200px;
- }
- .control-panel {
- background: rgba(30, 40, 50, 0.8);
- border-radius: 15px;
- padding: 20px;
- width: 300px;
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
- backdrop-filter: blur(5px);
- }
- .control-section {
- margin-bottom: 25px;
- }
- h2 {
- font-size: 1.5rem;
- margin-bottom: 15px;
- color: #8bc34a;
- border-bottom: 2px solid #4caf50;
- padding-bottom: 5px;
- }
- .glyph-selector {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 10px;
- margin-bottom: 15px;
- }
- .glyph-option {
- background: rgba(60, 80, 100, 0.7);
- border: 2px solid #4caf50;
- border-radius: 8px;
- height: 60px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 2rem;
- cursor: pointer;
- transition: all 0.3s;
- }
- .glyph-option:hover {
- background: rgba(76, 175, 80, 0.3);
- transform: scale(1.05);
- }
- .glyph-option.selected {
- background: rgba(76, 175, 80, 0.5);
- box-shadow: 0 0 15px rgba(76, 175, 80, 0.7);
- }
- .glyph-option.disabled {
- opacity: 0.5;
- cursor: not-allowed;
- transform: none !important;
- }
- button {
- background: linear-gradient(45deg, #4caf50, #8bc34a);
- border: none;
- border-radius: 8px;
- color: white;
- padding: 12px 20px;
- font-size: 1rem;
- font-weight: bold;
- cursor: pointer;
- transition: all 0.3s;
- width: 100%;
- margin-bottom: 10px;
- }
- button:hover:not(:disabled) {
- transform: translateY(-2px);
- box-shadow: 0 5px 15px rgba(76, 175, 80, 0.4);
- }
- button:disabled {
- background: #546e7a;
- cursor: not-allowed;
- transform: none;
- box-shadow: none;
- }
- .battle-indicator {
- background: rgba(244, 67, 54, 0.3);
- border: 2px solid #f44336;
- border-radius: 8px;
- padding: 10px;
- margin-bottom: 15px;
- text-align: center;
- font-weight: bold;
- color: #ff5252;
- display: none;
- }
- .battle-indicator.active {
- display: block;
- animation: pulse 1s infinite;
- }
- .stats {
- display: flex;
- flex-direction: column;
- gap: 10px;
- }
- .stat-bar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .stat-label {
- font-size: 0.9rem;
- }
- .stat-value {
- font-weight: bold;
- color: #8bc34a;
- }
- .stat-change {
- font-size: 0.8rem;
- margin-left: 5px;
- animation: fadeOut 2s forwards;
- }
- .stat-change.positive {
- color: #4caf50;
- }
- .stat-change.negative {
- color: #f44336;
- }
- .progress-bar {
- height: 10px;
- width: 100%;
- background: rgba(60, 80, 100, 0.7);
- border-radius: 5px;
- margin-top: 5px;
- overflow: hidden;
- }
- .progress-fill {
- height: 100%;
- border-radius: 5px;
- transition: width 0.5s;
- }
- .health-fill {
- background: linear-gradient(90deg, #f44336, #ff9800);
- }
- .growth-fill {
- background: linear-gradient(90deg, #4caf50, #8bc34a);
- }
- .soil-fill {
- background: linear-gradient(90deg, #795548, #a1887f);
- }
- .arena-container {
- flex: 1;
- min-width: 600px;
- min-height: 600px;
- position: relative;
- background: rgba(20, 30, 40, 0.7);
- border-radius: 15px;
- overflow: hidden;
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
- }
- #arena {
- width: 100%;
- height: 100%;
- position: relative;
- }
- .glyph-creature {
- position: absolute;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: 2.5rem;
- border-radius: 50%;
- transition: transform 0.3s, opacity 0.3s;
- z-index: 10;
- text-shadow: 0 0 10px rgba(0, 0, 0, 0.7);
- }
- .creature-health-bar {
- width: 80%;
- height: 8px;
- background: rgba(0, 0, 0, 0.5);
- border-radius: 4px;
- margin-bottom: 5px;
- overflow: hidden;
- display: none;
- }
- .creature-health-fill {
- height: 100%;
- background: linear-gradient(90deg, #4caf50, #8bc34a);
- transition: width 0.3s;
- width: 100%;
- }
- .glyph-body {
- position: relative;
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 50%;
- animation: pulse 2s infinite alternate;
- }
- .glyph-core {
- font-size: 1.5em;
- z-index: 2;
- }
- .glyph-limb {
- position: absolute;
- background: currentColor;
- border-radius: 5px;
- transform-origin: center;
- }
- .damage-indicator {
- position: absolute;
- color: #ff5252;
- font-weight: bold;
- animation: floatUp 1s forwards;
- pointer-events: none;
- z-index: 100;
- }
- .soil-grid {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- display: grid;
- grid-template-columns: repeat(10, 1fr);
- grid-template-rows: repeat(10, 1fr);
- opacity: 0.3;
- z-index: 1;
- }
- .soil-cell {
- border: 1px solid rgba(139, 195, 74, 0.1);
- }
- .soil-cell.fertile {
- background: rgba(139, 195, 74, 0.1);
- }
- .message-log {
- background: rgba(30, 40, 50, 0.8);
- border-radius: 15px;
- padding: 20px;
- width: 100%;
- max-width: 1200px;
- margin-top: 30px;
- height: 150px;
- overflow-y: auto;
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
- }
- .message {
- margin-bottom: 8px;
- padding: 5px 10px;
- border-radius: 5px;
- font-size: 0.9rem;
- }
- .message.plant {
- background: rgba(76, 175, 80, 0.2);
- border-left: 3px solid #4caf50;
- }
- .message.battle {
- background: rgba(244, 67, 54, 0.2);
- border-left: 3px solid #f44336;
- }
- .message.growth {
- background: rgba(255, 152, 0, 0.2);
- border-left: 3px solid #ff9800;
- }
- .message.game-over {
- background: rgba(244, 67, 54, 0.5);
- border-left: 3px solid #f44336;
- font-weight: bold;
- }
- .game-over-screen {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.8);
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- z-index: 1000;
- display: none;
- }
- .game-over-content {
- background: rgba(30, 40, 50, 0.95);
- padding: 40px;
- border-radius: 15px;
- text-align: center;
- max-width: 500px;
- width: 90%;
- box-shadow: 0 0 30px rgba(0, 0, 0, 0.7);
- }
- .game-over-content h2 {
- font-size: 2.5rem;
- color: #f44336;
- margin-bottom: 20px;
- }
- .game-over-content p {
- margin-bottom: 20px;
- font-size: 1.2rem;
- }
- @keyframes pulse {
- 0% { transform: scale(1); }
- 100% { transform: scale(1.05); }
- }
- @keyframes floatUp {
- 0% { transform: translateY(0); opacity: 1; }
- 100% { transform: translateY(-30px); opacity: 0; }
- }
- @keyframes fadeOut {
- 0% { opacity: 1; }
- 100% { opacity: 0; }
- }
- @keyframes sprout {
- 0% { transform: scale(0) rotate(0deg); opacity: 0; }
- 50% { transform: scale(1.2) rotate(5deg); opacity: 0.8; }
- 100% { transform: scale(1) rotate(0deg); opacity: 1; }
- }
- @keyframes attack {
- 0% { transform: translateX(0) scale(1); }
- 50% { transform: translateX(20px) scale(1.2); }
- 100% { transform: translateX(0) scale(1); }
- }
- @keyframes takeDamage {
- 0% { transform: scale(1); }
- 50% { transform: scale(1.1); background-color: rgba(255, 0, 0, 0.5); }
- 100% { transform: scale(1); }
- }
- @media (max-width: 1000px) {
- .game-container {
- flex-direction: column;
- align-items: center;
- }
- .control-panel, .arena-container {
- width: 100%;
- max-width: 600px;
- }
- .arena-container {
- min-width: unset;
- min-height: 400px;
- }
- }
- </style>
- </head>
- <body>
- <header>
- <h1>Glyph Garden Gladiator</h1>
- <p class="subtitle">Cultivate warriors from living symbols in this strategic battle arena</p>
- </header>
- <div class="game-container">
- <div class="control-panel">
- <div class="control-section">
- <div class="battle-indicator" id="battle-indicator">
- ⚔️ BATTLE IN PROGRESS ⚔️
- </div>
- <h2>Glyph Selection</h2>
- <div class="glyph-selector" id="glyph-selector">
- <div class="glyph-option" data-glyph="⚔">⚔</div>
- <div class="glyph-option" data-glyph="🛡">🛡</div>
- <div class="glyph-option" data-glyph="🏹">🏹</div>
- <div class="glyph-option" data-glyph="🔥">🔥</div>
- <div class="glyph-option" data-glyph="💧">💧</div>
- <div class="glyph-option" data-glyph="🌪">🌪</div>
- <div class="glyph-option" data-glyph="🌟">🌟</div>
- <div class="glyph-option" data-glyph="☯">☯</div>
- <div class="glyph-option" data-glyph="⚡">⚡</div>
- </div>
- <button id="plant-btn">Plant Selected Glyph</button>
- <button id="prune-btn">Prune Overgrowth</button>
- </div>
- <div class="control-section">
- <h2>Garden Stats</h2>
- <div class="stats">
- <div class="stat-bar">
- <span class="stat-label">Soil Fertility:</span>
- <span class="stat-value" id="soil-value">75%</span>
- </div>
- <div class="progress-bar">
- <div class="progress-fill soil-fill" id="soil-bar" style="width: 75%"></div>
- </div>
- <div class="stat-bar">
- <span class="stat-label">Garden Health:</span>
- <span class="stat-value" id="health-value">85%</span>
- </div>
- <div class="progress-bar">
- <div class="progress-fill health-fill" id="health-bar" style="width: 85%"></div>
- </div>
- <div class="stat-bar">
- <span class="stat-label">Growth Level:</span>
- <span class="stat-value" id="growth-value">45%</span>
- </div>
- <div class="progress-bar">
- <div class="progress-fill growth-fill" id="growth-bar" style="width: 45%"></div>
- </div>
- <div class="stat-bar">
- <span class="stat-label">Yield:</span>
- <span class="stat-value" id="yield-value">0</span>
- </div>
- </div>
- </div>
- <div class="control-section">
- <h2>Battle Controls</h2>
- <button id="battle-btn">Start Battle</button>
- <button id="reset-btn">Reset Garden</button>
- </div>
- </div>
- <div class="arena-container">
- <div id="arena">
- <div class="soil-grid" id="soil-grid"></div>
- <!-- Glyph creatures will be dynamically added here -->
- </div>
- </div>
- </div>
- <div class="message-log" id="message-log">
- <div class="message plant">Welcome to Glyph Garden Gladiator! Select a glyph and plant it to begin.</div>
- </div>
- <div class="game-over-screen" id="game-over-screen">
- <div class="game-over-content">
- <h2>Game Over</h2>
- <p>Your garden health has reached 0%!</p>
- <p>Final Yield: <span id="final-yield">0</span></p>
- <button id="restart-btn">Play Again</button>
- </div>
- </div>
- <script>
- // Game state
- const gameState = {
- selectedGlyph: null,
- creatures: [],
- soilFertility: 75,
- gardenHealth: 85,
- growthLevel: 45,
- yield: 0,
- battleMode: false,
- lastPlanted: null,
- messageCount: 0,
- gameOver: false,
- battleInProgress: false,
- pendingRemovals: new Set()
- };
- // Glyph interactions matrix
- const glyphInteractions = {
- '⚔': { // Sword - Strong against shield, weak against water
- strongAgainst: ['🛡'],
- weakAgainst: ['💧'],
- yieldBonus: 1.2,
- soilEffect: 0.8
- },
- '🛡': { // Shield - Strong against bow, weak against sword
- strongAgainst: ['🏹'],
- weakAgainst: ['⚔'],
- yieldBonus: 0.8,
- soilEffect: 1.2
- },
- '🏹': { // Bow - Strong against fire, weak against shield
- strongAgainst: ['🔥'],
- weakAgainst: ['🛡'],
- yieldBonus: 1.1,
- soilEffect: 0.9
- },
- '🔥': { // Fire - Strong against nature, weak against water
- strongAgainst: ['🌟'],
- weakAgainst: ['💧'],
- yieldBonus: 1.3,
- soilEffect: 0.7
- },
- '💧': { // Water - Strong against fire and sword, weak against lightning
- strongAgainst: ['🔥', '⚔'],
- weakAgainst: ['⚡'],
- yieldBonus: 1.0,
- soilEffect: 1.1
- },
- '🌪': { // Wind - Strong against earth, weak against lightning
- strongAgainst: ['☯'],
- weakAgainst: ['⚡'],
- yieldBonus: 1.1,
- soilEffect: 1.0
- },
- '🌟': { // Star - Strong against darkness, weak against fire
- strongAgainst: ['☯'],
- weakAgainst: ['🔥'],
- yieldBonus: 1.4,
- soilEffect: 0.9
- },
- '☯': { // Yin Yang - Balanced, no particular strengths/weaknesses
- strongAgainst: [],
- weakAgainst: [],
- yieldBonus: 1.0,
- soilEffect: 1.0
- },
- '⚡': { // Lightning - Strong against water and wind, weak against earth
- strongAgainst: ['💧', '🌪'],
- weakAgainst: ['☯'],
- yieldBonus: 1.2,
- soilEffect: 0.8
- }
- };
- // DOM elements
- const arena = document.getElementById('arena');
- const messageLog = document.getElementById('message-log');
- const soilGrid = document.getElementById('soil-grid');
- const plantBtn = document.getElementById('plant-btn');
- const pruneBtn = document.getElementById('prune-btn');
- const battleBtn = document.getElementById('battle-btn');
- const resetBtn = document.getElementById('reset-btn');
- const gameOverScreen = document.getElementById('game-over-screen');
- const finalYield = document.getElementById('final-yield');
- const restartBtn = document.getElementById('restart-btn');
- const battleIndicator = document.getElementById('battle-indicator');
- const glyphSelector = document.getElementById('glyph-selector');
- // Initialize soil grid
- function initSoilGrid() {
- for (let i = 0; i < 100; i++) {
- const cell = document.createElement('div');
- cell.classList.add('soil-cell');
- // Randomly mark some cells as fertile
- if (Math.random() > 0.7) {
- cell.classList.add('fertile');
- }
- soilGrid.appendChild(cell);
- }
- }
- // Glyph selection
- document.querySelectorAll('.glyph-option').forEach(option => {
- option.addEventListener('click', () => {
- if (gameState.gameOver || gameState.battleMode) return;
- document.querySelectorAll('.glyph-option').forEach(opt => {
- opt.classList.remove('selected');
- });
- option.classList.add('selected');
- gameState.selectedGlyph = option.getAttribute('data-glyph');
- });
- });
- // Update battle UI state
- function updateBattleUI() {
- if (gameState.battleMode) {
- battleIndicator.classList.add('active');
- plantBtn.disabled = true;
- document.querySelectorAll('.glyph-option').forEach(opt => {
- opt.classList.add('disabled');
- });
- } else {
- battleIndicator.classList.remove('active');
- plantBtn.disabled = gameState.gameOver;
- document.querySelectorAll('.glyph-option').forEach(opt => {
- opt.classList.remove('disabled');
- });
- }
- }
- // Plant glyph
- plantBtn.addEventListener('click', () => {
- if (gameState.gameOver || gameState.battleMode) {
- if (gameState.battleMode) {
- addMessage('Cannot plant during battle! Wait for the battle to end.', 'plant');
- }
- return;
- }
- if (!gameState.selectedGlyph) {
- addMessage('Please select a glyph first!', 'plant');
- return;
- }
- if (gameState.creatures.length >= 8) {
- addMessage('Garden is full! Prune some creatures to plant more.', 'plant');
- return;
- }
- // Find a random position in the arena
- const arenaRect = arena.getBoundingClientRect();
- const size = 80 + Math.random() * 40;
- const x = Math.random() * (arenaRect.width - size);
- const y = Math.random() * (arenaRect.height - size);
- createGlyphCreature(gameState.selectedGlyph, x, y, size);
- gameState.lastPlanted = gameState.selectedGlyph;
- // Update stats
- gameState.soilFertility = Math.max(10, gameState.soilFertility - 5);
- gameState.growthLevel = Math.min(100, gameState.growthLevel + 10);
- updateStats();
- addMessage(`Planted ${gameState.selectedGlyph} glyph. It's beginning to sprout!`, 'plant');
- checkGameOver();
- });
- // Prune overgrowth
- pruneBtn.addEventListener('click', () => {
- if (gameState.gameOver) return;
- if (gameState.creatures.length === 0) {
- addMessage('No creatures to prune!', 'growth');
- return;
- }
- // Filter out creatures that are already being removed
- const availableCreatures = gameState.creatures.filter(c => !gameState.pendingRemovals.has(c.id));
- if (availableCreatures.length === 0) {
- addMessage('No creatures available to prune!', 'growth');
- return;
- }
- // Remove a random available creature
- const index = Math.floor(Math.random() * availableCreatures.length);
- const creature = availableCreatures[index];
- // Mark as pending removal
- gameState.pendingRemovals.add(creature.id);
- // Calculate yield from pruning
- const baseYield = 10 + Math.floor(creature.health / 10);
- const interaction = glyphInteractions[creature.glyph];
- const yieldBonus = interaction ? interaction.yieldBonus : 1;
- const yieldGained = Math.floor(baseYield * yieldBonus);
- gameState.yield += yieldGained;
- creature.element.style.opacity = '0';
- creature.element.style.transform = 'scale(0)';
- setTimeout(() => {
- if (arena.contains(creature.element)) {
- arena.removeChild(creature.element);
- }
- const actualIndex = gameState.creatures.findIndex(c => c.id === creature.id);
- if (actualIndex !== -1) {
- gameState.creatures.splice(actualIndex, 1);
- }
- gameState.pendingRemovals.delete(creature.id);
- }, 500);
- // Update stats
- gameState.soilFertility = Math.min(100, gameState.soilFertility + 10);
- gameState.growthLevel = Math.max(0, gameState.growthLevel - 15);
- gameState.gardenHealth = Math.min(100, gameState.gardenHealth + 5);
- updateStats();
- addMessage(`Pruned a ${creature.glyph} creature. Gained ${yieldGained} yield!`, 'growth');
- checkGameOver();
- });
- // Toggle battle mode
- battleBtn.addEventListener('click', () => {
- if (gameState.gameOver) return;
- if (gameState.creatures.length < 2 && !gameState.battleMode) {
- addMessage('Need at least 2 creatures to start a battle!', 'battle');
- return;
- }
- gameState.battleMode = !gameState.battleMode;
- battleBtn.textContent = gameState.battleMode ? 'Stop Battle' : 'Start Battle';
- updateBattleUI();
- // Show/hide health bars
- gameState.creatures.forEach(creature => {
- const healthBar = creature.element.querySelector('.creature-health-bar');
- healthBar.style.display = gameState.battleMode ? 'block' : 'none';
- });
- if (gameState.battleMode) {
- addMessage('Battle begun! Creatures will now fight for dominance.', 'battle');
- gameState.battleInProgress = true;
- startBattles();
- } else {
- addMessage('Battle stopped. Garden returns to peaceful growth.', 'battle');
- gameState.battleInProgress = false;
- }
- });
- // Reset garden
- resetBtn.addEventListener('click', () => {
- resetGame();
- });
- // Restart game
- restartBtn.addEventListener('click', () => {
- resetGame();
- gameOverScreen.style.display = 'none';
- });
- // Create a glyph creature
- function createGlyphCreature(glyph, x, y, size) {
- const creatureElement = document.createElement('div');
- creatureElement.classList.add('glyph-creature');
- creatureElement.style.left = `${x}px`;
- creatureElement.style.top = `${y}px`;
- creatureElement.style.width = `${size}px`;
- creatureElement.style.height = `${size}px`;
- // Create health bar
- const healthBar = document.createElement('div');
- healthBar.classList.add('creature-health-bar');
- const healthFill = document.createElement('div');
- healthFill.classList.add('creature-health-fill');
- healthBar.appendChild(healthFill);
- creatureElement.appendChild(healthBar);
- // Set color based on glyph
- const colors = {
- '⚔': '#ff5252', '🛡': '#2196f3', '🏹': '#ff9800',
- '🔥': '#ff5722', '💧': '#03a9f4', '🌪': '#9c27b0',
- '🌟': '#ffeb3b', '☯': '#e0e0e0', '⚡': '#ffc107'
- };
- const color = colors[glyph] || '#8bc34a';
- creatureElement.style.color = color;
- // Create creature body
- const body = document.createElement('div');
- body.classList.add('glyph-body');
- body.style.animation = 'sprout 1.5s ease-out';
- // Create glyph core
- const core = document.createElement('div');
- core.classList.add('glyph-core');
- core.textContent = glyph;
- body.appendChild(core);
- // Create limbs (procedural generation)
- const limbCount = 3 + Math.floor(Math.random() * 4);
- for (let i = 0; i < limbCount; i++) {
- const limb = document.createElement('div');
- limb.classList.add('glyph-limb');
- // Random limb properties
- const angle = (i / limbCount) * 360;
- const length = 20 + Math.random() * 30;
- const width = 5 + Math.random() * 10;
- limb.style.width = `${length}px`;
- limb.style.height = `${width}px`;
- limb.style.transform = `rotate(${angle}deg) translateX(${size/2 - length/2}px)`;
- body.appendChild(limb);
- }
- creatureElement.appendChild(body);
- arena.appendChild(creatureElement);
- // Create creature object with unique ID
- const creature = {
- id: Date.now() + Math.random(), // Unique ID to prevent ghost issues
- element: creatureElement,
- glyph: glyph,
- x: x,
- y: y,
- size: size,
- health: 80 + Math.floor(Math.random() * 20),
- maxHealth: 0, // Will be set to health after creation
- attack: 10 + Math.floor(Math.random() * 15),
- speed: 1 + Math.random() * 2,
- color: color,
- isAlive: true
- };
- creature.maxHealth = creature.health;
- gameState.creatures.push(creature);
- updateCreatureHealthBar(creature);
- return creature;
- }
- // Update creature health bar
- function updateCreatureHealthBar(creature) {
- if (!creature.isAlive) return;
- const healthFill = creature.element.querySelector('.creature-health-fill');
- const healthPercent = (creature.health / creature.maxHealth) * 100;
- healthFill.style.width = `${healthPercent}%`;
- // Change color based on health
- if (healthPercent > 70) {
- healthFill.style.background = 'linear-gradient(90deg, #4caf50, #8bc34a)';
- } else if (healthPercent > 30) {
- healthFill.style.background = 'linear-gradient(90deg, #ff9800, #ffc107)';
- } else {
- healthFill.style.background = 'linear-gradient(90deg, #f44336, #ff5722)';
- }
- }
- // Battle timer for continuous stat updates during battle
- let battleTimer = null;
- // Start creature battles
- function startBattles() {
- if (!gameState.battleMode || gameState.gameOver) {
- if (battleTimer) {
- clearInterval(battleTimer);
- battleTimer = null;
- }
- return;
- }
- // Filter out dead and pending removal creatures
- const aliveCreatures = gameState.creatures.filter(c =>
- c.isAlive && !gameState.pendingRemovals.has(c.id)
- );
- if (aliveCreatures.length < 2) {
- if (aliveCreatures.length === 1) {
- addMessage(`${aliveCreatures[0].glyph} is the champion of the garden!`, 'battle');
- }
- gameState.battleMode = false;
- gameState.battleInProgress = false;
- battleBtn.textContent = 'Start Battle';
- updateBattleUI();
- // Hide health bars
- gameState.creatures.forEach(creature => {
- const healthBar = creature.element.querySelector('.creature-health-bar');
- if (healthBar) healthBar.style.display = 'none';
- });
- if (battleTimer) {
- clearInterval(battleTimer);
- battleTimer = null;
- }
- return;
- }
- // Start battle timer for continuous stat changes
- if (!battleTimer) {
- battleTimer = setInterval(() => {
- if (gameState.battleMode && !gameState.gameOver) {
- // Decrease garden health and growth level during battle
- gameState.gardenHealth = Math.max(0, gameState.gardenHealth - 1);
- gameState.growthLevel = Math.max(0, gameState.growthLevel - 2);
- // Increase soil fertility during battle
- gameState.soilFertility = Math.min(100, gameState.soilFertility + 1);
- updateStats();
- checkGameOver();
- }
- }, 1000); // Update every second
- }
- // Randomly select two creatures to battle
- const indices = [];
- while (indices.length < 2) {
- const idx = Math.floor(Math.random() * aliveCreatures.length);
- if (!indices.includes(idx)) indices.push(idx);
- }
- const creature1 = aliveCreatures[indices[0]];
- const creature2 = aliveCreatures[indices[1]];
- // Animate attack
- creature1.element.style.animation = 'attack 0.5s ease-in-out';
- setTimeout(() => {
- creature1.element.style.animation = '';
- // Calculate damage with interaction bonuses
- let damage = Math.floor(creature1.attack * (0.5 + Math.random() * 0.5));
- // Apply interaction bonuses
- const interaction1 = glyphInteractions[creature1.glyph];
- const interaction2 = glyphInteractions[creature2.glyph];
- if (interaction1 && interaction1.strongAgainst.includes(creature2.glyph)) {
- damage = Math.floor(damage * 1.5);
- addMessage(`${creature1.glyph} is strong against ${creature2.glyph}!`, 'battle');
- }
- if (interaction2 && interaction2.strongAgainst.includes(creature1.glyph)) {
- damage = Math.floor(damage * 0.7);
- addMessage(`${creature2.glyph} resists ${creature1.glyph}'s attack!`, 'battle');
- }
- creature2.health -= damage;
- // Show damage indicator
- showDamage(creature2, damage);
- // Update creature health bar
- updateCreatureHealthBar(creature2);
- addMessage(`${creature1.glyph} attacks ${creature2.glyph} for ${damage} damage!`, 'battle');
- // Check if creature is defeated
- if (creature2.health <= 0 && creature2.isAlive) {
- creature2.isAlive = false;
- gameState.pendingRemovals.add(creature2.id);
- addMessage(`${creature2.glyph} has been defeated!`, 'battle');
- // Calculate yield and effects from defeat
- const baseYield = 15 + Math.floor(creature2.maxHealth / 10);
- const yieldBonus = interaction1 ? interaction1.yieldBonus : 1;
- const yieldGained = Math.floor(baseYield * yieldBonus);
- gameState.yield += yieldGained;
- creature2.element.style.animation = 'takeDamage 0.5s ease-in-out';
- setTimeout(() => {
- if (arena.contains(creature2.element)) {
- arena.removeChild(creature2.element);
- }
- const removeIndex = gameState.creatures.findIndex(c => c.id === creature2.id);
- if (removeIndex !== -1) {
- gameState.creatures.splice(removeIndex, 1);
- }
- gameState.pendingRemovals.delete(creature2.id);
- addMessage(`Gained ${yieldGained} yield from defeated ${creature2.glyph}!`, 'battle');
- }, 500);
- }
- // Continue battles if still in battle mode
- if (gameState.battleMode) {
- setTimeout(startBattles, 1500);
- }
- }, 500);
- }
- // Show damage indicator
- function showDamage(creature, damage) {
- const damageElement = document.createElement('div');
- damageElement.classList.add('damage-indicator');
- damageElement.textContent = `-${damage}`;
- damageElement.style.left = `${creature.x + creature.size/2}px`;
- damageElement.style.top = `${creature.y}px`;
- arena.appendChild(damageElement);
- setTimeout(() => {
- if (arena.contains(damageElement)) {
- arena.removeChild(damageElement);
- }
- }, 1000);
- }
- // Update stats display with change indicators
- function updateStats() {
- const prevSoil = parseInt(document.getElementById('soil-value').textContent);
- const prevHealth = parseInt(document.getElementById('health-value').textContent);
- const prevGrowth = parseInt(document.getElementById('growth-value').textContent);
- document.getElementById('soil-value').textContent = `${gameState.soilFertility}%`;
- document.getElementById('soil-bar').style.width = `${gameState.soilFertility}%`;
- document.getElementById('health-value').textContent = `${gameState.gardenHealth}%`;
- document.getElementById('health-bar').style.width = `${gameState.gardenHealth}%`;
- document.getElementById('growth-value').textContent = `${gameState.growthLevel}%`;
- document.getElementById('growth-bar').style.width = `${gameState.growthLevel}%`;
- document.getElementById('yield-value').textContent = gameState.yield;
- // Color health bar red when low
- const healthBar = document.getElementById('health-bar');
- if (gameState.gardenHealth <= 20) {
- healthBar.style.background = 'linear-gradient(90deg, #d32f2f, #f44336)';
- } else if (gameState.gardenHealth <= 50) {
- healthBar.style.background = 'linear-gradient(90deg, #f44336, #ff9800)';
- } else {
- healthBar.style.background = 'linear-gradient(90deg, #ff9800, #ffc107)';
- }
- }
- // Add message to log
- function addMessage(text, type) {
- const messageElement = document.createElement('div');
- messageElement.classList.add('message', type);
- messageElement.textContent = text;
- messageLog.appendChild(messageElement);
- // Limit message count
- gameState.messageCount++;
- if (gameState.messageCount > 10) {
- messageLog.removeChild(messageLog.firstChild);
- }
- // Auto-scroll to bottom
- messageLog.scrollTop = messageLog.scrollHeight;
- }
- // Check if game is over
- function checkGameOver() {
- if (gameState.gardenHealth <= 0 && !gameState.gameOver) {
- gameState.gameOver = true;
- gameState.battleMode = false;
- gameState.battleInProgress = false;
- battleBtn.textContent = 'Start Battle';
- updateBattleUI();
- if (battleTimer) {
- clearInterval(battleTimer);
- battleTimer = null;
- }
- // Disable buttons
- plantBtn.disabled = true;
- pruneBtn.disabled = true;
- battleBtn.disabled = true;
- // Show game over screen
- finalYield.textContent = gameState.yield;
- gameOverScreen.style.display = 'flex';
- addMessage('Game Over! Your garden health has reached 0%.', 'game-over');
- }
- }
- // Reset the game
- function resetGame() {
- // Clear battle timer
- if (battleTimer) {
- clearInterval(battleTimer);
- battleTimer = null;
- }
- // Remove all creatures
- gameState.creatures.forEach(creature => {
- if (arena.contains(creature.element)) {
- arena.removeChild(creature.element);
- }
- });
- // Reset game state
- gameState.creatures = [];
- gameState.soilFertility = 75;
- gameState.gardenHealth = 85;
- gameState.growthLevel = 45;
- gameState.yield = 0;
- gameState.battleMode = false;
- gameState.battleInProgress = false;
- gameState.gameOver = false;
- gameState.selectedGlyph = null;
- gameState.pendingRemovals.clear();
- // Reset UI
- battleBtn.textContent = 'Start Battle';
- plantBtn.disabled = false;
- pruneBtn.disabled = false;
- battleBtn.disabled = false;
- updateBattleUI();
- // Clear message log
- messageLog.innerHTML = '';
- addMessage('Garden has been reset. Ready for new plantings!', 'plant');
- // Update stats
- updateStats();
- // Plant a few initial glyphs
- setTimeout(() => {
- const initialGlyphs = ['⚔', '🛡', '🏹'];
- initialGlyphs.forEach(glyph => {
- gameState.selectedGlyph = glyph;
- const arenaRect = arena.getBoundingClientRect();
- const size = 80 + Math.random() * 40;
- const x = Math.random() * (arenaRect.width - size);
- const y = Math.random() * (arenaRect.height - size);
- createGlyphCreature(glyph, x, y, size);
- });
- addMessage('Initial glyphs have been planted. The garden is growing!', 'plant');
- }, 500);
- }
- // Initialize the game
- function init() {
- initSoilGrid();
- updateStats();
- // Plant a few initial glyphs
- setTimeout(() => {
- const initialGlyphs = ['⚔', '🛡', '🏹'];
- initialGlyphs.forEach(glyph => {
- gameState.selectedGlyph = glyph;
- const arenaRect = arena.getBoundingClientRect();
- const size = 80 + Math.random() * 40;
- const x = Math.random() * (arenaRect.width - size);
- const y = Math.random() * (arenaRect.height - size);
- createGlyphCreature(glyph, x, y, size);
- });
- addMessage('Initial glyphs have been planted. The garden is growing!', 'plant');
- }, 1000);
- }
- // Start the game
- init();
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment