Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>2D Minecraft | Physics Visualizer Pro</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| canvas { | |
| border: 1px solid #333; | |
| background-color: #87CEEB; | |
| display: block; | |
| margin: 0 auto; | |
| } | |
| #inventory { | |
| display: flex; | |
| justify-content: center; | |
| margin: 10px 0; | |
| } | |
| .block-item { | |
| border: 2px solid transparent; | |
| margin: 0 5px; | |
| cursor: pointer; | |
| } | |
| .block-item.selected { | |
| border-color: #4f46e5; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100"> | |
| <nav class="bg-indigo-600 text-white shadow-lg"> | |
| <div class="container mx-auto px-6 py-3"> | |
| <div class="flex justify-between items-center"> | |
| <div class="flex space-x-4"> | |
| <div> | |
| <a href="#" class="flex items-center py-2 px-2"> | |
| <i data-feather="atom" class="mr-2"></i> | |
| <span class="font-bold text-lg">Physics Visualizer Pro</span> | |
| </a> | |
| </div> | |
| </div> | |
| <div class="hidden md:flex items-center space-x-1"> | |
| <a href="index.html" class="py-2 px-3 hover:bg-indigo-700 rounded transition duration-300">Home</a> | |
| <a href="minecraft2d.html" class="py-2 px-3 bg-indigo-700 rounded hover:bg-indigo-800 transition duration-300">2D Minecraft</a> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <div class="container mx-auto px-4 py-8"> | |
| <h1 class="text-3xl font-bold text-center mb-6">2D Minecraft</h1> | |
| <div class="max-w-3xl mx-auto bg-white p-6 rounded-lg shadow-md"> | |
| <div id="inventory"> | |
| <div class="block-item selected" data-block="dirt"> | |
| <img src="https://static.photos/agriculture/64x64/1" alt="Dirt" width="64" height="64"> | |
| </div> | |
| <div class="block-item" data-block="stone"> | |
| <img src="https://static.photos/construction/64x64/2" alt="Stone" width="64" height="64"> | |
| </div> | |
| <div class="block-item" data-block="wood"> | |
| <img src="https://static.photos/agriculture/64x64/3" alt="Wood" width="64" height="64"> | |
| </div> | |
| <div class="block-item" data-block="leaf"> | |
| <img src="https://static.photos/nature/64x64/4" alt="Leaf" width="64" height="64"> | |
| </div> | |
| </div> | |
| <canvas id="gameCanvas" width="800" height="400"></canvas> | |
| <div class="mt-4 text-center"> | |
| <p class="text-gray-600 mb-2">Controls: Click to place blocks. Select block type from above.</p> | |
| <button id="clearBtn" class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600"> | |
| Clear World | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| const canvas = document.getElementById('gameCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| let selectedBlock = 'dirt'; | |
| // Block textures (using placeholder images) | |
| const blockTextures = { | |
| dirt: 'https://static.photos/agriculture/32x32/1', | |
| stone: 'https://static.photos/construction/32x32/2', | |
| wood: 'https://static.photos/agriculture/32x32/3', | |
| leaf: 'https://static.photos/nature/32x32/4' | |
| }; | |
| // Game grid | |
| const gridSize = 32; | |
| const gridWidth = canvas.width / gridSize; | |
| const gridHeight = canvas.height / gridSize; | |
| let world = Array(gridWidth).fill().map(() => Array(gridHeight).fill(null)); | |
| // Generate simple terrain | |
| function generateTerrain() { | |
| const groundLevel = Math.floor(gridHeight * 0.7); | |
| for (let x = 0; x < gridWidth; x++) { | |
| // Base ground layer | |
| for (let y = groundLevel; y < gridHeight; y++) { | |
| world[x][y] = 'dirt'; | |
| } | |
| // Stone layer below ground | |
| for (let y = groundLevel + 3; y < gridHeight; y++) { | |
| world[x][y] = 'stone'; | |
| } | |
| // Add some surface features | |
| if (x % 10 === 0 && x > 0 && x < gridWidth - 5) { | |
| // Tree | |
| const treeHeight = 5; | |
| for (let y = groundLevel - 1; y >= groundLevel - treeHeight; y--) { | |
| world[x][y] = 'wood'; | |
| } | |
| // Tree leaves | |
| for (let dx = -2; dx <= 2; dx++) { | |
| if (x + dx >= 0 && x + dx < gridWidth) { | |
| world[x + dx][groundLevel - treeHeight - 1] = 'leaf'; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Draw the world | |
| function drawWorld() { | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| // Sky | |
| ctx.fillStyle = '#87CEEB'; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| // Draw blocks | |
| for (let x = 0; x < gridWidth; x++) { | |
| for (let y = 0; y < gridHeight; y++) { | |
| if (world[x][y]) { | |
| const img = new Image(); | |
| img.src = blockTextures[world[x][y]]; | |
| ctx.drawImage(img, x * gridSize, y * gridSize, gridSize, gridSize); | |
| } | |
| } | |
| } | |
| } | |
| // Handle block selection | |
| document.querySelectorAll('.block-item').forEach(item => { | |
| item.addEventListener('click', () => { | |
| document.querySelectorAll('.block-item').forEach(i => i.classList.remove('selected')); | |
| item.classList.add('selected'); | |
| selectedBlock = item.dataset.block; | |
| }); | |
| }); | |
| // Handle canvas clicks | |
| canvas.addEventListener('click', (e) => { | |
| const rect = canvas.getBoundingClientRect(); | |
| const x = Math.floor((e.clientX - rect.left) / gridSize); | |
| const y = Math.floor((e.clientY - rect.top) / gridSize); | |
| if (x >= 0 && x < gridWidth && y >= 0 && y < gridHeight) { | |
| world[x][y] = selectedBlock; | |
| drawWorld(); | |
| } | |
| }); | |
| // Clear button | |
| document.getElementById('clearBtn').addEventListener('click', () => { | |
| world = Array(gridWidth).fill().map(() => Array(gridHeight).fill(null)); | |
| generateTerrain(); | |
| drawWorld(); | |
| }); | |
| // Initialize game | |
| generateTerrain(); | |
| drawWorld(); | |
| </script> | |
| </body> | |
| </html> |