Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>WebCraft - Minecraft Inspired Game</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| user-select: none; | |
| } | |
| :root { | |
| --grass: #7CB342; | |
| --grass-side: #689F38; | |
| --dirt: #8D6E63; | |
| --stone: #757575; | |
| --wood: #6D4C41; | |
| --wood-top: #5D4037; | |
| --leaves: #2E7D32; | |
| --water: #42A5F5; | |
| --sand: #FFD54F; | |
| --coal: #424242; | |
| --iron: #B0BEC5; | |
| --gold: #FFD700; | |
| --diamond: #00BCD4; | |
| --bedrock: #212121; | |
| --sky-day: linear-gradient(to bottom, #87CEEB 0%, #98D8E8 100%); | |
| --sky-night: linear-gradient(to bottom, #0C1445 0%, #183059 100%); | |
| --sun: #FFD700; | |
| --moon: #F0F0F0; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| overflow: hidden; | |
| background: var(--sky-day); | |
| transition: background 2s ease; | |
| position: relative; | |
| height: 100vh; | |
| } | |
| body.night { | |
| background: var(--sky-night); | |
| } | |
| header { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| z-index: 1000; | |
| padding: 15px 20px; | |
| background: linear-gradient(to bottom, rgba(0,0,0,0.7), transparent); | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| color: white; | |
| } | |
| .logo { | |
| font-size: 24px; | |
| font-weight: bold; | |
| text-shadow: 2px 2px 4px rgba(0,0,0,0.5); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .logo::before { | |
| content: "⛏️"; | |
| font-size: 28px; | |
| } | |
| .stats { | |
| display: flex; | |
| gap: 30px; | |
| font-size: 14px; | |
| text-shadow: 1px 1px 2px rgba(0,0,0,0.5); | |
| } | |
| .stat-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| } | |
| .celestial-body { | |
| position: absolute; | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| top: 80px; | |
| transition: all 2s ease; | |
| box-shadow: 0 0 30px rgba(255, 255, 255, 0.8); | |
| } | |
| .sun { | |
| background: var(--sun); | |
| right: 100px; | |
| } | |
| .moon { | |
| background: var(--moon); | |
| right: 100px; | |
| box-shadow: 0 0 20px rgba(255, 255, 255, 0.5); | |
| } | |
| .night .sun { | |
| transform: translateY(100vh); | |
| opacity: 0; | |
| } | |
| .night .moon { | |
| transform: translateY(0); | |
| opacity: 1; | |
| } | |
| .sun { | |
| transform: translateY(0); | |
| opacity: 1; | |
| } | |
| .night .sun ~ .moon { | |
| transform: translateY(0); | |
| } | |
| .game-container { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| perspective: 1000px; | |
| } | |
| .world { | |
| position: relative; | |
| transform-style: preserve-3d; | |
| transform: rotateX(30deg) rotateY(45deg); | |
| transition: transform 0.3s ease; | |
| } | |
| .chunk { | |
| position: absolute; | |
| transform-style: preserve-3d; | |
| } | |
| .block { | |
| position: absolute; | |
| width: 32px; | |
| height: 32px; | |
| transform-style: preserve-3d; | |
| cursor: pointer; | |
| transition: transform 0.2s ease; | |
| } | |
| .block:hover { | |
| transform: scale(1.05); | |
| filter: brightness(1.2); | |
| } | |
| .block-face { | |
| position: absolute; | |
| width: 32px; | |
| height: 32px; | |
| border: 1px solid rgba(0,0,0,0.2); | |
| image-rendering: pixelated; | |
| } | |
| .block-face.top { | |
| transform: rotateX(90deg) translateZ(16px); | |
| } | |
| .block-face.front { | |
| transform: translateZ(16px); | |
| } | |
| .block-face.back { | |
| transform: rotateY(180deg) translateZ(16px); | |
| } | |
| .block-face.left { | |
| transform: rotateY(-90deg) translateZ(16px); | |
| } | |
| .block-face.right { | |
| transform: rotateY(90deg) translateZ(16px); | |
| } | |
| .block-face.bottom { | |
| transform: rotateX(-90deg) translateZ(16px); | |
| } | |
| .grass .top { background: var(--grass); } | |
| .grass .front, .grass .back, .grass .left, .grass .right { background: var(--grass-side); } | |
| .grass .bottom { background: var(--dirt); } | |
| .dirt .top, .dirt .front, .dirt .back, .dirt .left, .dirt .right, .dirt .bottom { | |
| background: var(--dirt); | |
| } | |
| .stone .top, .stone .front, .stone .back, .stone .left, .stone .right, .stone .bottom { | |
| background: var(--stone); | |
| } | |
| .wood .top, .wood .bottom { background: var(--wood-top); } | |
| .wood .front, .wood .back, .wood .left, .wood .right { background: var(--wood); } | |
| .leaves .top, .leaves .front, .leaves .back, .leaves .left, .leaves .right, .leaves .bottom { | |
| background: var(--leaves); | |
| opacity: 0.9; | |
| } | |
| .water .top, .water .front, .water .back, .water .left, .water .right, .water .bottom { | |
| background: var(--water); | |
| opacity: 0.7; | |
| } | |
| .sand .top, .sand .front, .sand .back, .sand .left, .sand .right, .sand .bottom { | |
| background: var(--sand); | |
| } | |
| .coal .top, .coal .front, .coal .back, .coal .left, .coal .right, .coal .bottom { | |
| background: var(--coal); | |
| } | |
| .iron .top, .iron .front, .iron .back, .iron .left, .iron .right, .iron .bottom { | |
| background: var(--iron); | |
| } | |
| .gold .top, .gold .front, .gold .back, .gold .left, .gold .right, .gold .bottom { | |
| background: var(--gold); | |
| } | |
| .diamond .top, .diamond .front, .diamond .back, .diamond .left, .diamond .right, .diamond .bottom { | |
| background: var(--diamond); | |
| } | |
| .bedrock .top, .bedrock .front, .bedrock .back, .bedrock .left, .bedrock .right, .bedrock .bottom { | |
| background: var(--bedrock); | |
| } | |
| .inventory { | |
| position: absolute; | |
| bottom: 30px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| display: flex; | |
| gap: 10px; | |
| padding: 15px; | |
| background: rgba(0,0,0,0.8); | |
| border-radius: 10px; | |
| z-index: 1000; | |
| } | |
| .inventory-slot { | |
| width: 60px; | |
| height: 60px; | |
| background: rgba(255,255,255,0.1); | |
| border: 2px solid rgba(255,255,255,0.3); | |
| border-radius: 5px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| position: relative; | |
| } | |
| .inventory-slot:hover { | |
| background: rgba(255,255,255,0.2); | |
| transform: scale(1.1); | |
| } | |
| .inventory-slot.active { | |
| border-color: #FFD700; | |
| background: rgba(255,215,0,0.3); | |
| box-shadow: 0 0 10px rgba(255,215,0,0.5); | |
| } | |
| .block-preview { | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 3px; | |
| image-rendering: pixelated; | |
| } | |
| .controls { | |
| position: absolute; | |
| top: 80px; | |
| left: 20px; | |
| background: rgba(0,0,0,0.7); | |
| color: white; | |
| padding: 15px; | |
| border-radius: 10px; | |
| font-size: 12px; | |
| z-index: 1000; | |
| max-width: 200px; | |
| } | |
| .controls h3 { | |
| margin-bottom: 10px; | |
| color: #FFD700; | |
| } | |
| .control-item { | |
| margin: 5px 0; | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| } | |
| .key { | |
| background: rgba(255,255,255,0.2); | |
| padding: 2px 6px; | |
| border-radius: 3px; | |
| font-weight: bold; | |
| } | |
| .cloud { | |
| position: absolute; | |
| background: white; | |
| border-radius: 100px; | |
| opacity: 0.7; | |
| animation: float 20s infinite ease-in-out; | |
| } | |
| .cloud::before, | |
| .cloud::after { | |
| content: ''; | |
| position: absolute; | |
| background: white; | |
| border-radius: 100px; | |
| } | |
| .cloud1 { | |
| width: 100px; | |
| height: 40px; | |
| top: 20%; | |
| left: -100px; | |
| } | |
| .cloud1::before { | |
| width: 50px; | |
| height: 50px; | |
| top: -25px; | |
| left: 10px; | |
| } | |
| .cloud1::after { | |
| width: 60px; | |
| height: 40px; | |
| top: -15px; | |
| right: 10px; | |
| } | |
| @keyframes float { | |
| 0% { transform: translateX(0); } | |
| 100% { transform: translateX(calc(100vw + 200px)); } | |
| } | |
| .particle { | |
| position: absolute; | |
| width: 4px; | |
| height: 4px; | |
| background: rgba(255,255,255,0.8); | |
| pointer-events: none; | |
| animation: particle-fall 1s ease-out forwards; | |
| } | |
| @keyframes particle-fall { | |
| 0% { | |
| transform: translate(0, 0) scale(1); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: translate(var(--dx), var(--dy)) scale(0); | |
| opacity: 0; | |
| } | |
| } | |
| .build-mode { | |
| position: absolute; | |
| top: 50%; | |
| right: 20px; | |
| transform: translateY(-50%); | |
| background: rgba(0,0,0,0.7); | |
| color: white; | |
| padding: 10px; | |
| border-radius: 10px; | |
| font-size: 14px; | |
| z-index: 1000; | |
| } | |
| .mode-indicator { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 10px; | |
| } | |
| .mode-toggle { | |
| background: rgba(255,255,255,0.2); | |
| border: none; | |
| color: white; | |
| padding: 5px 10px; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| } | |
| .mode-toggle:hover { | |
| background: rgba(255,255,255,0.3); | |
| } | |
| .mode-toggle.active { | |
| background: #4CAF50; | |
| } | |
| @media (max-width: 768px) { | |
| .controls { | |
| display: none; | |
| } | |
| .inventory { | |
| bottom: 10px; | |
| padding: 10px; | |
| gap: 5px; | |
| } | |
| .inventory-slot { | |
| width: 50px; | |
| height: 50px; | |
| } | |
| .block-preview { | |
| width: 30px; | |
| height: 30px; | |
| } | |
| .stats { | |
| font-size: 12px; | |
| gap: 15px; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="logo"> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: white; text-decoration: none;"> | |
| WebCraft | |
| </a> | |
| </div> | |
| <div class="stats"> | |
| <div class="stat-item"> | |
| <span>📍</span> | |
| <span id="position">X:0 Y:0 Z:0</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span>🧱</span> | |
| <span id="blockCount">0</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span>⏰</span> | |
| <span id="time">Day</span> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="celestial-body sun"></div> | |
| <div class="celestial-body moon"></div> | |
| <div class="cloud cloud1"></div> | |
| <div class="controls"> | |
| <h3>🎮 Controls</h3> | |
| <div class="control-item"> | |
| <span class="key">WASD</span> Move | |
| </div> | |
| <div class="control-item"> | |
| <span class="key">Q/E</span> Rotate view | |
| </div> | |
| <div class="control-item"> | |
| <span class="key">Left Click</span> Break block | |
| </div> | |
| <div class="control-item"> | |
| <span class="key">Right Click</span> Place block | |
| </div> | |
| <div class="control-item"> | |
| <span class="key">1-9</span> Select block | |
| </div> | |
| <div class="control-item"> | |
| <span class="key">G</span> Generate terrain | |
| </div> | |
| <div class="control-item"> | |
| <span class="key">N</span> Toggle day/night | |
| </div> | |
| </div> | |
| <div class="build-mode"> | |
| <div class="mode-indicator"> | |
| <span>🔨 Build Mode</span> | |
| <button class="mode-toggle active" id="buildToggle">ON</button> | |
| </div> | |
| </div> | |
| <div class="game-container"> | |
| <div class="world" id="world"></div> | |
| </div> | |
| <div class="inventory"> | |
| <div class="inventory-slot active" data-block="grass"> | |
| <div class="block-preview" style="background: var(--grass);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="dirt"> | |
| <div class="block-preview" style="background: var(--dirt);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="stone"> | |
| <div class="block-preview" style="background: var(--stone);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="wood"> | |
| <div class="block-preview" style="background: var(--wood);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="leaves"> | |
| <div class="block-preview" style="background: var(--leaves);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="water"> | |
| <div class="block-preview" style="background: var(--water);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="sand"> | |
| <div class="block-preview" style="background: var(--sand);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="diamond"> | |
| <div class="block-preview" style="background: var(--diamond);"></div> | |
| </div> | |
| <div class="inventory-slot" data-block="gold"> | |
| <div class="block-preview" style="background: var(--gold);"></div> | |
| </div> | |
| </div> | |
| <script> | |
| class MinecraftGame { | |
| constructor() { | |
| this.world = document.getElementById('world'); | |
| this.blocks = new Map(); | |
| this.selectedBlock = 'grass'; | |
| this.playerPos = { x: 0, y: 5, z: 0 }; | |
| this.rotation = { x: 30, y: 45 }; | |
| this.isNight = false; | |
| this.buildMode = true; | |
| this.worldSize = 20; | |
| this.blockCount = 0; | |
| this.init(); | |
| } | |
| init() { | |
| this.generateTerrain(); | |
| this.setupEventListeners(); | |
| this.updateStats(); | |
| this.startDayNightCycle(); | |
| } | |
| generateTerrain() { | |
| // Clear existing world | |
| this.world.innerHTML = ''; | |
| this.blocks.clear(); | |
| this.blockCount = 0; | |
| // Generate terrain using simplex-like noise | |
| for (let x = -this.worldSize; x <= this.worldSize; x++) { | |
| for (let z = -this.worldSize; z <= this.worldSize; z++) { | |
| const height = Math.floor(this.getTerrainHeight(x, z)); | |
| for (let y = 0; y <= height; y++) { | |
| let blockType = 'stone'; | |
| if (y === height) { | |
| if (y > 8) { | |
| blockType = Math.random() > 0.8 ? 'snow' : 'grass'; | |
| } else if (y > 2) { | |
| blockType = 'grass'; | |
| } else { | |
| blockType = 'sand'; | |
| } | |
| } else if (y > height - 3) { | |
| blockType = 'dirt'; | |
| } | |
| // Add ores | |
| if (y < height - 3 && Math.random() < 0.05) { | |
| blockType = Math.random() > 0.5 ? 'coal' : 'iron'; | |
| } | |
| if (y < height - 5 && Math.random() < 0.02) { | |
| blockType = 'gold'; | |
| } | |
| if (y < height - 7 && Math.random() < 0.01) { | |
| blockType = 'diamond'; | |
| } | |
| this.createBlock(x, y, z, blockType); | |
| } | |
| } | |
| } | |
| // Add some trees | |
| for (let i = 0; i < 10; i++) { | |
| const treeX = Math.floor(Math.random() * this.worldSize * 2) - this.worldSize; | |
| const treeZ = Math.floor(Math.random() * this.worldSize * 2) - this.worldSize; | |
| const treeY = this.getTerrainHeight(treeX, treeZ) + 1; | |
| if (treeY > 2) { | |
| this.generateTree(treeX, treeY, treeZ); | |
| } | |
| } | |
| // Add water pools | |
| for (let i = 0; i < 5; i++) { | |
| const waterX = Math.floor(Math.random() * this.worldSize * 2) - this.worldSize; | |
| const waterZ = Math.floor(Math.random() * this.worldSize * 2) - this.worldSize; | |
| const waterY = this.getTerrainHeight(waterX, waterZ); | |
| if (waterY <= 1) { | |
| for (let dx = -2; dx <= 2; dx++) { | |
| for (let dz = -2; dz <= 2; dz++) { | |
| if (Math.abs(dx) + Math.abs(dz) <= 2) { | |
| const key = `${waterX + dx},${waterY},${waterZ + dz}`; | |
| const existingBlock = this.world.querySelector(`[data-key="${key}"]`); | |
| if (existingBlock) { | |
| existingBlock.remove(); | |
| this.blocks.delete(key); | |
| } | |
| this.createBlock(waterX + dx, waterY, waterZ + dz, 'water'); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| this.updateStats(); | |
| } | |
| getTerrainHeight(x, z) { | |
| // Simple terrain generation using sine waves | |
| const scale = 0.1; | |
| const height1 = Math.sin(x * scale) * 3 + Math.cos(z * scale) * 3; | |
| const height2 = Math.sin(x * scale * 2) * 1.5 + Math.cos(z * scale * 2) * 1.5; | |
| const height3 = Math.sin(x * scale * 0.5) * 2 + Math.cos(z * scale * 0.5) * 2; | |
| return Math.floor(5 + height1 + height2 + height3); | |
| } | |
| generateTree(x, y, z) { | |
| // Tree trunk | |
| for (let i = 0; i < 5; i++) { | |
| this.createBlock(x, y + i, z, 'wood'); | |
| } | |
| // Tree leaves | |
| for (let dx = -2; dx <= 2; dx++) { | |
| for (let dy = 3; dy <= 5; dy++) { | |
| for (let dz = -2; dz <= 2; dz++) { | |
| if (Math.abs(dx) + Math.abs(dz) <= 3) { | |
| const key = `${x + dx},${y + dy},${z + dz}`; | |
| if (!this.blocks.has(key)) { | |
| this.createBlock(x + dx, y + dy, z + dz, 'leaves'); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| createBlock(x, y, z, type) { | |
| const key = `${x},${y},${z}`; | |
| if (this.blocks.has(key)) return; | |
| const block = document.createElement('div'); | |
| block.className = `block ${type}`; | |
| block.dataset.key = key; | |
| block.dataset.type = type; | |
| // Create all 6 faces | |
| const faces = ['top', 'bottom', 'front', 'back', 'left', 'right']; | |
| faces.forEach(face => { | |
| const faceDiv = document.createElement('div'); | |
| faceDiv.className = `block-face ${face}`; | |
| block.appendChild(faceDiv); | |
| }); | |
| // Position the block | |
| block.style.transform = `translate3d(${x * 32}px, ${-y * 32}px, ${z * 32}px)`; | |
| // Add event listeners | |
| block.addEventListener('click', (e) => this.onBlockClick(e, x, y, z)); | |
| block.addEventListener('contextmenu', (e) => this.onBlockRightClick(e, x, y, z)); | |
| this.world.appendChild(block); | |
| this.blocks.set(key, type); | |
| this.blockCount++; | |
| } | |
| removeBlock(x, y, z) { | |
| const key = `${x},${y},${z}`; | |
| const block = this.world.querySelector(`[data-key="${key}"]`); | |
| if (block) { | |
| // Create particle effect | |
| this.createParticles(x, y, z); | |
| block.remove(); | |
| this.blocks.delete(key); | |
| this.blockCount--; | |
| this.updateStats(); | |
| } | |
| } | |
| onBlockClick(e, x, y, z) { | |
| e.preventDefault(); | |
| if (!this.buildMode) return; | |
| this.removeBlock(x, y, z); | |
| } | |
| onBlockRightClick(e, x, y, z) { | |
| e.preventDefault(); | |
| if (!this.buildMode) return; | |
| // Find empty adjacent position | |
| const directions = [ | |
| { dx: 0, dy: 1, dz: 0 }, | |
| { dx: 0, dy: -1, dz: 0 }, | |
| { dx: 1, dy: 0, dz: 0 }, | |
| { dx: -1, dy: 0, dz: 0 }, | |
| { dx: 0, dy: 0, dz: 1 }, | |
| { dx: 0, dy: 0, dz: -1 } | |
| ]; | |
| for (const dir of directions) { | |
| const newX = x + dir.dx; | |
| const newY = y + dir.dy; | |
| const newZ = z + dir.dz; | |
| const key = `${newX},${newY},${newZ}`; | |
| if (!this.blocks.has(key)) { | |
| this.createBlock(newX, newY, newZ, this.selectedBlock); | |
| break; | |
| } | |
| } | |
| } | |
| createParticles(x, y, z) { | |
| for (let i = 0; i < 10; i++) { | |
| const particle = document.createElement('div'); | |
| particle.className = 'particle'; | |
| particle.style.setProperty('--dx', `${(Math.random() - 0.5) * 100}px`); | |
| particle.style.setProperty('--dy', `${Math.random() * 100}px`); | |
| const worldRect = this.world.getBoundingClientRect(); | |
| particle.style.left = `${worldRect.left + (x * 32) + 16}px`; | |
| particle.style.top = `${worldRect.top + (-y * 32) + 16}px`; | |
| document.body.appendChild(particle); | |
| setTimeout(() => particle.remove(), 1000); | |
| } | |
| } | |
| setupEventListeners() { | |
| // Movement | |
| document.addEventListener('keydown', (e) => { | |
| const speed = 1; | |
| switch(e.key.toLowerCase()) { | |
| case 'w': | |
| this.playerPos.z -= speed; | |
| break; | |
| case 's': | |
| this.playerPos.z += speed; | |
| break; | |
| case 'a': | |
| this.playerPos.x -= speed; | |
| break; | |
| case 'd': | |
| this.playerPos.x += speed; | |
| break; | |
| case 'q': | |
| this.rotation.y -= 5; | |
| this.updateWorldRotation(); | |
| break; | |
| case 'e': | |
| this.rotation.y += 5; | |
| this.updateWorldRotation(); | |
| break; | |
| case 'g': | |
| this.generateTerrain(); | |
| break; | |
| case 'n': | |
| this.toggleDayNight(); | |
| break; | |
| } | |
| // Number keys for block selection | |
| if (e.key >= '1' && e.key <= '9') { | |
| const index = parseInt(e.key) - 1; | |
| const slots = document.querySelectorAll('.inventory-slot'); | |
| if (slots[index]) { | |
| this.selectBlock(slots[index]); | |
| } | |
| } | |
| this.updateStats(); | |
| }); | |
| // Inventory selection | |
| document.querySelectorAll('.inventory-slot').forEach(slot => { | |
| slot.addEventListener('click', () => this.selectBlock(slot)); | |
| }); | |
| // Build mode toggle | |
| document.getElementById('buildToggle').addEventListener('click', (e) => { | |
| this.buildMode = !this.buildMode; | |
| e.target.classList.toggle('active'); | |
| e.target.textContent = this.buildMode ? 'ON' : 'OFF'; | |
| }); | |
| } | |
| selectBlock(slot) { | |
| document.querySelectorAll('.inventory-slot').forEach(s => s.classList.remove('active')); | |
| slot.classList.add('active'); | |
| this.selectedBlock = slot.dataset.block; | |
| } | |
| updateWorldRotation() { | |
| this.world.style.transform = `rotateX(${this.rotation.x}deg) rotateY(${this.rotation.y}deg)`; | |
| } | |
| toggleDayNight() { | |
| this.isNight = !this.isNight; | |
| document.body.classList.toggle('night', this.isNight); | |
| document.getElementById('time').textContent = this.isNight ? 'Night' : 'Day'; | |
| } | |
| startDayNightCycle() { | |
| setInterval(() => { | |
| if (Math.random() < 0.1) { // 10% chance every 5 seconds | |
| this.toggleDayNight(); | |
| } | |
| }, 5000); | |
| } | |
| updateStats() { | |
| document.getElementById('position').textContent = | |
| `X:${this.playerPos.x} Y:${this.playerPos.y} Z:${this.playerPos.z}`; | |
| document.getElementById('blockCount').textContent = this.blockCount; | |
| } | |
| } | |
| // Initialize the game | |
| const game = new MinecraftGame(); | |
| </script> | |
| </body> | |
| </html> |