<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Florr.io 离线版 (精准还原核心)</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', sans-serif;
        }
        
        body {
            background: #1a1a1a;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
            padding: 20px;
            color: #fff;
            overflow: hidden;
        }
        
        #game-container {
            position: relative;
            border: 2px solid #3498db;
            border-radius: 4px;
            background: #111;
            overflow: hidden;
        }
        
        #game-canvas {
            display: block;
            background: #0f0f0f;
            image-rendering: pixelated;
        }
        
        #game-hud {
            display: flex;
            justify-content: space-between;
            width: 1000px;
            margin-top: 15px;
            background: #222;
            padding: 10px;
            border-radius: 6px;
        }
        
        #stats-panel {
            display: flex;
            gap: 15px;
            font-size: 14px;
        }
        
        .level { color: #f1c40f; }
        .hp { color: #e74c3c; }
        .petals { color: #2ecc71; }
        
        #controls-panel {
            font-size: 13px;
            color: #aaa;
        }
        
        #petal-slots {
            width: 1000px;
            margin-top: 10px;
            background: #222;
            padding: 10px;
            border-radius: 6px;
            display: flex;
            gap: 8px;
        }
        
        .petal-slot {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background: #333;
            border: 2px solid #444;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
        }
        
        .petal-slot.active {
            border-color: #3498db;
        }
        
        .petal-slot .petal {
            width: 30px;
            height: 30px;
            border-radius: 50%;
        }
        
        .petal-slot .count {
            position: absolute;
            bottom: -5px;
            right: -5px;
            background: #000;
            color: #fff;
            font-size: 10px;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    </style>
</head>
<body>
    <div id="game-container">
        <canvas id="game-canvas" width="1000" height="700"></canvas>
    </div>
    
    <div id="game-hud">
        <div id="stats-panel">
            <div><span class="level">等级: 1</span></div>
            <div><span class="hp">生命值: 100/100</span></div>
            <div><span class="petals">花瓣数: 15</span></div>
            <div><span class="xp">经验: 0/100</span></div>
        </div>
        <div id="controls-panel">
            🖱️ 鼠标控制移动方向 | 🌸 花瓣直接碰撞攻击 | 🎒 数字键切换花瓣类型
        </div>
    </div>
    
    <div id="petal-slots">
        <div class="petal-slot active" data-slot="1">
            <div class="petal" style="background: #ffd700;"></div>
            <div class="count">15</div>
        </div>
        <div class="petal-slot" data-slot="2">
            <div class="petal" style="background: #1e90ff;"></div>
            <div class="count">8</div>
        </div>
        <div class="petal-slot" data-slot="3">
            <div class="petal" style="background: #ff6347;"></div>
            <div class="count">5</div>
        </div>
    </div>

    <script>
        // 游戏核心配置 (完全匹配florr.io)
        const canvas = document.getElementById('game-canvas');
        const ctx = canvas.getContext('2d');
        const statsPanel = document.getElementById('stats-panel');
        
        // 游戏世界(玩家始终在视觉中心,移动的是世界而非玩家)
        const world = {
            offsetX: 0,
            offsetY: 0,
            scale: 1
        };
        
        // 玩家对象 (florr.io核心属性)
        const player = {
            // 玩家始终在画布中心(视觉上)
            visualX: canvas.width / 2,
            visualY: canvas.height / 2,
            // 实际世界坐标
            worldX: 0,
            worldY: 0,
            coreSize: 20,    // 核心大小
            speed: 4,        // 移动速度
            level: 1,
            hp: 100,
            maxHp: 100,
            xp: 0,
            xpToNextLevel: 100,
            // 花瓣系统 (核心战斗机制)
            activePetalType: 1,
            petals: {
                1: { type: 'normal', count: 15, damage: 2, size: 12, color: '#ffd700', speed: 0.03 },
                2: { type: 'fast', count: 8, damage: 1, size: 8, color: '#1e90ff', speed: 0.05 },
                3: { type: 'strong', count: 5, damage: 5, size: 16, color: '#ff6347', speed: 0.02 }
            },
            // 花瓣实体(围绕核心旋转的战斗单元)
            petalEntities: [],
            // 鼠标相对位置(控制移动)
            mouseRelativeX: 0,
            mouseRelativeY: 0
        };
        
        // 游戏实体
        const entities = {
            enemies: [],      // 敌人 (bug/larva/flower)
            resources: [],    // 可收集资源 (花瓣/经验球)
            particles: []     // 特效粒子
        };
        
        // 游戏状态
        let mouseX = 0;
        let mouseY = 0;
        let frameCount = 0;
        
        // ======================
        // 初始化花瓣实体 (核心战斗单元)
        // ======================
        function initPetals() {
            player.petalEntities = [];
            const petalType = player.petals[player.activePetalType];
            const petalCount = petalType.count;
            
            // 创建围绕玩家核心旋转的花瓣
            for (let i = 0; i < petalCount; i++) {
                const angle = (i / petalCount) * Math.PI * 2;
                const distance = player.coreSize + 10 + (i % 3) * 8; // 分层排列
                
                player.petalEntities.push({
                    angle: angle,
                    distance: distance,
                    size: petalType.size,
                    color: petalType.color,
                    damage: petalType.damage,
                    rotateSpeed: petalType.speed,
                    // 碰撞盒
                    worldX: player.worldX + Math.cos(angle) * distance,
                    worldY: player.worldY + Math.sin(angle) * distance
                });
            }
        }
        
        // ======================
        // 事件监听 (florr.io原版操作)
        // ======================
        // 鼠标位置跟踪(核心移动控制)
        canvas.addEventListener('mousemove', (e) => {
            const rect = canvas.getBoundingClientRect();
            mouseX = e.clientX - rect.left;
            mouseY = e.clientY - rect.top;
            
            // 计算鼠标相对于玩家视觉中心的偏移
            player.mouseRelativeX = mouseX - player.visualX;
            player.mouseRelativeY = mouseY - player.visualY;
        });
        
        // 键盘切换花瓣类型
        document.addEventListener('keydown', (e) => {
            const slotNum = parseInt(e.key);
            if (slotNum >= 1 && slotNum <= 3) {
                player.activePetalType = slotNum;
                initPetals(); // 切换花瓣类型
                
                // 更新UI
                document.querySelectorAll('.petal-slot').forEach(slot => {
                    slot.classList.remove('active');
                    if (parseInt(slot.dataset.slot) === slotNum) {
                        slot.classList.add('active');
                    }
                });
            }
        });
        
        // ======================
        // 核心游戏逻辑
        // ======================
        // 玩家移动 (florr.io核心机制:按鼠标相对方向移动)
        function updatePlayerMovement() {
            // 计算移动方向(基于鼠标相对位置)
            const moveAngle = Math.atan2(player.mouseRelativeY, player.mouseRelativeX);
            const moveDistance = Math.hypot(player.mouseRelativeX, player.mouseRelativeY);
            
            // 只有鼠标远离中心一定距离才移动
            if (moveDistance > 20) {
                // 移动玩家的世界坐标
                player.worldX += Math.cos(moveAngle) * player.speed;
                player.worldY += Math.sin(moveAngle) * player.speed;
                
                // 更新世界偏移(保持玩家在视觉中心)
                world.offsetX = -player.worldX + player.visualX;
                world.offsetY = -player.worldY + player.visualY;
            }
        }
        
        // 更新花瓣位置和旋转
        function updatePetals() {
            const petalType = player.petals[player.activePetalType];
            
            player.petalEntities.forEach((petal, index) => {
                // 花瓣旋转
                petal.angle += petal.rotateSpeed;
                
                // 更新花瓣世界坐标
                petal.worldX = player.worldX + Math.cos(petal.angle) * petal.distance;
                petal.worldY = player.worldY + Math.sin(petal.angle) * petal.distance;
                
                // 花瓣碰撞检测(直接接触攻击)
                checkPetalCollision(petal, index);
            });
        }
        
        // 花瓣碰撞检测(核心战斗逻辑:直接接触伤害)
        function checkPetalCollision(petal, petalIndex) {
            for (let i = entities.enemies.length - 1; i >= 0; i--) {
                const enemy = entities.enemies[i];
                const distance = Math.hypot(petal.worldX - enemy.worldX, petal.worldY - enemy.worldY);
                
                // 花瓣接触敌人 = 造成伤害
                if (distance < petal.size/2 + enemy.size/2) {
                    enemy.hp -= petal.damage;
                    
                    // 生成伤害粒子
                    entities.particles.push({
                        x: petal.worldX,
                        y: petal.worldY,
                        size: 3 + Math.random() * 2,
                        color: petal.color,
                        speed: 1 + Math.random() * 2,
                        angle: Math.random() * Math.PI * 2,
                        lifetime: 15
                    });
                    
                    // 敌人死亡
                    if (enemy.hp <= 0) {
                        // 掉落资源
                        spawnResources(enemy.worldX, enemy.worldY, enemy.type);
                        entities.enemies.splice(i, 1);
                        player.xp += enemy.maxHp * 2;
                        
                        // 升级检测
                        if (player.xp >= player.xpToNextLevel) {
                            levelUp();
                        }
                    }
                    break;
                }
            }
        }
        
        // 生成敌人
        function spawnEnemies() {
            if (frameCount % 120 !== 0 || entities.enemies.length > 10) return;
            
            const enemyTypes = [
                { type: 'bug', size: 15, hp: 10, speed: 2.5, color: '#34495e', damage: 1 },
                { type: 'larva', size: 18, hp: 15, speed: 1.8, color: '#8e44ad', damage: 2 },
                { type: 'small_flower', size: 22, hp: 25, speed: 1.5, color: '#e74c3c', damage: 3 }
            ];
            
            const enemyType = enemyTypes[Math.floor(Math.random() * enemyTypes.length)];
            
            // 随机生成在玩家周围一定距离
            const spawnDistance = 400 + Math.random() * 200;
            const spawnAngle = Math.random() * Math.PI * 2;
            
            entities.enemies.push({
                worldX: player.worldX + Math.cos(spawnAngle) * spawnDistance,
                worldY: player.worldY + Math.sin(spawnAngle) * spawnDistance,
                size: enemyType.size,
                color: enemyType.color,
                hp: enemyType.hp,
                maxHp: enemyType.hp,
                speed: enemyType.speed,
                damage: enemyType.damage,
                type: enemyType.type
            });
        }
        
        // 生成资源
        function spawnResources(x, y, enemyType) {
            // 掉落经验球
            entities.resources.push({
                worldX: x + (Math.random() - 0.5) * 30,
                worldY: y + (Math.random() - 0.5) * 30,
                size: 10,
                color: '#9370db',
                type: 'xp',
                value: 10,
                floatSpeed: 0.02 + Math.random() * 0.02
            });
            
            // 随机掉落花瓣
            if (Math.random() > 0.3) {
                const petalTypes = ['normal', 'fast', 'strong'];
                const randomPetal = petalTypes[Math.floor(Math.random() * petalTypes)];
                
                let color, size, typeId;
                if (randomPetal === 'normal') { color = '#ffd700'; size = 8; typeId = 1; }
                else if (randomPetal === 'fast') { color = '#1e90ff'; size = 6; typeId = 2; }
                else { color = '#ff6347'; size = 10; typeId = 3; }
                
                entities.resources.push({
                    worldX: x + (Math.random() - 0.5) * 40,
                    worldY: y + (Math.random() - 0.5) * 40,
                    size: size,
                    color: color,
                    type: 'petal',
                    petalType: typeId,
                    floatSpeed: 0.01 + Math.random() * 0.02
                });
            }
        }
        
        // 更新敌人AI
        function updateEnemies() {
            entities.enemies.forEach(enemy => {
                // 敌人向玩家移动
                const angle = Math.atan2(player.worldY - enemy.worldY, player.worldX - enemy.worldX);
                enemy.worldX += Math.cos(angle) * enemy.speed;
                enemy.worldY += Math.sin(angle) * enemy.speed;
                
                // 敌人接触玩家核心 = 玩家掉血
                const distanceToPlayer = Math.hypot(player.worldX - enemy.worldX, player.worldY - enemy.worldY);
                if (distanceToPlayer < player.coreSize/2 + enemy.size/2) {
                    player.hp -= enemy.damage * 0.1;
                    if (player.hp <= 0) {
                        resetGame();
                    }
                }
            });
        }
        
        // 资源收集(触碰即收集)
        function collectResources() {
            for (let i = entities.resources.length - 1; i >= 0; i--) {
                const resource = entities.resources[i];
                const distance = Math.hypot(player.worldX - resource.worldX, player.worldY - resource.worldY);
                
                // 触碰收集
                if (distance < player.coreSize + resource.size) {
                    if (resource.type === 'xp') {
                        player.xp += resource.value;
                        if (player.xp >= player.xpToNextLevel) {
                            levelUp();
                        }
                    } else if (resource.type === 'petal') {
                        // 收集花瓣
                        player.petals[resource.petalType].count++;
                        initPetals(); // 更新花瓣实体
                    }
                    
                    entities.resources.splice(i, 1);
                } else {
                    // 资源漂浮动画
                    resource.worldY += Math.sin(frameCount * resource.floatSpeed) * 0.8;
                }
            }
        }
        
        // 更新粒子特效
        function updateParticles() {
            for (let i = entities.particles.length - 1; i >= 0; i--) {
                const particle = entities.particles[i];
                particle.worldX = particle.x;
                particle.worldY = particle.y;
                
                particle.x += Math.cos(particle.angle) * particle.speed;
                particle.y += Math.sin(particle.angle) * particle.speed;
                particle.size *= 0.95;
                particle.lifetime--;
                
                if (particle.lifetime <= 0 || particle.size < 0.5) {
                    entities.particles.splice(i, 1);
                }
            }
        }
        
        // 玩家升级
        function levelUp() {
            player.level++;
            player.xp -= player.xpToNextLevel;
            player.xpToNextLevel = Math.floor(player.xpToNextLevel * 1.6);
            player.maxHp += 25;
            player.hp = player.maxHp;
            player.speed += 0.2;
            
            // 升级奖励花瓣
            player.petals[1].count += 3;
            initPetals();
        }
        
        // 重置游戏
        function resetGame() {
            player.worldX = 0;
            player.worldY = 0;
            world.offsetX = player.visualX;
            world.offsetY = player.visualY;
            
            player.level = 1;
            player.hp = 100;
            player.maxHp = 100;
            player.xp = 0;
            player.xpToNextLevel = 100;
            player.speed = 4;
            
            // 重置花瓣
            player.petals[1].count = 15;
            player.petals[2].count = 8;
            player.petals[3].count = 5;
            player.activePetalType = 1;
            
            // 清空实体
            entities.enemies = [];
            entities.resources = [];
            entities.particles = [];
            
            initPetals();
        }
        
        // 更新UI
        function updateUI() {
            const totalPetals = player.petals[1].count + player.petals[2].count + player.petals[3].count;
            
            statsPanel.innerHTML = `
                <div><span class="level">等级: ${player.level}</span></div>
                <div><span class="hp">生命值: ${Math.floor(player.hp)}/${player.maxHp}</span></div>
                <div><span class="petals">花瓣数: ${totalPetals}</span></div>
                <div><span class="xp">经验: ${player.xp}/${player.xpToNextLevel}</span></div>
            `;
            
            // 更新花瓣槽位计数
            document.querySelectorAll('.petal-slot .count')[0].textContent = player.petals[1].count;
            document.querySelectorAll('.petal-slot .count')[1].textContent = player.petals[2].count;
            document.querySelectorAll('.petal-slot .count')[2].textContent = player.petals[3].count;
        }
        
        // ======================
        // 渲染系统
        // ======================
        function renderGame() {
            // 清空画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制背景网格
            ctx.strokeStyle = '#222';
            ctx.lineWidth = 1;
            
            // 绘制无限网格(跟随世界移动)
            const gridSize = 40;
            const startX = (world.offsetX % gridSize) - gridSize;
            const startY = (world.offsetY % gridSize) - gridSize;
            
            for (let x = startX; x < canvas.width; x += gridSize) {
                ctx.beginPath();
                ctx.moveTo(x, 0);
                ctx.lineTo(x, canvas.height);
                ctx.stroke();
            }
            
            for (let y = startY; y < canvas.height; y += gridSize) {
                ctx.beginPath();
                ctx.moveTo(0, y);
                ctx.lineTo(canvas.width, y);
                ctx.stroke();
            }
            
            // 绘制资源
            entities.resources.forEach(resource => {
                const screenX = resource.worldX + world.offsetX;
                const screenY = resource.worldY + world.offsetY;
                
                ctx.beginPath();
                ctx.arc(screenX, screenY, resource.size, 0, Math.PI * 2);
                ctx.fillStyle = resource.color;
                ctx.fill();
                ctx.strokeStyle = '#fff';
                ctx.lineWidth = 0.5;
                ctx.stroke();
            });
            
            // 绘制敌人
            entities.enemies.forEach(enemy => {
                const screenX = enemy.worldX + world.offsetX;
                const screenY = enemy.worldY + world.offsetY;
                
                ctx.save();
                ctx.translate(screenX, screenY);
                
                // 敌人主体
                ctx.beginPath();
                ctx.arc(0, 0, enemy.size/2, 0, Math.PI * 2);
                ctx.fillStyle = enemy.color;
                ctx.fill();
                ctx.strokeStyle = '#000';
                ctx.lineWidth = 1;
                ctx.stroke();
                
                // HP条
                const hpWidth = enemy.size;
                ctx.fillStyle = '#e74c3c';
                ctx.fillRect(-hpWidth/2, -enemy.size/2 - 5, hpWidth * (enemy.hp/enemy.maxHp), 3);
                ctx.strokeStyle = '#000';
                ctx.strokeRect(-hpWidth/2, -enemy.size/2 - 5, hpWidth, 3);
                
                ctx.restore();
            });
            
            // 绘制粒子
            entities.particles.forEach(particle => {
                const screenX = particle.x + world.offsetX;
                const screenY = particle.y + world.offsetY;
                
                ctx.beginPath();
                ctx.arc(screenX, screenY, particle.size, 0, Math.PI * 2);
                ctx.fillStyle = particle.color;
                ctx.fill();
            });
            
            // 绘制玩家花瓣(核心战斗单元)
            player.petalEntities.forEach(petal => {
                const screenX = petal.worldX + world.offsetX;
                const screenY = petal.worldY + world.offsetY;
                
                ctx.beginPath();
                ctx.arc(screenX, screenY, petal.size/2, 0, Math.PI * 2);
                ctx.fillStyle = petal.color;
                ctx.fill();
                ctx.strokeStyle = '#fff';
                ctx.lineWidth = 0.5;
                ctx.stroke();
            });
            
            // 绘制玩家核心(始终在视觉中心)
            ctx.beginPath();
            ctx.arc(player.visualX, player.visualY, player.coreSize/2, 0, Math.PI * 2);
            ctx.fillStyle = '#2ecc71';
            ctx.fill();
            ctx.strokeStyle = '#27ae60';
            ctx.lineWidth = 2;
            ctx.stroke();
            
            // 玩家核心内部
            ctx.beginPath();
            ctx.arc(player.visualX, player.visualY, player.coreSize/6, 0, Math.PI * 2);
            ctx.fillStyle = '#27ae60';
            ctx.fill();
        }
        
        // ======================
        // 游戏主循环
        // ======================
        function gameLoop() {
            // 更新游戏逻辑
            updatePlayerMovement();
            spawnEnemies();
            updatePetals();
            updateEnemies();
            collectResources();
            updateParticles();
            updateUI();
            
            // 渲染画面
            renderGame();
            
            frameCount++;
            requestAnimationFrame(gameLoop);
        }
        
        // 初始化游戏
        function initGame() {
            world.offsetX = player.visualX;
            world.offsetY = player.visualY;
            initPetals();
            gameLoop();
        }
        
        // 启动游戏
        window.addEventListener('load', initGame);
    </script>
</body>
</html>