← back to Model Arena

data/artifacts/1d4944290382/gemma3-12b.html

139 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tiny Isometric City</title>
    <style>
        body { margin: 0; overflow: hidden; background-color: #eee; }
        #canvasContainer { width: 800px; height: 600px; margin: 50px auto; border: 1px solid black; position: relative;}
        #rotateButton { position: absolute; top: 10px; right: 10px; padding: 5px 10px; background-color: #333; color: white; cursor: pointer; }
        #counter { position: absolute; bottom: 10px; left: 10px; color: black; }

    </style>
</head>
<body>
    <div id="canvasContainer">
        <button id="rotateButton">Rotate View</button>
        <div id="counter"></div>
        <canvas id="cityCanvas" width="800" height="600"></canvas>
    </div>

    <script>
        const canvas = document.getElementById('cityCanvas');
        const ctx = canvas.getContext('2d');
        const rotateButton = document.getElementById('rotateButton');
        const counterDiv = document.getElementById('counter');

        let gridSize = 30;
        let data = [];
        let buildingTypes = ['house', 'tree', 'road', 'shop'];
        let currentBuildingTypeIndex = 0;
        let rotateAngle = 0;


        function init() {
            for (let x = 0; x < canvas.width / gridSize; x++) {
                data[x] = [];
                for (let y = 0; y < canvas.height / gridSize; y++) {
                    data[x][y] = null; // Initialize all tiles as empty
                }
            }

            updateCounter();
        }

        function drawIsometric(x, y, type) {
            const tileWidth = gridSize;
            const tileHeight = gridSize * 0.866;
            const zOffset = 5;  // Depth offset for isometric effect. Adjust as needed.

            let color;
            switch (type) {
                case 'house': color = '#a0785a'; break;
                case 'tree': color = '#228b22'; break;
                case 'road': color = '#8b4513'; break;
                case 'shop': color = '#d2691e'; break;
                default: color = '#777';
            }


            let isoX = (x - y) * tileWidth / 2;
            let isoY = (x + y) * tileHeight / 2;

            ctx.fillStyle = color;
            //Draw isometric rectangle
            if(type === 'house'){
                ctx.fillRect(isoX, isoY - tileHeight/3, tileWidth/1.5, tileHeight*0.7); // Draw the house shape
            } else if (type === 'tree'){
                ctx.fillRect(isoX, isoY - tileHeight / 2 , tileWidth * 0.8, tileHeight * 0.4 );
            } else if (type === 'road') {
                 ctx.fillRect(isoX, isoY - tileHeight/2, tileWidth*1.3, tileHeight * 0.2);

            }else if (type === 'shop'){
                ctx.fillRect(isoX, isoY - tileHeight /3 , tileWidth/1.5, tileHeight*0.7 ); // Draw the shop shape
            }


        }



        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            for (let x = 0; x < data.length; x++) {
                for (let y = 0; y < data[x].length; y++) {
                    if (data[x][y] !== null) {
                        drawIsometric(x, y, data[x][y]);
                    }
                }
            }
        }

       function updateCounter(){
           let houseCount = 0;
           let treeCount = 0;
           let roadCount = 0;
           let shopCount = 0;
           for (let x = 0; x < data.length; x++) {
               for (let y = 0; y < data[x].length; y++) {
                   if (data[x][y] === 'house') houseCount++;
                   if (data[x][y] === 'tree') treeCount++;
                   if (data[x][y] === 'road') roadCount++;
                   if (data[x][y] === 'shop') shopCount++;
               }
           }
           counterDiv.textContent = `House: ${houseCount}, Tree: ${treeCount}, Road: ${roadCount}, Shop: ${shopCount}`;
       }


        function handleClick(event) {
            const x = Math.floor(event.offsetX / gridSize);
            const y = Math.floor(event.offsetY / gridSize);

            if (x >= 0 && x < data.length && y >= 0 && y < data[x].length) {
                data[x][y] = buildingTypes[currentBuildingTypeIndex];
                draw();
                updateCounter();
            }
        }



        rotateButton.addEventListener('click', () => {
          rotateAngle += 45;
          if(rotateAngle > 360) rotateAngle -= 360;

           ctx.setTransform(Math.cos(rotateAngle * Math.PI / 180), Math.sin(rotateAngle * Math.PI / 180), -Math.sin(rotateAngle * Math.PI / 180), Math.cos(rotateAngle * Math.PI / 180), 0, 0);
        });



        canvas.addEventListener('click', handleClick);

        init();
        draw();
    </script>
</body>
</html>