DEV Community

Zako Mako
Zako Mako

Posted on

New game!

My new game is awesome! you get to make a civilization in space! here is the code:

<!DOCTYPE html>
<html>
<head>
    <title>Space Boy - Build a Space Civilization</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #0f0f1f;
            color: #fff;
            font-family: 'Courier New', monospace;
            overflow: hidden;
            touch-action: none;
        }

        #gameContainer {
            position: relative;
            width: 800px;
            height: 600px;
            margin: 20px auto;
            border: 4px solid #4466ff;
            box-shadow: 0 0 20px #4466ff;
            image-rendering: pixelated;
        }

        #gameCanvas {
            background-color: #000022;
        }

        #uiPanel {
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 120px;
            background-color: rgba(0, 0, 40, 0.8);
            border-top: 2px solid #4466ff;
            display: flex;
            flex-direction: column;
            padding: 10px;
            box-sizing: border-box;
        }

        #resources {
            display: flex;
            justify-content: space-around;
            margin-bottom: 10px;
        }

        .resource {
            display: flex;
            align-items: center;
        }

        .resource-icon {
            width: 16px;
            height: 16px;
            margin-right: 5px;
        }

        #buildMenu {
            display: flex;
            justify-content: space-around;
        }

        .buildButton {
            width: 64px;
            height: 64px;
            background-color: #112244;
            border: 2px solid #4466ff;
            color: white;
            cursor: pointer;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            font-size: 10px;
            image-rendering: pixelated;
        }

        .buildButton:hover {
            background-color: #224466;
        }

        #titleScreen {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 40, 0.9);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 100;
        }

        #title {
            font-size: 48px;
            color: #4466ff;
            margin-bottom: 30px;
            text-shadow: 0 0 10px #4466ff;
        }

        #startButton {
            padding: 10px 30px;
            background-color: #112244;
            border: 2px solid #4466ff;
            color: white;
            font-size: 20px;
            cursor: pointer;
        }

        #startButton:hover {
            background-color: #224466;
        }

        #message {
            position: absolute;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 40, 0.8);
            border: 2px solid #4466ff;
            padding: 10px;
            display: none;
            z-index: 50;
        }
    </style>
</head>
<body>
    <div id="gameContainer">
        <canvas id="gameCanvas" width="800" height="600"></canvas>

        <div id="uiPanel">
            <div id="resources">
                <div class="resource">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" class="resource-icon">
                    <span id="metalCount">100</span>
                </div>
                <div class="resource">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAdklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQANVYYw4QhXAAAAABJRU5ErkJggg==" class="resource-icon">
                    <span id="energyCount">50</span>
                </div>
                <div class="resource">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" class="resource-icon">
                    <span id="foodCount">30</span>
                </div>
                <div class="resource">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" class="resource-icon">
                    <span id="populationCount">5</span>
                </div>
            </div>

            <div id="buildMenu">
                <div class="buildButton" data-building="habitat">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" width="32" height="32">
                    Habitat
                </div>
                <div class="buildButton" data-building="solar">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" width="32" height="32">
                    Solar Panel
                </div>
                <div class="buildButton" data-building="mine">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" width="32" height="32">
                    Mine
                </div>
                <div class="buildButton" data-building="farm">
                    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhklEQVQ4y2NgGAXDFmzatMmKAQ38v3//PgMqRgWoYqgYFQwqC1A9gOoRRjQxRrQwYEQTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTY0QTYwQAjXQYw4QhXAAAAABJRU5ErkJggg==" width="32" height="32">
                    Farm
                </div>
            </div>
        </div>

        <div id="titleScreen">
            <h1 id="title">SPACE BOY</h1>
            <button id="startButton">START GAME</button>
        </div>

        <div id="message"></div>
    </div>

    <script>
        // Game state
        const gameState = {
            resources: {
                metal: 100,
                energy: 50,
                food: 30,
                population: 5,
                maxPopulation: 10
            },
            buildings: [],
            selectedBuilding: null,
            gameStarted: false
        };

        // Building definitions
        const buildingTypes = {
            habitat: {
                name: "Habitat",
                cost: { metal: 50, energy: 20 },
                production: { population: 2 },
                color: "#4466ff",
                width: 40,
                height: 40
            },
            solar: {
                name: "Solar Panel",
                cost: { metal: 30 },
                production: { energy: 5 },
                color: "#ffff00",
                width: 30,
                height: 30
            },
            mine: {
                name: "Mine",
                cost: { energy: 10 },
                production: { metal: 3 },
                color: "#aaaaaa",
                width: 35,
                height: 35
            },
            farm: {
                name: "Farm",
                cost: { metal: 20, energy: 5 },
                production: { food: 4 },
                color: "#44ff44",
                width: 40,
                height: 30
            }
        };

        // DOM elements
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const titleScreen = document.getElementById('titleScreen');
        const startButton = document.getElementById('startButton');
        const messageDiv = document.getElementById('message');
        const buildButtons = document.querySelectorAll('.buildButton');
        const resourceCounts = {
            metal: document.getElementById('metalCount'),
            energy: document.getElementById('energyCount'),
            food: document.getElementById('foodCount'),
            population: document.getElementById('populationCount')
        };

        // Event listeners
        startButton.addEventListener('click', startGame);
        canvas.addEventListener('click', handleCanvasClick);
        buildButtons.forEach(button => {
            button.addEventListener('click', () => {
                const buildingType = button.getAttribute('data-building');
                selectBuilding(buildingType);
            });
        });

        // Game functions
        function startGame() {
            titleScreen.style.display = 'none';
            gameState.gameStarted = true;
            updateResourceDisplay();

            // Start game loop
            setInterval(gameLoop, 1000);
            requestAnimationFrame(render);
        }

        function gameLoop() {
            // Update resources from buildings
            gameState.buildings.forEach(building => {
                const type = buildingTypes[building.type];
                Object.keys(type.production).forEach(resource => {
                    gameState.resources[resource] += type.production[resource];

                    // Handle population cap
                    if (resource === 'population') {
                        gameState.resources.population = Math.min(
                            gameState.resources.population,
                            gameState.resources.maxPopulation
                        );
                    }
                });
            });

            updateResourceDisplay();
        }

        function updateResourceDisplay() {
            Object.keys(resourceCounts).forEach(resource => {
                resourceCounts[resource].textContent = gameState.resources[resource];
            });
        }

        function selectBuilding(buildingType) {
            gameState.selectedBuilding = buildingType;
            showMessage(`Selected: ${buildingTypes[buildingType].name}`);
        }

        function handleCanvasClick(e) {
            if (!gameState.gameStarted || !gameState.selectedBuilding) return;

            const rect = canvas.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;

            // Check if we can afford the building
            const buildingType = buildingTypes[gameState.selectedBuilding];
            let canAfford = true;

            Object.keys(buildingType.cost).forEach(resource => {
                if (gameState.resources[resource] < buildingType.cost[resource]) {
                    canAfford = false;
                }
            });

            if (!canAfford) {
                showMessage("Not enough resources!");
                return;
            }

            // Pay for the building
            Object.keys(buildingType.cost).forEach(resource => {
                gameState.resources[resource] -= buildingType.cost[resource];
            });

            // Add the building
            gameState.buildings.push({
                type: gameState.selectedBuilding,
                x: x - buildingType.width/2,
                y: y - buildingType.height/2
            });

            updateResourceDisplay();
            showMessage(`${buildingType.name} built!`);
        }

        function showMessage(text) {
            messageDiv.textContent = text;
            messageDiv.style.display = 'block';
            setTimeout(() => {
                messageDiv.style.display = 'none';
            }, 2000);
        }

        function render() {
            // Clear canvas
            ctx.fillStyle = '#000022';
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // Draw stars
            for (let i = 0; i < 100; i++) {
                ctx.fillStyle = '#ffffff';
                ctx.fillRect(
                    Math.random() * canvas.width,
                    Math.random() * canvas.height,
                    1, 1
                );
            }

            // Draw buildings
            gameState.buildings.forEach(building => {
                const type = buildingTypes[building.type];
                ctx.fillStyle = type.color;
                ctx.fillRect(building.x, building.y, type.width, type.height);

                // Draw building details
                ctx.fillStyle = '#000000';
                ctx.fillRect(building.x + 5, building.y + 5, type.width - 10, 3);
                ctx.fillRect(building.x + 5, building.y + 10, type.width - 10, 3);
            });

            // Draw selected building preview
            if (gameState.selectedBuilding) {
                const type = buildingTypes[gameState.selectedBuilding];
                ctx.strokeStyle = '#ffffff';
                ctx.setLineDash([5, 5]);
                ctx.strokeRect(
                    gameState.mouseX - type.width/2,
                    gameState.mouseY - type.height/2,
                    type.width,
                    type.height
                );
                ctx.setLineDash([]);
            }

            requestAnimationFrame(render);
        }

        // Track mouse position for building preview
        canvas.addEventListener('mousemove', (e) => {
            const rect = canvas.getBoundingClientRect();
            gameState.mouseX = e.clientX - rect.left;
            gameState.mouseY = e.clientY - rect.top;
        });

        // Initialize
        updateResourceDisplay();
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

here is the link:

thank you!

Top comments (0)