XTaylorSpenceX

Glyph Garden Gladiator

Sep 30th, 2025
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 43.35 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Glyph Garden Gladiator</title>
  7.     <style>
  8.         * {
  9.             margin: 0;
  10.             padding: 0;
  11.             box-sizing: border-box;
  12.             font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  13.         }
  14.  
  15.         body {
  16.             background: linear-gradient(135deg, #1a2a3a, #0d1b2a);
  17.             color: #e0e0e0;
  18.             min-height: 100vh;
  19.             display: flex;
  20.             flex-direction: column;
  21.             align-items: center;
  22.             padding: 20px;
  23.         }
  24.  
  25.         header {
  26.             text-align: center;
  27.             margin-bottom: 30px;
  28.             width: 100%;
  29.             max-width: 1200px;
  30.         }
  31.  
  32.         h1 {
  33.             font-size: 3.5rem;
  34.             margin-bottom: 10px;
  35.             background: linear-gradient(45deg, #8bc34a, #4caf50);
  36.             -webkit-background-clip: text;
  37.             background-clip: text;
  38.             color: transparent;
  39.             text-shadow: 0 0 10px rgba(139, 195, 74, 0.3);
  40.         }
  41.  
  42.         .subtitle {
  43.             font-size: 1.2rem;
  44.             margin-bottom: 20px;
  45.             color: #a5d6a7;
  46.         }
  47.  
  48.         .game-container {
  49.             display: flex;
  50.             flex-wrap: wrap;
  51.             gap: 30px;
  52.             justify-content: center;
  53.             width: 100%;
  54.             max-width: 1200px;
  55.         }
  56.  
  57.         .control-panel {
  58.             background: rgba(30, 40, 50, 0.8);
  59.             border-radius: 15px;
  60.             padding: 20px;
  61.             width: 300px;
  62.             box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
  63.             backdrop-filter: blur(5px);
  64.         }
  65.  
  66.         .control-section {
  67.             margin-bottom: 25px;
  68.         }
  69.  
  70.         h2 {
  71.             font-size: 1.5rem;
  72.             margin-bottom: 15px;
  73.             color: #8bc34a;
  74.             border-bottom: 2px solid #4caf50;
  75.             padding-bottom: 5px;
  76.         }
  77.  
  78.         .glyph-selector {
  79.             display: grid;
  80.             grid-template-columns: repeat(3, 1fr);
  81.             gap: 10px;
  82.             margin-bottom: 15px;
  83.         }
  84.  
  85.         .glyph-option {
  86.             background: rgba(60, 80, 100, 0.7);
  87.             border: 2px solid #4caf50;
  88.             border-radius: 8px;
  89.             height: 60px;
  90.             display: flex;
  91.             align-items: center;
  92.             justify-content: center;
  93.             font-size: 2rem;
  94.             cursor: pointer;
  95.             transition: all 0.3s;
  96.         }
  97.  
  98.         .glyph-option:hover {
  99.             background: rgba(76, 175, 80, 0.3);
  100.             transform: scale(1.05);
  101.         }
  102.  
  103.         .glyph-option.selected {
  104.             background: rgba(76, 175, 80, 0.5);
  105.             box-shadow: 0 0 15px rgba(76, 175, 80, 0.7);
  106.         }
  107.  
  108.         .glyph-option.disabled {
  109.             opacity: 0.5;
  110.             cursor: not-allowed;
  111.             transform: none !important;
  112.         }
  113.  
  114.         button {
  115.             background: linear-gradient(45deg, #4caf50, #8bc34a);
  116.             border: none;
  117.             border-radius: 8px;
  118.             color: white;
  119.             padding: 12px 20px;
  120.             font-size: 1rem;
  121.             font-weight: bold;
  122.             cursor: pointer;
  123.             transition: all 0.3s;
  124.             width: 100%;
  125.             margin-bottom: 10px;
  126.         }
  127.  
  128.         button:hover:not(:disabled) {
  129.             transform: translateY(-2px);
  130.             box-shadow: 0 5px 15px rgba(76, 175, 80, 0.4);
  131.         }
  132.  
  133.         button:disabled {
  134.             background: #546e7a;
  135.             cursor: not-allowed;
  136.             transform: none;
  137.             box-shadow: none;
  138.         }
  139.  
  140.         .battle-indicator {
  141.             background: rgba(244, 67, 54, 0.3);
  142.             border: 2px solid #f44336;
  143.             border-radius: 8px;
  144.             padding: 10px;
  145.             margin-bottom: 15px;
  146.             text-align: center;
  147.             font-weight: bold;
  148.             color: #ff5252;
  149.             display: none;
  150.         }
  151.  
  152.         .battle-indicator.active {
  153.             display: block;
  154.             animation: pulse 1s infinite;
  155.         }
  156.  
  157.         .stats {
  158.             display: flex;
  159.             flex-direction: column;
  160.             gap: 10px;
  161.         }
  162.  
  163.         .stat-bar {
  164.             display: flex;
  165.             justify-content: space-between;
  166.             align-items: center;
  167.         }
  168.  
  169.         .stat-label {
  170.             font-size: 0.9rem;
  171.         }
  172.  
  173.         .stat-value {
  174.             font-weight: bold;
  175.             color: #8bc34a;
  176.         }
  177.  
  178.         .stat-change {
  179.             font-size: 0.8rem;
  180.             margin-left: 5px;
  181.             animation: fadeOut 2s forwards;
  182.         }
  183.  
  184.         .stat-change.positive {
  185.             color: #4caf50;
  186.         }
  187.  
  188.         .stat-change.negative {
  189.             color: #f44336;
  190.         }
  191.  
  192.         .progress-bar {
  193.             height: 10px;
  194.             width: 100%;
  195.             background: rgba(60, 80, 100, 0.7);
  196.             border-radius: 5px;
  197.             margin-top: 5px;
  198.             overflow: hidden;
  199.         }
  200.  
  201.         .progress-fill {
  202.             height: 100%;
  203.             border-radius: 5px;
  204.             transition: width 0.5s;
  205.         }
  206.  
  207.         .health-fill {
  208.             background: linear-gradient(90deg, #f44336, #ff9800);
  209.         }
  210.  
  211.         .growth-fill {
  212.             background: linear-gradient(90deg, #4caf50, #8bc34a);
  213.         }
  214.  
  215.         .soil-fill {
  216.             background: linear-gradient(90deg, #795548, #a1887f);
  217.         }
  218.  
  219.         .arena-container {
  220.             flex: 1;
  221.             min-width: 600px;
  222.             min-height: 600px;
  223.             position: relative;
  224.             background: rgba(20, 30, 40, 0.7);
  225.             border-radius: 15px;
  226.             overflow: hidden;
  227.             box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
  228.         }
  229.  
  230.         #arena {
  231.             width: 100%;
  232.             height: 100%;
  233.             position: relative;
  234.         }
  235.  
  236.         .glyph-creature {
  237.             position: absolute;
  238.             display: flex;
  239.             flex-direction: column;
  240.             align-items: center;
  241.             justify-content: center;
  242.             font-size: 2.5rem;
  243.             border-radius: 50%;
  244.             transition: transform 0.3s, opacity 0.3s;
  245.             z-index: 10;
  246.             text-shadow: 0 0 10px rgba(0, 0, 0, 0.7);
  247.         }
  248.  
  249.         .creature-health-bar {
  250.             width: 80%;
  251.             height: 8px;
  252.             background: rgba(0, 0, 0, 0.5);
  253.             border-radius: 4px;
  254.             margin-bottom: 5px;
  255.             overflow: hidden;
  256.             display: none;
  257.         }
  258.  
  259.         .creature-health-fill {
  260.             height: 100%;
  261.             background: linear-gradient(90deg, #4caf50, #8bc34a);
  262.             transition: width 0.3s;
  263.             width: 100%;
  264.         }
  265.  
  266.         .glyph-body {
  267.             position: relative;
  268.             width: 100%;
  269.             height: 100%;
  270.             display: flex;
  271.             align-items: center;
  272.             justify-content: center;
  273.             border-radius: 50%;
  274.             animation: pulse 2s infinite alternate;
  275.         }
  276.  
  277.         .glyph-core {
  278.             font-size: 1.5em;
  279.             z-index: 2;
  280.         }
  281.  
  282.         .glyph-limb {
  283.             position: absolute;
  284.             background: currentColor;
  285.             border-radius: 5px;
  286.             transform-origin: center;
  287.         }
  288.  
  289.         .damage-indicator {
  290.             position: absolute;
  291.             color: #ff5252;
  292.             font-weight: bold;
  293.             animation: floatUp 1s forwards;
  294.             pointer-events: none;
  295.             z-index: 100;
  296.         }
  297.  
  298.         .soil-grid {
  299.             position: absolute;
  300.             top: 0;
  301.             left: 0;
  302.             width: 100%;
  303.             height: 100%;
  304.             display: grid;
  305.             grid-template-columns: repeat(10, 1fr);
  306.             grid-template-rows: repeat(10, 1fr);
  307.             opacity: 0.3;
  308.             z-index: 1;
  309.         }
  310.  
  311.         .soil-cell {
  312.             border: 1px solid rgba(139, 195, 74, 0.1);
  313.         }
  314.  
  315.         .soil-cell.fertile {
  316.             background: rgba(139, 195, 74, 0.1);
  317.         }
  318.  
  319.         .message-log {
  320.             background: rgba(30, 40, 50, 0.8);
  321.             border-radius: 15px;
  322.             padding: 20px;
  323.             width: 100%;
  324.             max-width: 1200px;
  325.             margin-top: 30px;
  326.             height: 150px;
  327.             overflow-y: auto;
  328.             box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
  329.         }
  330.  
  331.         .message {
  332.             margin-bottom: 8px;
  333.             padding: 5px 10px;
  334.             border-radius: 5px;
  335.             font-size: 0.9rem;
  336.         }
  337.  
  338.         .message.plant {
  339.             background: rgba(76, 175, 80, 0.2);
  340.             border-left: 3px solid #4caf50;
  341.         }
  342.  
  343.         .message.battle {
  344.             background: rgba(244, 67, 54, 0.2);
  345.             border-left: 3px solid #f44336;
  346.         }
  347.  
  348.         .message.growth {
  349.             background: rgba(255, 152, 0, 0.2);
  350.             border-left: 3px solid #ff9800;
  351.         }
  352.  
  353.         .message.game-over {
  354.             background: rgba(244, 67, 54, 0.5);
  355.             border-left: 3px solid #f44336;
  356.             font-weight: bold;
  357.         }
  358.  
  359.         .game-over-screen {
  360.             position: fixed;
  361.             top: 0;
  362.             left: 0;
  363.             width: 100%;
  364.             height: 100%;
  365.             background: rgba(0, 0, 0, 0.8);
  366.             display: flex;
  367.             flex-direction: column;
  368.             align-items: center;
  369.             justify-content: center;
  370.             z-index: 1000;
  371.             display: none;
  372.         }
  373.  
  374.         .game-over-content {
  375.             background: rgba(30, 40, 50, 0.95);
  376.             padding: 40px;
  377.             border-radius: 15px;
  378.             text-align: center;
  379.             max-width: 500px;
  380.             width: 90%;
  381.             box-shadow: 0 0 30px rgba(0, 0, 0, 0.7);
  382.         }
  383.  
  384.         .game-over-content h2 {
  385.             font-size: 2.5rem;
  386.             color: #f44336;
  387.             margin-bottom: 20px;
  388.         }
  389.  
  390.         .game-over-content p {
  391.             margin-bottom: 20px;
  392.             font-size: 1.2rem;
  393.         }
  394.  
  395.         @keyframes pulse {
  396.             0% { transform: scale(1); }
  397.             100% { transform: scale(1.05); }
  398.         }
  399.  
  400.         @keyframes floatUp {
  401.             0% { transform: translateY(0); opacity: 1; }
  402.             100% { transform: translateY(-30px); opacity: 0; }
  403.         }
  404.  
  405.         @keyframes fadeOut {
  406.             0% { opacity: 1; }
  407.             100% { opacity: 0; }
  408.         }
  409.  
  410.         @keyframes sprout {
  411.             0% { transform: scale(0) rotate(0deg); opacity: 0; }
  412.             50% { transform: scale(1.2) rotate(5deg); opacity: 0.8; }
  413.             100% { transform: scale(1) rotate(0deg); opacity: 1; }
  414.         }
  415.  
  416.         @keyframes attack {
  417.             0% { transform: translateX(0) scale(1); }
  418.             50% { transform: translateX(20px) scale(1.2); }
  419.             100% { transform: translateX(0) scale(1); }
  420.         }
  421.  
  422.         @keyframes takeDamage {
  423.             0% { transform: scale(1); }
  424.             50% { transform: scale(1.1); background-color: rgba(255, 0, 0, 0.5); }
  425.             100% { transform: scale(1); }
  426.         }
  427.  
  428.         @media (max-width: 1000px) {
  429.             .game-container {
  430.                 flex-direction: column;
  431.                 align-items: center;
  432.             }
  433.            
  434.             .control-panel, .arena-container {
  435.                 width: 100%;
  436.                 max-width: 600px;
  437.             }
  438.            
  439.             .arena-container {
  440.                 min-width: unset;
  441.                 min-height: 400px;
  442.             }
  443.         }
  444.     </style>
  445. </head>
  446. <body>
  447.     <header>
  448.         <h1>Glyph Garden Gladiator</h1>
  449.         <p class="subtitle">Cultivate warriors from living symbols in this strategic battle arena</p>
  450.     </header>
  451.  
  452.     <div class="game-container">
  453.         <div class="control-panel">
  454.             <div class="control-section">
  455.                 <div class="battle-indicator" id="battle-indicator">
  456.                     ⚔️ BATTLE IN PROGRESS ⚔️
  457.                 </div>
  458.                 <h2>Glyph Selection</h2>
  459.                 <div class="glyph-selector" id="glyph-selector">
  460.                     <div class="glyph-option" data-glyph="⚔"></div>
  461.                     <div class="glyph-option" data-glyph="🛡">🛡</div>
  462.                     <div class="glyph-option" data-glyph="🏹">🏹</div>
  463.                     <div class="glyph-option" data-glyph="🔥">🔥</div>
  464.                     <div class="glyph-option" data-glyph="💧">💧</div>
  465.                     <div class="glyph-option" data-glyph="🌪">🌪</div>
  466.                     <div class="glyph-option" data-glyph="🌟">🌟</div>
  467.                     <div class="glyph-option" data-glyph="☯"></div>
  468.                     <div class="glyph-option" data-glyph="⚡"></div>
  469.                 </div>
  470.                 <button id="plant-btn">Plant Selected Glyph</button>
  471.                 <button id="prune-btn">Prune Overgrowth</button>
  472.             </div>
  473.  
  474.             <div class="control-section">
  475.                 <h2>Garden Stats</h2>
  476.                 <div class="stats">
  477.                     <div class="stat-bar">
  478.                         <span class="stat-label">Soil Fertility:</span>
  479.                         <span class="stat-value" id="soil-value">75%</span>
  480.                     </div>
  481.                     <div class="progress-bar">
  482.                         <div class="progress-fill soil-fill" id="soil-bar" style="width: 75%"></div>
  483.                     </div>
  484.  
  485.                     <div class="stat-bar">
  486.                         <span class="stat-label">Garden Health:</span>
  487.                         <span class="stat-value" id="health-value">85%</span>
  488.                     </div>
  489.                     <div class="progress-bar">
  490.                         <div class="progress-fill health-fill" id="health-bar" style="width: 85%"></div>
  491.                     </div>
  492.  
  493.                     <div class="stat-bar">
  494.                         <span class="stat-label">Growth Level:</span>
  495.                         <span class="stat-value" id="growth-value">45%</span>
  496.                     </div>
  497.                     <div class="progress-bar">
  498.                         <div class="progress-fill growth-fill" id="growth-bar" style="width: 45%"></div>
  499.                     </div>
  500.                    
  501.                     <div class="stat-bar">
  502.                         <span class="stat-label">Yield:</span>
  503.                         <span class="stat-value" id="yield-value">0</span>
  504.                     </div>
  505.                 </div>
  506.             </div>
  507.  
  508.             <div class="control-section">
  509.                 <h2>Battle Controls</h2>
  510.                 <button id="battle-btn">Start Battle</button>
  511.                 <button id="reset-btn">Reset Garden</button>
  512.             </div>
  513.         </div>
  514.  
  515.         <div class="arena-container">
  516.             <div id="arena">
  517.                 <div class="soil-grid" id="soil-grid"></div>
  518.                 <!-- Glyph creatures will be dynamically added here -->
  519.             </div>
  520.         </div>
  521.     </div>
  522.  
  523.     <div class="message-log" id="message-log">
  524.         <div class="message plant">Welcome to Glyph Garden Gladiator! Select a glyph and plant it to begin.</div>
  525.     </div>
  526.  
  527.     <div class="game-over-screen" id="game-over-screen">
  528.         <div class="game-over-content">
  529.             <h2>Game Over</h2>
  530.             <p>Your garden health has reached 0%!</p>
  531.             <p>Final Yield: <span id="final-yield">0</span></p>
  532.             <button id="restart-btn">Play Again</button>
  533.         </div>
  534.     </div>
  535.  
  536.     <script>
  537.         // Game state
  538.         const gameState = {
  539.             selectedGlyph: null,
  540.             creatures: [],
  541.             soilFertility: 75,
  542.             gardenHealth: 85,
  543.             growthLevel: 45,
  544.             yield: 0,
  545.             battleMode: false,
  546.             lastPlanted: null,
  547.             messageCount: 0,
  548.             gameOver: false,
  549.             battleInProgress: false,
  550.             pendingRemovals: new Set()
  551.         };
  552.  
  553.         // Glyph interactions matrix
  554.         const glyphInteractions = {
  555.             '⚔': { // Sword - Strong against shield, weak against water
  556.                 strongAgainst: ['🛡'],
  557.                 weakAgainst: ['💧'],
  558.                 yieldBonus: 1.2,
  559.                 soilEffect: 0.8
  560.             },
  561.             '🛡': { // Shield - Strong against bow, weak against sword
  562.                 strongAgainst: ['🏹'],
  563.                 weakAgainst: ['⚔'],
  564.                 yieldBonus: 0.8,
  565.                 soilEffect: 1.2
  566.             },
  567.             '🏹': { // Bow - Strong against fire, weak against shield
  568.                 strongAgainst: ['🔥'],
  569.                 weakAgainst: ['🛡'],
  570.                 yieldBonus: 1.1,
  571.                 soilEffect: 0.9
  572.             },
  573.             '🔥': { // Fire - Strong against nature, weak against water
  574.                 strongAgainst: ['🌟'],
  575.                 weakAgainst: ['💧'],
  576.                 yieldBonus: 1.3,
  577.                 soilEffect: 0.7
  578.             },
  579.             '💧': { // Water - Strong against fire and sword, weak against lightning
  580.                 strongAgainst: ['🔥', '⚔'],
  581.                 weakAgainst: ['⚡'],
  582.                 yieldBonus: 1.0,
  583.                 soilEffect: 1.1
  584.             },
  585.             '🌪': { // Wind - Strong against earth, weak against lightning
  586.                 strongAgainst: ['☯'],
  587.                 weakAgainst: ['⚡'],
  588.                 yieldBonus: 1.1,
  589.                 soilEffect: 1.0
  590.             },
  591.             '🌟': { // Star - Strong against darkness, weak against fire
  592.                 strongAgainst: ['☯'],
  593.                 weakAgainst: ['🔥'],
  594.                 yieldBonus: 1.4,
  595.                 soilEffect: 0.9
  596.             },
  597.             '☯': { // Yin Yang - Balanced, no particular strengths/weaknesses
  598.                 strongAgainst: [],
  599.                 weakAgainst: [],
  600.                 yieldBonus: 1.0,
  601.                 soilEffect: 1.0
  602.             },
  603.             '⚡': { // Lightning - Strong against water and wind, weak against earth
  604.                 strongAgainst: ['💧', '🌪'],
  605.                 weakAgainst: ['☯'],
  606.                 yieldBonus: 1.2,
  607.                 soilEffect: 0.8
  608.             }
  609.         };
  610.  
  611.         // DOM elements
  612.         const arena = document.getElementById('arena');
  613.         const messageLog = document.getElementById('message-log');
  614.         const soilGrid = document.getElementById('soil-grid');
  615.         const plantBtn = document.getElementById('plant-btn');
  616.         const pruneBtn = document.getElementById('prune-btn');
  617.         const battleBtn = document.getElementById('battle-btn');
  618.         const resetBtn = document.getElementById('reset-btn');
  619.         const gameOverScreen = document.getElementById('game-over-screen');
  620.         const finalYield = document.getElementById('final-yield');
  621.         const restartBtn = document.getElementById('restart-btn');
  622.         const battleIndicator = document.getElementById('battle-indicator');
  623.         const glyphSelector = document.getElementById('glyph-selector');
  624.  
  625.         // Initialize soil grid
  626.         function initSoilGrid() {
  627.             for (let i = 0; i < 100; i++) {
  628.                const cell = document.createElement('div');
  629.                cell.classList.add('soil-cell');
  630.                // Randomly mark some cells as fertile
  631.                if (Math.random() > 0.7) {
  632.                     cell.classList.add('fertile');
  633.                 }
  634.                 soilGrid.appendChild(cell);
  635.             }
  636.         }
  637.  
  638.         // Glyph selection
  639.         document.querySelectorAll('.glyph-option').forEach(option => {
  640.             option.addEventListener('click', () => {
  641.                 if (gameState.gameOver || gameState.battleMode) return;
  642.                
  643.                 document.querySelectorAll('.glyph-option').forEach(opt => {
  644.                     opt.classList.remove('selected');
  645.                 });
  646.                 option.classList.add('selected');
  647.                 gameState.selectedGlyph = option.getAttribute('data-glyph');
  648.             });
  649.         });
  650.  
  651.         // Update battle UI state
  652.         function updateBattleUI() {
  653.             if (gameState.battleMode) {
  654.                 battleIndicator.classList.add('active');
  655.                 plantBtn.disabled = true;
  656.                 document.querySelectorAll('.glyph-option').forEach(opt => {
  657.                     opt.classList.add('disabled');
  658.                 });
  659.             } else {
  660.                 battleIndicator.classList.remove('active');
  661.                 plantBtn.disabled = gameState.gameOver;
  662.                 document.querySelectorAll('.glyph-option').forEach(opt => {
  663.                     opt.classList.remove('disabled');
  664.                 });
  665.             }
  666.         }
  667.  
  668.         // Plant glyph
  669.         plantBtn.addEventListener('click', () => {
  670.             if (gameState.gameOver || gameState.battleMode) {
  671.                 if (gameState.battleMode) {
  672.                     addMessage('Cannot plant during battle! Wait for the battle to end.', 'plant');
  673.                 }
  674.                 return;
  675.             }
  676.            
  677.             if (!gameState.selectedGlyph) {
  678.                 addMessage('Please select a glyph first!', 'plant');
  679.                 return;
  680.             }
  681.  
  682.             if (gameState.creatures.length >= 8) {
  683.                 addMessage('Garden is full! Prune some creatures to plant more.', 'plant');
  684.                 return;
  685.             }
  686.  
  687.             // Find a random position in the arena
  688.             const arenaRect = arena.getBoundingClientRect();
  689.             const size = 80 + Math.random() * 40;
  690.             const x = Math.random() * (arenaRect.width - size);
  691.             const y = Math.random() * (arenaRect.height - size);
  692.  
  693.             createGlyphCreature(gameState.selectedGlyph, x, y, size);
  694.             gameState.lastPlanted = gameState.selectedGlyph;
  695.  
  696.             // Update stats
  697.             gameState.soilFertility = Math.max(10, gameState.soilFertility - 5);
  698.             gameState.growthLevel = Math.min(100, gameState.growthLevel + 10);
  699.             updateStats();
  700.  
  701.             addMessage(`Planted ${gameState.selectedGlyph} glyph. It's beginning to sprout!`, 'plant');
  702.            
  703.             checkGameOver();
  704.         });
  705.  
  706.         // Prune overgrowth
  707.         pruneBtn.addEventListener('click', () => {
  708.             if (gameState.gameOver) return;
  709.            
  710.             if (gameState.creatures.length === 0) {
  711.                 addMessage('No creatures to prune!', 'growth');
  712.                 return;
  713.             }
  714.  
  715.             // Filter out creatures that are already being removed
  716.             const availableCreatures = gameState.creatures.filter(c => !gameState.pendingRemovals.has(c.id));
  717.            
  718.             if (availableCreatures.length === 0) {
  719.                 addMessage('No creatures available to prune!', 'growth');
  720.                 return;
  721.             }
  722.  
  723.             // Remove a random available creature
  724.             const index = Math.floor(Math.random() * availableCreatures.length);
  725.             const creature = availableCreatures[index];
  726.            
  727.             // Mark as pending removal
  728.             gameState.pendingRemovals.add(creature.id);
  729.            
  730.             // Calculate yield from pruning
  731.             const baseYield = 10 + Math.floor(creature.health / 10);
  732.             const interaction = glyphInteractions[creature.glyph];
  733.             const yieldBonus = interaction ? interaction.yieldBonus : 1;
  734.             const yieldGained = Math.floor(baseYield * yieldBonus);
  735.            
  736.             gameState.yield += yieldGained;
  737.            
  738.             creature.element.style.opacity = '0';
  739.             creature.element.style.transform = 'scale(0)';
  740.            
  741.             setTimeout(() => {
  742.                 if (arena.contains(creature.element)) {
  743.                     arena.removeChild(creature.element);
  744.                 }
  745.                 const actualIndex = gameState.creatures.findIndex(c => c.id === creature.id);
  746.                 if (actualIndex !== -1) {
  747.                     gameState.creatures.splice(actualIndex, 1);
  748.                 }
  749.                 gameState.pendingRemovals.delete(creature.id);
  750.             }, 500);
  751.  
  752.             // Update stats
  753.             gameState.soilFertility = Math.min(100, gameState.soilFertility + 10);
  754.             gameState.growthLevel = Math.max(0, gameState.growthLevel - 15);
  755.             gameState.gardenHealth = Math.min(100, gameState.gardenHealth + 5);
  756.             updateStats();
  757.  
  758.             addMessage(`Pruned a ${creature.glyph} creature. Gained ${yieldGained} yield!`, 'growth');
  759.            
  760.             checkGameOver();
  761.         });
  762.  
  763.         // Toggle battle mode
  764.         battleBtn.addEventListener('click', () => {
  765.             if (gameState.gameOver) return;
  766.            
  767.             if (gameState.creatures.length < 2 && !gameState.battleMode) {
  768.                addMessage('Need at least 2 creatures to start a battle!', 'battle');
  769.                return;
  770.            }
  771.            
  772.            gameState.battleMode = !gameState.battleMode;
  773.            battleBtn.textContent = gameState.battleMode ? 'Stop Battle' : 'Start Battle';
  774.            
  775.            updateBattleUI();
  776.            
  777.            // Show/hide health bars
  778.            gameState.creatures.forEach(creature => {
  779.                 const healthBar = creature.element.querySelector('.creature-health-bar');
  780.                 healthBar.style.display = gameState.battleMode ? 'block' : 'none';
  781.             });
  782.            
  783.             if (gameState.battleMode) {
  784.                 addMessage('Battle begun! Creatures will now fight for dominance.', 'battle');
  785.                 gameState.battleInProgress = true;
  786.                 startBattles();
  787.             } else {
  788.                 addMessage('Battle stopped. Garden returns to peaceful growth.', 'battle');
  789.                 gameState.battleInProgress = false;
  790.             }
  791.         });
  792.  
  793.         // Reset garden
  794.         resetBtn.addEventListener('click', () => {
  795.             resetGame();
  796.         });
  797.  
  798.         // Restart game
  799.         restartBtn.addEventListener('click', () => {
  800.             resetGame();
  801.             gameOverScreen.style.display = 'none';
  802.         });
  803.  
  804.         // Create a glyph creature
  805.         function createGlyphCreature(glyph, x, y, size) {
  806.             const creatureElement = document.createElement('div');
  807.             creatureElement.classList.add('glyph-creature');
  808.             creatureElement.style.left = `${x}px`;
  809.             creatureElement.style.top = `${y}px`;
  810.             creatureElement.style.width = `${size}px`;
  811.             creatureElement.style.height = `${size}px`;
  812.            
  813.             // Create health bar
  814.             const healthBar = document.createElement('div');
  815.             healthBar.classList.add('creature-health-bar');
  816.             const healthFill = document.createElement('div');
  817.             healthFill.classList.add('creature-health-fill');
  818.             healthBar.appendChild(healthFill);
  819.             creatureElement.appendChild(healthBar);
  820.            
  821.             // Set color based on glyph
  822.             const colors = {
  823.                 '⚔': '#ff5252', '🛡': '#2196f3', '🏹': '#ff9800',
  824.                 '🔥': '#ff5722', '💧': '#03a9f4', '🌪': '#9c27b0',
  825.                 '🌟': '#ffeb3b', '☯': '#e0e0e0', '⚡': '#ffc107'
  826.             };
  827.             const color = colors[glyph] || '#8bc34a';
  828.             creatureElement.style.color = color;
  829.  
  830.             // Create creature body
  831.             const body = document.createElement('div');
  832.             body.classList.add('glyph-body');
  833.             body.style.animation = 'sprout 1.5s ease-out';
  834.  
  835.             // Create glyph core
  836.             const core = document.createElement('div');
  837.             core.classList.add('glyph-core');
  838.             core.textContent = glyph;
  839.             body.appendChild(core);
  840.  
  841.             // Create limbs (procedural generation)
  842.             const limbCount = 3 + Math.floor(Math.random() * 4);
  843.             for (let i = 0; i < limbCount; i++) {
  844.                const limb = document.createElement('div');
  845.                limb.classList.add('glyph-limb');
  846.                
  847.                // Random limb properties
  848.                const angle = (i / limbCount) * 360;
  849.                const length = 20 + Math.random() * 30;
  850.                const width = 5 + Math.random() * 10;
  851.                
  852.                limb.style.width = `${length}px`;
  853.                limb.style.height = `${width}px`;
  854.                limb.style.transform = `rotate(${angle}deg) translateX(${size/2 - length/2}px)`;
  855.                
  856.                body.appendChild(limb);
  857.            }
  858.  
  859.            creatureElement.appendChild(body);
  860.            arena.appendChild(creatureElement);
  861.  
  862.            // Create creature object with unique ID
  863.            const creature = {
  864.                id: Date.now() + Math.random(), // Unique ID to prevent ghost issues
  865.                element: creatureElement,
  866.                glyph: glyph,
  867.                x: x,
  868.                y: y,
  869.                size: size,
  870.                health: 80 + Math.floor(Math.random() * 20),
  871.                maxHealth: 0, // Will be set to health after creation
  872.                attack: 10 + Math.floor(Math.random() * 15),
  873.                speed: 1 + Math.random() * 2,
  874.                color: color,
  875.                isAlive: true
  876.            };
  877.            
  878.            creature.maxHealth = creature.health;
  879.  
  880.            gameState.creatures.push(creature);
  881.            updateCreatureHealthBar(creature);
  882.            return creature;
  883.        }
  884.  
  885.        // Update creature health bar
  886.        function updateCreatureHealthBar(creature) {
  887.            if (!creature.isAlive) return;
  888.            
  889.            const healthFill = creature.element.querySelector('.creature-health-fill');
  890.            const healthPercent = (creature.health / creature.maxHealth) * 100;
  891.            healthFill.style.width = `${healthPercent}%`;
  892.            
  893.            // Change color based on health
  894.            if (healthPercent > 70) {
  895.                 healthFill.style.background = 'linear-gradient(90deg, #4caf50, #8bc34a)';
  896.             } else if (healthPercent > 30) {
  897.                 healthFill.style.background = 'linear-gradient(90deg, #ff9800, #ffc107)';
  898.             } else {
  899.                 healthFill.style.background = 'linear-gradient(90deg, #f44336, #ff5722)';
  900.             }
  901.         }
  902.  
  903.         // Battle timer for continuous stat updates during battle
  904.         let battleTimer = null;
  905.  
  906.         // Start creature battles
  907.         function startBattles() {
  908.             if (!gameState.battleMode || gameState.gameOver) {
  909.                 if (battleTimer) {
  910.                     clearInterval(battleTimer);
  911.                     battleTimer = null;
  912.                 }
  913.                 return;
  914.             }
  915.  
  916.             // Filter out dead and pending removal creatures
  917.             const aliveCreatures = gameState.creatures.filter(c =>
  918.                 c.isAlive && !gameState.pendingRemovals.has(c.id)
  919.            );
  920.  
  921.             if (aliveCreatures.length < 2) {
  922.                if (aliveCreatures.length === 1) {
  923.                    addMessage(`${aliveCreatures[0].glyph} is the champion of the garden!`, 'battle');
  924.                }
  925.                gameState.battleMode = false;
  926.                gameState.battleInProgress = false;
  927.                battleBtn.textContent = 'Start Battle';
  928.                updateBattleUI();
  929.                
  930.                // Hide health bars
  931.                gameState.creatures.forEach(creature => {
  932.                     const healthBar = creature.element.querySelector('.creature-health-bar');
  933.                     if (healthBar) healthBar.style.display = 'none';
  934.                 });
  935.                
  936.                 if (battleTimer) {
  937.                     clearInterval(battleTimer);
  938.                     battleTimer = null;
  939.                 }
  940.                 return;
  941.             }
  942.  
  943.             // Start battle timer for continuous stat changes
  944.             if (!battleTimer) {
  945.                 battleTimer = setInterval(() => {
  946.                     if (gameState.battleMode && !gameState.gameOver) {
  947.                        // Decrease garden health and growth level during battle
  948.                        gameState.gardenHealth = Math.max(0, gameState.gardenHealth - 1);
  949.                         gameState.growthLevel = Math.max(0, gameState.growthLevel - 2);
  950.                         // Increase soil fertility during battle
  951.                         gameState.soilFertility = Math.min(100, gameState.soilFertility + 1);
  952.                         updateStats();
  953.                         checkGameOver();
  954.                     }
  955.                 }, 1000); // Update every second
  956.             }
  957.  
  958.             // Randomly select two creatures to battle
  959.             const indices = [];
  960.             while (indices.length < 2) {
  961.                const idx = Math.floor(Math.random() * aliveCreatures.length);
  962.                if (!indices.includes(idx)) indices.push(idx);
  963.            }
  964.  
  965.            const creature1 = aliveCreatures[indices[0]];
  966.            const creature2 = aliveCreatures[indices[1]];
  967.  
  968.            // Animate attack
  969.            creature1.element.style.animation = 'attack 0.5s ease-in-out';
  970.            setTimeout(() => {
  971.                 creature1.element.style.animation = '';
  972.                
  973.                 // Calculate damage with interaction bonuses
  974.                 let damage = Math.floor(creature1.attack * (0.5 + Math.random() * 0.5));
  975.                
  976.                 // Apply interaction bonuses
  977.                 const interaction1 = glyphInteractions[creature1.glyph];
  978.                 const interaction2 = glyphInteractions[creature2.glyph];
  979.                
  980.                 if (interaction1 && interaction1.strongAgainst.includes(creature2.glyph)) {
  981.                    damage = Math.floor(damage * 1.5);
  982.                     addMessage(`${creature1.glyph} is strong against ${creature2.glyph}!`, 'battle');
  983.                 }
  984.                
  985.                 if (interaction2 && interaction2.strongAgainst.includes(creature1.glyph)) {
  986.                    damage = Math.floor(damage * 0.7);
  987.                     addMessage(`${creature2.glyph} resists ${creature1.glyph}'s attack!`, 'battle');
  988.                 }
  989.                
  990.                 creature2.health -= damage;
  991.                
  992.                 // Show damage indicator
  993.                 showDamage(creature2, damage);
  994.                
  995.                 // Update creature health bar
  996.                 updateCreatureHealthBar(creature2);
  997.                
  998.                 addMessage(`${creature1.glyph} attacks ${creature2.glyph} for ${damage} damage!`, 'battle');
  999.                
  1000.                 // Check if creature is defeated
  1001.                 if (creature2.health <= 0 && creature2.isAlive) {
  1002.                    creature2.isAlive = false;
  1003.                    gameState.pendingRemovals.add(creature2.id);
  1004.                    
  1005.                    addMessage(`${creature2.glyph} has been defeated!`, 'battle');
  1006.                    
  1007.                    // Calculate yield and effects from defeat
  1008.                    const baseYield = 15 + Math.floor(creature2.maxHealth / 10);
  1009.                    const yieldBonus = interaction1 ? interaction1.yieldBonus : 1;
  1010.                    const yieldGained = Math.floor(baseYield * yieldBonus);
  1011.                    
  1012.                    gameState.yield += yieldGained;
  1013.                    
  1014.                    creature2.element.style.animation = 'takeDamage 0.5s ease-in-out';
  1015.                    setTimeout(() => {
  1016.                         if (arena.contains(creature2.element)) {
  1017.                             arena.removeChild(creature2.element);
  1018.                         }
  1019.                         const removeIndex = gameState.creatures.findIndex(c => c.id === creature2.id);
  1020.                         if (removeIndex !== -1) {
  1021.                             gameState.creatures.splice(removeIndex, 1);
  1022.                         }
  1023.                         gameState.pendingRemovals.delete(creature2.id);
  1024.                        
  1025.                         addMessage(`Gained ${yieldGained} yield from defeated ${creature2.glyph}!`, 'battle');
  1026.                     }, 500);
  1027.                 }
  1028.                
  1029.                 // Continue battles if still in battle mode
  1030.                 if (gameState.battleMode) {
  1031.                     setTimeout(startBattles, 1500);
  1032.                 }
  1033.             }, 500);
  1034.         }
  1035.  
  1036.         // Show damage indicator
  1037.         function showDamage(creature, damage) {
  1038.             const damageElement = document.createElement('div');
  1039.             damageElement.classList.add('damage-indicator');
  1040.             damageElement.textContent = `-${damage}`;
  1041.             damageElement.style.left = `${creature.x + creature.size/2}px`;
  1042.             damageElement.style.top = `${creature.y}px`;
  1043.             arena.appendChild(damageElement);
  1044.            
  1045.             setTimeout(() => {
  1046.                 if (arena.contains(damageElement)) {
  1047.                     arena.removeChild(damageElement);
  1048.                 }
  1049.             }, 1000);
  1050.         }
  1051.  
  1052.         // Update stats display with change indicators
  1053.         function updateStats() {
  1054.             const prevSoil = parseInt(document.getElementById('soil-value').textContent);
  1055.             const prevHealth = parseInt(document.getElementById('health-value').textContent);
  1056.             const prevGrowth = parseInt(document.getElementById('growth-value').textContent);
  1057.            
  1058.             document.getElementById('soil-value').textContent = `${gameState.soilFertility}%`;
  1059.             document.getElementById('soil-bar').style.width = `${gameState.soilFertility}%`;
  1060.            
  1061.             document.getElementById('health-value').textContent = `${gameState.gardenHealth}%`;
  1062.             document.getElementById('health-bar').style.width = `${gameState.gardenHealth}%`;
  1063.            
  1064.             document.getElementById('growth-value').textContent = `${gameState.growthLevel}%`;
  1065.             document.getElementById('growth-bar').style.width = `${gameState.growthLevel}%`;
  1066.            
  1067.             document.getElementById('yield-value').textContent = gameState.yield;
  1068.            
  1069.             // Color health bar red when low
  1070.             const healthBar = document.getElementById('health-bar');
  1071.             if (gameState.gardenHealth <= 20) {
  1072.                healthBar.style.background = 'linear-gradient(90deg, #d32f2f, #f44336)';
  1073.            } else if (gameState.gardenHealth <= 50) {
  1074.                healthBar.style.background = 'linear-gradient(90deg, #f44336, #ff9800)';
  1075.            } else {
  1076.                healthBar.style.background = 'linear-gradient(90deg, #ff9800, #ffc107)';
  1077.            }
  1078.        }
  1079.  
  1080.        // Add message to log
  1081.        function addMessage(text, type) {
  1082.            const messageElement = document.createElement('div');
  1083.            messageElement.classList.add('message', type);
  1084.            messageElement.textContent = text;
  1085.            messageLog.appendChild(messageElement);
  1086.            
  1087.            // Limit message count
  1088.            gameState.messageCount++;
  1089.            if (gameState.messageCount > 10) {
  1090.                 messageLog.removeChild(messageLog.firstChild);
  1091.             }
  1092.            
  1093.             // Auto-scroll to bottom
  1094.             messageLog.scrollTop = messageLog.scrollHeight;
  1095.         }
  1096.  
  1097.         // Check if game is over
  1098.         function checkGameOver() {
  1099.             if (gameState.gardenHealth <= 0 && !gameState.gameOver) {
  1100.                gameState.gameOver = true;
  1101.                gameState.battleMode = false;
  1102.                gameState.battleInProgress = false;
  1103.                battleBtn.textContent = 'Start Battle';
  1104.                updateBattleUI();
  1105.                
  1106.                if (battleTimer) {
  1107.                    clearInterval(battleTimer);
  1108.                    battleTimer = null;
  1109.                }
  1110.                
  1111.                // Disable buttons
  1112.                plantBtn.disabled = true;
  1113.                pruneBtn.disabled = true;
  1114.                battleBtn.disabled = true;
  1115.                
  1116.                // Show game over screen
  1117.                finalYield.textContent = gameState.yield;
  1118.                gameOverScreen.style.display = 'flex';
  1119.                
  1120.                addMessage('Game Over! Your garden health has reached 0%.', 'game-over');
  1121.            }
  1122.        }
  1123.  
  1124.        // Reset the game
  1125.        function resetGame() {
  1126.            // Clear battle timer
  1127.            if (battleTimer) {
  1128.                clearInterval(battleTimer);
  1129.                battleTimer = null;
  1130.            }
  1131.            
  1132.            // Remove all creatures
  1133.            gameState.creatures.forEach(creature => {
  1134.                 if (arena.contains(creature.element)) {
  1135.                     arena.removeChild(creature.element);
  1136.                 }
  1137.             });
  1138.            
  1139.             // Reset game state
  1140.             gameState.creatures = [];
  1141.             gameState.soilFertility = 75;
  1142.             gameState.gardenHealth = 85;
  1143.             gameState.growthLevel = 45;
  1144.             gameState.yield = 0;
  1145.             gameState.battleMode = false;
  1146.             gameState.battleInProgress = false;
  1147.             gameState.gameOver = false;
  1148.             gameState.selectedGlyph = null;
  1149.             gameState.pendingRemovals.clear();
  1150.            
  1151.             // Reset UI
  1152.             battleBtn.textContent = 'Start Battle';
  1153.             plantBtn.disabled = false;
  1154.             pruneBtn.disabled = false;
  1155.             battleBtn.disabled = false;
  1156.             updateBattleUI();
  1157.            
  1158.             // Clear message log
  1159.             messageLog.innerHTML = '';
  1160.             addMessage('Garden has been reset. Ready for new plantings!', 'plant');
  1161.            
  1162.             // Update stats
  1163.             updateStats();
  1164.            
  1165.             // Plant a few initial glyphs
  1166.             setTimeout(() => {
  1167.                 const initialGlyphs = ['⚔', '🛡', '🏹'];
  1168.                 initialGlyphs.forEach(glyph => {
  1169.                     gameState.selectedGlyph = glyph;
  1170.                     const arenaRect = arena.getBoundingClientRect();
  1171.                     const size = 80 + Math.random() * 40;
  1172.                     const x = Math.random() * (arenaRect.width - size);
  1173.                     const y = Math.random() * (arenaRect.height - size);
  1174.                     createGlyphCreature(glyph, x, y, size);
  1175.                 });
  1176.                
  1177.                 addMessage('Initial glyphs have been planted. The garden is growing!', 'plant');
  1178.             }, 500);
  1179.         }
  1180.  
  1181.         // Initialize the game
  1182.         function init() {
  1183.             initSoilGrid();
  1184.             updateStats();
  1185.            
  1186.             // Plant a few initial glyphs
  1187.             setTimeout(() => {
  1188.                 const initialGlyphs = ['⚔', '🛡', '🏹'];
  1189.                 initialGlyphs.forEach(glyph => {
  1190.                     gameState.selectedGlyph = glyph;
  1191.                     const arenaRect = arena.getBoundingClientRect();
  1192.                     const size = 80 + Math.random() * 40;
  1193.                     const x = Math.random() * (arenaRect.width - size);
  1194.                     const y = Math.random() * (arenaRect.height - size);
  1195.                     createGlyphCreature(glyph, x, y, size);
  1196.                 });
  1197.                
  1198.                 addMessage('Initial glyphs have been planted. The garden is growing!', 'plant');
  1199.             }, 1000);
  1200.         }
  1201.  
  1202.         // Start the game
  1203.         init();
  1204.     </script>
  1205. </body>
  1206. </html>
  1207.  
Advertisement
Add Comment
Please, Sign In to add comment