<!DOCTYPE html>
<html>
<head>
    <title>2D Top-Down Game with Army and Death Effects</title>
    <style>
        body { margin: 0; overflow: hidden; }
        canvas { display: block; background: #000; cursor: grab; }
        #instructions {
            position: absolute;
            top: 10px;
            left: 10px;
            color: white;
            font-family: Arial, sans-serif;
            background-color: rgba(0,0,0,0.5);
            padding: 10px;
            border-radius: 5px;
            z-index: 1;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas"></canvas>
    <div id="instructions">
        <h2>2D Top-Down Game with Army and Death Effects</h2>
        <p>Click on the landscape to spawn 8-bit characters.</p>
        <p>Characters form countries, collect resources, and form armies.</p>
        <p>Characters need food to survive; countries collect food from within their borders.</p>
        <p>Drag with the mouse to explore the larger world.</p>
    </div>
    <script>
        // Setup canvas
        const canvas = document.getElementById("gameCanvas");
        const ctx = canvas.getContext("2d");
        let canvasWidth = window.innerWidth;
        let canvasHeight = window.innerHeight;
        canvas.width = canvasWidth;
        canvas.height = canvasHeight;

        // Tile and world dimensions
        const tileSize = 16; // Adjusted tile size
        const worldWidth = 200; // Increased world size
        const worldHeight = 200;

        // Camera (viewport) position
        let cameraX = 0;
        let cameraY = 0;

        // Variables for panning the camera
        let isPanning = false;
        let startMouseX, startMouseY;
        let startCameraX, startCameraY;

        // World array
        const world = [];
        for(let y = 0; y < worldHeight; y++) {
            world[y] = [];
            for(let x = 0; x < worldWidth; x++) {
                world[y][x] = {};
            }
        }

        // Generate terrain resembling Earth's landscape
        const centerX = worldWidth / 2;
        const centerY = worldHeight / 2;
        const maxDistance = Math.sqrt(centerX * centerX + centerY * centerY);

        for(let y = 0; y < worldHeight; y++) {
            for(let x = 0; x < worldWidth; x++) {
                const dx = x - centerX;
                const dy = y - centerY;
                const distance = Math.sqrt(dx * dx + dy * dy);
                let height = 1 - (distance / maxDistance); // Height decreases from center
                height += (Math.random() - 0.5) * 0.5; // Add noise
                world[y][x].height = height;
                world[y][x].type = 'water'; // Initialize as water
                world[y][x].country = null; // Track ownership for borders
            }
        }

        // Assign land tiles based on height
        for(let y = 0; y < worldHeight; y++) {
            for(let x = 0; x < worldWidth; x++) {
                const tile = world[y][x];
                if(tile.height > 0.3) {
                    tile.type = 'land';
                }
            }
        }

        // Generate woods, food, and iron on land tiles
        for(let y = 0; y < worldHeight; y++) {
            for(let x = 0; x < worldWidth; x++) {
                const tile = world[y][x];
                if(tile.type === 'land') {
                    const rnd = Math.random();
                    if(rnd < 0.15) { // 15% chance to be woods
                        tile.type = 'woods';
                    } else if(rnd < 0.25) { // 10% chance to be food
                        tile.type = 'food';
                    } else if(rnd < 0.28) { // Additional 3% chance to be iron
                        tile.type = 'iron';
                    }
                }
            }
        }

        // Generate rivers
        function generateRivers(numRivers) {
            for(let i = 0; i < numRivers; i++) {
                // Start river at random x position at the top
                let x = Math.floor(Math.random() * worldWidth);
                let y = 0;
                while(y < worldHeight && x >= 0 && x < worldWidth) {
                    world[y][x].type = 'river';
                    // Randomly move left, right, or straight down
                    const direction = Math.floor(Math.random() * 3) - 1; // -1, 0, or 1
                    x += direction;
                    y += 1;
                }
            }
        }

        generateRivers(5); // Generate 5 rivers

        // Function to draw the world
        function drawWorld() {
            const startX = Math.floor(cameraX / tileSize);
            const startY = Math.floor(cameraY / tileSize);
            const endX = startX + Math.ceil(canvasWidth / tileSize) + 1;
            const endY = startY + Math.ceil(canvasHeight / tileSize) + 1;

            for(let y = startY; y < endY; y++) {
                for(let x = startX; x < endX; x++) {
                    if(x >= 0 && x < worldWidth && y >= 0 && y < worldHeight) {
                        const tile = world[y][x];
                        switch(tile.type) {
                            case 'land':
                                ctx.fillStyle = '#228B22'; // Forest green
                                break;
                            case 'woods':
                                ctx.fillStyle = '#006400'; // Dark green for woods
                                break;
                            case 'food':
                                ctx.fillStyle = '#FFD700'; // Gold for food sources
                                break;
                            case 'iron':
                                ctx.fillStyle = '#A9A9A9'; // Dark gray for iron
                                break;
                            case 'river':
                                ctx.fillStyle = '#1E90FF'; // Blue for rivers
                                break;
                            case 'water':
                                ctx.fillStyle = '#87CEEB'; // Light blue for water
                                break;
                            case 'house':
                                ctx.fillStyle = '#8B4513'; // Brown for houses
                                break;
                            default:
                                ctx.fillStyle = '#000';
                                break;
                        }
                        ctx.fillRect((x * tileSize) - cameraX, (y * tileSize) - cameraY, tileSize, tileSize);

                        // Optionally, draw tiles claimed by a country in lighter shade
                        if(tile.country && tile.type !== 'water' && tile.type !== 'river') {
                            ctx.fillStyle = tile.country.color + '55'; // Semi-transparent
                            ctx.fillRect((x * tileSize) - cameraX, (y * tileSize) - cameraY, tileSize, tileSize);
                        }
                    }
                }
            }

            // Draw country borders
            countries.forEach(country => {
                ctx.strokeStyle = country.borderColor;
                country.borders.forEach(tile => {
                    ctx.strokeRect((tile.x * tileSize) - cameraX, (tile.y * tileSize) - cameraY, tileSize, tileSize);
                });
            });
        }

        // Character array
        const characters = [];
        // Army units array
        const armies = [];
        // Death effects array
        const deathEffects = [];

        // Country array
        const countries = [];

        // Names for countries and kings
        const countryNames = ["Avalon", "Eldoria", "Valoria", "Draconia", "Zephyria", "Arcadia", "Elysium", "Calradia", "Mythland", "Serentia"];
        let usedCountryNames = [];

        const kingNames = ["Arthur", "Leon", "Maximilian", "Victor", "Robert", "Richard", "William", "Henry", "Edward", "Alexander"];

        // Character class
        class Character {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                this.woodCollected = 0;
                this.ironCollected = 0;
                this.moveDelay = Math.floor(Math.random() * 10) + 5; // Random delay between moves
                this.moveCounter = 0;
                this.country = null; // Reference to the country they belong to
                this.hungerCounter = Math.floor(Math.random() * 200) + 100; // Time until next meal
            }
            move() {
                this.moveCounter++;
                if(this.moveCounter >= this.moveDelay) {
                    this.moveCounter = 0;

                    // Check hunger
                    this.hungerCounter--;
                    if(this.hungerCounter <= 0) {
                        this.eat();
                        this.hungerCounter = Math.floor(Math.random() * 200) + 100; // Reset hunger counter
                    }

                    // Build house if enough wood collected
                    if(this.woodCollected >= 5) {
                        this.buildHouse();
                        this.woodCollected = 0;
                    }

                    // Random direction: up, down, left, right
                    const directions = [
                        {dx: -1, dy: 0}, // left
                        {dx: 1, dy: 0},  // right
                        {dx: 0, dy: -1}, // up
                        {dx: 0, dy: 1},  // down
                    ];
                    const dir = directions[Math.floor(Math.random() * directions.length)];
                    const newX = this.x + dir.dx;
                    const newY = this.y + dir.dy;
                    // Check bounds
                    if(newX >= 0 && newX < worldWidth && newY >= 0 && newY < worldHeight) {
                        const tile = world[newY][newX];

                        // Check if tile is passable (not water or river)
                        if(tile.type === 'land' || tile.type === 'woods' || tile.type === 'food' || tile.type === 'iron' || tile.type === 'house') {
                            // Check for country borders
                            if(this.canEnterTile(tile)) {
                                this.x = newX;
                                this.y = newY;

                                // Collect wood if on woods tile
                                if(tile.type === 'woods') {
                                    this.woodCollected++;
                                    tile.type = 'land'; // Remove woods after chopping
                                    // If part of a country, add wood to country's resources
                                    if(this.country) {
                                        this.country.wood++;
                                    }
                                }

                                // Collect iron if on iron tile
                                if(tile.type === 'iron') {
                                    this.ironCollected++;
                                    tile.type = 'land'; // Remove iron after mining
                                    // If part of a country, add iron to country's resources
                                    if(this.country) {
                                        this.country.iron++;
                                    }
                                }

                                // If part of a country, claim tile
                                if(this.country) {
                                    tile.country = this.country;
                                    this.country.updateBorders();
                                }
                            }
                        }
                    }

                    // Check for proximity to form a country
                    if(!this.country) {
                        checkForCountryFormation(this);
                    }
                }
            }
            eat() {
                if(this.country) {
                    if(this.country.food > 0) {
                        this.country.food--;
                    } else {
                        // No food available, character dies
                        this.die();
                    }
                } else {
                    // Character without country dies of starvation
                    this.die();
                }
            }
            die() {
                // Add death effect
                deathEffects.push(new DeathEffect(this.x, this.y));

                // Remove character from the game
                const index = characters.indexOf(this);
                if(index !== -1) {
                    characters.splice(index, 1);
                }
                // Remove from country members if applicable
                if(this.country) {
                    const idx = this.country.members.indexOf(this);
                    if(idx !== -1) {
                        this.country.members.splice(idx, 1);
                    }
                    // Check if country has no members left
                    if(this.country.members.length === 0) {
                        // Remove country from the game
                        const cIndex = countries.indexOf(this.country);
                        if(cIndex !== -1) {
                            countries.splice(cIndex, 1);
                        }
                        // Remove country ownership from tiles
                        for(let y = 0; y < worldHeight; y++) {
                            for(let x = 0; x < worldWidth; x++) {
                                const tile = world[y][x];
                                if(tile.country === this.country) {
                                    tile.country = null;
                                }
                            }
                        }
                    }
                }
            }
            buildHouse() {
                const tile = world[this.y][this.x];
                // Can only build on land or woods within own country or unclaimed territory
                if((tile.type === 'land' || tile.type === 'woods') && this.canEnterTile(tile)) {
                    tile.type = 'house';
                    // If part of a country, claim the tile
                    if(this.country) {
                        tile.country = this.country;
                        this.country.updateBorders();
                    }
                }
            }
            canEnterTile(tile) {
                // If the tile is not claimed by any country, it's free to enter
                if(!tile.country) return true;
                // If the tile belongs to the character's own country, they can enter
                if(tile.country === this.country) return true;
                // Otherwise, they cannot enter
                return false;
            }
            draw() {
                // Calculate position on canvas
                const drawX = (this.x * tileSize) - cameraX;
                const drawY = (this.y * tileSize) - cameraY;

                // Only draw if within the visible area
                if(drawX >= -tileSize && drawX <= canvasWidth && drawY >= -tileSize && drawY <= canvasHeight) {
                    // Draw character sprite
                    ctx.fillStyle = this.country ? this.country.color : '#FFD700'; // Color based on country
                    ctx.fillRect(drawX + 4, drawY + 2, 8, 12); // Body
                    ctx.fillStyle = '#FFFFFF'; // White for face
                    ctx.fillRect(drawX + 5, drawY + 4, 6, 6); // Face
                    ctx.fillStyle = '#000000'; // Black for eyes
                    ctx.fillRect(drawX + 6, drawY + 5, 1, 1); // Left eye
                    ctx.fillRect(drawX + 9, drawY + 5, 1, 1); // Right eye
                    ctx.fillRect(drawX + 7, drawY + 7, 2, 1); // Mouth
                }
            }
        }

        // Army class
        class Army {
            constructor(x, y, country) {
                this.x = x;
                this.y = y;
                this.country = country;
            }
            draw() {
                // Calculate position on canvas
                const drawX = (this.x * tileSize) - cameraX;
                const drawY = (this.y * tileSize) - cameraY;

                // Only draw if within the visible area
                if(drawX >= -tileSize && drawX <= canvasWidth && drawY >= -tileSize && drawY <= canvasHeight) {
                    // Draw army sprite (simple flag icon)
                    ctx.fillStyle = this.country.color;
                    ctx.fillRect(drawX + 4, drawY + 2, 8, 12); // Pole
                    ctx.fillStyle = '#000000'; // Black flag
                    ctx.fillRect(drawX + 8, drawY + 2, 6, 6); // Flag
                }
            }
        }

        // Death effect class
        class DeathEffect {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                this.duration = 50; // Duration of the effect
            }
            update() {
                this.duration--;
            }
            draw() {
                // Calculate position on canvas
                const drawX = (this.x * tileSize) - cameraX;
                const drawY = (this.y * tileSize) - cameraY;

                // Only draw if within the visible area
                if(drawX >= -tileSize && drawX <= canvasWidth && drawY >= -tileSize && drawY <= canvasHeight) {
                    // Draw skull icon
                    ctx.fillStyle = 'rgba(255, 255, 255, ${this.duration / 50});' // Fade out effect
                    ctx.font = '14px Arial';
                    ctx.fillText('💀', drawX + 2, drawY + 14);
                }
            }
        }

        // Country class
        class Country {
            constructor(name, king, members) {
                this.name = name;
                this.king = king;
                this.members = members; // Array of characters in the country
                this.wood = 0; // Wood resources
                this.food = 0; // Food resources
                this.iron = 0; // Iron resources

                // Assign a color to the country for visualization
                this.color = getRandomColor();

                // Assign a border color for visualization
                this.borderColor = getRandomBorderColor();

                // Borders are tiles claimed by the country
                this.borders = []; // Array of tiles that form the country's territory
                this.updateBorders();

                this.army = []; // Army units
                this.updateArmy();
            }
            updateBorders() {
                // Clear previous borders
                this.borders = [];
                // Reset food resources
                this.food = 0;
                // Iterate over the world tiles to find those claimed by this country
                for(let y = 0; y < worldHeight; y++) {
                    for(let x = 0; x < worldWidth; x++) {
                        const tile = world[y][x];
                        if(tile.country === this) {
                            this.borders.push({x, y});
                            // Collect food if tile has food
                            if(tile.type === 'food') {
                                this.food++; // Each food tile counts as one food unit
                            }
                        }
                    }
                }
            }
            updateArmy() {
                // Calculate desired army size (2% of population)
                const desiredArmySize = Math.max(1, Math.floor(this.members.length * 0.02));
                // Create or disband army units to match desired size
                while(this.army.length < desiredArmySize && this.iron >= 10) { // Assume each army unit costs 10 iron
                    // Create new army unit at random member's location
                    const member = this.members[Math.floor(Math.random() * this.members.length)];
                    const newArmy = new Army(member.x, member.y, this);
                    this.army.push(newArmy);
                    this.iron -= 10; // Consume iron to create army unit
                }
                while(this.army.length > desiredArmySize) {
                    // Disband army unit
                    this.army.pop();
                }
            }
            drawArmy() {
                this.army.forEach(armyUnit => armyUnit.draw());
            }
        }

        // Helper function to generate a random color
        function getRandomColor() {
            const letters = '0123456789ABCDEF';
            let color = '#';
            for(let i = 0; i < 6; i++) {
                color += letters[Math.floor(Math.random() * 16)];
            }
            return color;
        }

        // Helper function to generate a random border color
        function getRandomBorderColor() {
            const colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF', '#FFFFFF'];
            return colors[Math.floor(Math.random() * colors.length)];
        }

        // Function to check for country formation
        function checkForCountryFormation(character) {
            // Find nearby characters within a certain radius
            const radius = 3;
            const nearbyCharacters = characters.filter(other => {
                if(other !== character && !other.country) {
                    const dx = other.x - character.x;
                    const dy = other.y - character.y;
                    const distance = Math.sqrt(dx * dx + dy * dy);
                    return distance <= radius;
                }
                return false;
            });

            // Include the character themselves
            nearbyCharacters.push(character);

            // If 5 or more characters are nearby, form a country
            if(nearbyCharacters.length >= 5) {
                // Create a new country
                const countryName = getUniqueCountryName();
                const king = nearbyCharacters[Math.floor(Math.random() * nearbyCharacters.length)];
                const newCountry = new Country(countryName, king, nearbyCharacters);

                // Assign country to members and claim their current tiles
                nearbyCharacters.forEach(member => {
                    member.country = newCountry;
                    const tile = world[member.y][member.x];
                    tile.country = newCountry;
                });

                // Add country to the list
                countries.push(newCountry);
            }
        }

        // Helper function to get a unique country name
        function getUniqueCountryName() {
            let name = countryNames[Math.floor(Math.random() * countryNames.length)];
            while(usedCountryNames.includes(name) && usedCountryNames.length < countryNames.length) {
                name = countryNames[Math.floor(Math.random() * countryNames.length)];
            }
            usedCountryNames.push(name);
            return name;
        }

        // Handle mouse clicks to spawn characters
        canvas.addEventListener('click', function(e) {
            const rect = canvas.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;
            const x = Math.floor((mouseX + cameraX) / tileSize);
            const y = Math.floor((mouseY + cameraY) / tileSize);

            // Spawn character if tile is land or woods and not within another country's borders
            if(x >= 0 && x < worldWidth && y >= 0 && y < worldHeight) {
                const tile = world[y][x];
                const tileType = tile.type;
                if((tileType === 'land' || tileType === 'woods' || tileType === 'food' || tileType === 'iron') && !tile.country) {
                    const character = new Character(x, y);
                    characters.push(character);
                }
            }
        });

        // Handle mouse down for panning
        canvas.addEventListener('mousedown', function(e) {
            isPanning = true;
            canvas.style.cursor = 'grabbing';
            startMouseX = e.clientX;
            startMouseY = e.clientY;
            startCameraX = cameraX;
            startCameraY = cameraY;
        });

        // Handle mouse move for panning
        canvas.addEventListener('mousemove', function(e) {
            if(isPanning) {
                const dx = e.clientX - startMouseX;
                const dy = e.clientY - startMouseY;
                cameraX = startCameraX - dx;
                cameraY = startCameraY - dy;

                // Clamp camera within world bounds
                cameraX = Math.max(0, Math.min(cameraX, worldWidth * tileSize - canvasWidth));
                cameraY = Math.max(0, Math.min(cameraY, worldHeight * tileSize - canvasHeight));
            }
        });

        // Handle mouse up for panning
        canvas.addEventListener('mouseup', function(e) {
            isPanning = false;
            canvas.style.cursor = 'grab';
        });

        // Handle mouse out
        canvas.addEventListener('mouseleave', function(e) {
            isPanning = false;
            canvas.style.cursor = 'grab';
        });

        // Function to draw everything
        function draw() {
            ctx.clearRect(0, 0, canvasWidth, canvasHeight);
            drawWorld();
            characters.forEach(character => character.draw());
            countries.forEach(country => country.drawArmy());
            deathEffects.forEach(effect => effect.draw());
        }

        // Game loop
        function gameLoop() {
            // Update characters
            characters.forEach(character => character.move());
            // Update countries
            countries.forEach(country => {
                country.updateBorders();
                country.updateArmy();
            });
            // Update death effects
            for(let i = deathEffects.length -1; i >= 0; i--) {
                const effect = deathEffects[i];
                effect.update();
                if(effect.duration <= 0) {
                    deathEffects.splice(i,1); // Remove expired effects
                }
            }
            // Redraw everything
            draw();
            requestAnimationFrame(gameLoop);
        }

        // Initial draw and start game loop
        draw();
        requestAnimationFrame(gameLoop);

        // Adjust canvas size on window resize
        window.addEventListener('resize', function() {
            canvasWidth = window.innerWidth;
            canvasHeight = window.innerHeight;
            canvas.width = canvasWidth;
            canvas.height = canvasHeight;
        });

    </script>
</body>
</html>

Now country can declare war to another country if they have enough army and have reason to start the war (For example, conqurier more lands), army of another country can defend their borders