{"id":80,"date":"2025-07-30T09:20:01","date_gmt":"2025-07-30T01:20:01","guid":{"rendered":"http:\/\/152.136.195.60\/?p=80"},"modified":"2025-07-30T09:20:01","modified_gmt":"2025-07-30T01:20:01","slug":"%e5%88%87%e6%b0%b4%e6%9e%9c","status":"publish","type":"post","link":"https:\/\/liusaide.cn\/index.php\/2025\/07\/30\/%e5%88%87%e6%b0%b4%e6%9e%9c\/","title":{"rendered":"\u5207\u6c34\u679c"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"zh\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n    <title>\u5207\u6c34\u679c<\/title>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=ZCOOL+KuaiLe&#038;display=swap\" rel=\"stylesheet\">\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/tone\/14.7.77\/Tone.js\"><\/script>\n    <style>\n        body {\n            margin: 0;\n            padding: 0;\n            background-color: #3d2314;\n            font-family: 'ZCOOL KuaiLe', cursive, 'Arial', sans-serif;\n            overflow: hidden;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            height: 100vh;\n        }\n        #game-container {\n            position: relative;\n            width: 100%;\n            height: 100%;\n            max-width: 600px;\n            max-height: 800px;\n            background-image: url('https:\/\/www.transparenttextures.com\/patterns\/wood-pattern.png'), linear-gradient(to bottom, #8e6e53, #6a513b);\n            background-repeat: repeat, no-repeat;\n            cursor: crosshair;\n            box-shadow: 0 0 20px rgba(0,0,0,0.5);\n            border: 5px solid #5a3821;\n        }\n        canvas {\n            display: block;\n            width: 100%;\n            height: 100%;\n        }\n        #ui-container {\n            position: absolute;\n            top: 10px;\n            left: 10px;\n            right: 10px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            color: white;\n            text-shadow: 2px 2px 4px #000;\n        }\n        #score, #lives {\n            font-size: 2rem;\n        }\n        #modal-overlay {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.7);\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            color: white;\n            text-align: center;\n        }\n        #modal-overlay h2 {\n            font-size: 3rem;\n            margin-bottom: 10px;\n        }\n        #modal-overlay p {\n            font-size: 1.5rem;\n            margin-top: 0;\n        }\n        #start-button, #restart-button {\n            padding: 15px 40px;\n            font-size: 1.8rem;\n            font-family: 'ZCOOL KuaiLe', cursive;\n            background: linear-gradient(145deg, #4CAF50, #45a049);\n            color: white;\n            border: 3px solid #fff;\n            border-radius: 15px;\n            cursor: pointer;\n            box-shadow: 0 5px 10px rgba(0,0,0,0.3);\n            transition: all 0.2s ease;\n        }\n        #start-button:hover, #restart-button:hover {\n            transform: scale(1.05);\n            background: linear-gradient(145deg, #5cb85c, #4CAF50);\n        }\n        #final-score-text {\n            color: #ffeb3b;\n        }\n    <\/style>\n<\/head>\n<body>\n    <div id=\"game-container\">\n        <canvas id=\"game-canvas\"><\/canvas>\n        <div id=\"ui-container\">\n            <div id=\"score\">\u5f97\u5206: 0<\/div>\n            <div id=\"lives\">\u2764\ufe0f\u2764\ufe0f\u2764\ufe0f<\/div>\n        <\/div>\n        <div id=\"modal-overlay\">\n            <h2>\u5207\u6c34\u679c<\/h2>\n            <p>\u5207\u5f00\u6c34\u679c\uff0c\u907f\u5f00\u70b8\u5f39\uff01<\/p>\n            <button id=\"start-button\">\u5f00\u59cb\u6e38\u620f<\/button>\n        <\/div>\n    <\/div>\n\n    <script>\n        const canvas = document.getElementById('game-canvas');\n        const ctx = canvas.getContext('2d');\n        const gameContainer = document.getElementById('game-container');\n        const scoreEl = document.getElementById('score');\n        const livesEl = document.getElementById('lives');\n        const modalOverlay = document.getElementById('modal-overlay');\n        const startButton = document.getElementById('start-button');\n        \n        \/\/ Resize canvas to fit container\n        function resizeCanvas() {\n            canvas.width = gameContainer.clientWidth;\n            canvas.height = gameContainer.clientHeight;\n        }\n        window.addEventListener('resize', resizeCanvas);\n        resizeCanvas();\n\n        let score, lives, isGameOver, gameLoopId;\n        let fruits = [];\n        let particles = [];\n        let slicePoints = [];\n        let isSlicing = false;\n        \n        const gravity = 0.03;\n        const fruitColors = ['#ff4757', '#2ed573', '#ffa502', '#ff6348', '#f1c40f'];\n\n        \/\/ Sound Effects with Tone.js\n        const sliceSynth = new Tone.Synth({\n            oscillator: { type: 'triangle' },\n            envelope: { attack: 0.01, decay: 0.1, sustain: 0.2, release: 0.2 }\n        }).toDestination();\n        \n        const bombSynth = new Tone.Synth({\n            oscillator: { type: 'fmsquare', modulationType: 'sawtooth', modulationIndex: 3, harmonicity: 3.4 },\n            envelope: { attack: 0.05, decay: 0.3, sustain: 0.1, release: 0.8 },\n            pitchDecay: 0.05\n        }).toDestination();\n\n        class Fruit {\n            constructor(x, y, radius, color, velocity) {\n                this.x = x;\n                this.y = y;\n                this.radius = radius;\n                this.color = color;\n                this.velocity = velocity;\n                this.isBomb = color === 'black';\n            }\n            draw() {\n                ctx.fillStyle = this.color;\n                ctx.beginPath();\n                ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);\n                ctx.fill();\n                if(this.isBomb){\n                    ctx.fillStyle = 'white';\n                    ctx.fillRect(this.x + this.radius * 0.5, this.y - this.radius * 0.8, 4, 15);\n                }\n            }\n            update() {\n                this.velocity.y += gravity;\n                this.x += this.velocity.x;\n                this.y += this.velocity.y;\n            }\n        }\n\n        class Particle {\n            constructor(x, y, radius, color, velocity) {\n                this.x = x;\n                this.y = y;\n                this.radius = radius;\n                this.color = color;\n                this.velocity = velocity;\n                this.alpha = 1;\n            }\n            draw() {\n                ctx.save();\n                ctx.globalAlpha = this.alpha;\n                ctx.fillStyle = this.color;\n                ctx.beginPath();\n                ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);\n                ctx.fill();\n                ctx.restore();\n            }\n            update() {\n                this.velocity.y += gravity * 0.5;\n                this.x += this.velocity.x;\n                this.y += this.velocity.y;\n                this.alpha -= 0.02;\n            }\n        }\n\n        function init() {\n            score = 0;\n            lives = 3;\n            isGameOver = false;\n            fruits = [];\n            particles = [];\n            updateUI();\n            modalOverlay.style.display = 'none';\n            gameLoop();\n        }\n\n        function updateUI() {\n            scoreEl.textContent = `\u5f97\u5206: ${score}`;\n            livesEl.textContent = '\u2764\ufe0f'.repeat(lives);\n        }\n\n        function spawnFruit() {\n            const radius = Math.random() * 20 + 20;\n            const x = Math.random() * (canvas.width - radius * 2) + radius;\n            const y = canvas.height + radius;\n            \n            const isBomb = Math.random() < 0.15;\n            const color = isBomb ? 'black' : fruitColors[Math.floor(Math.random() * fruitColors.length)];\n            \n            const velocity = {\n                x: (Math.random() - 0.5) * 6,\n                y: - (Math.random() * 4 + 8)\n            };\n            fruits.push(new Fruit(x, y, radius, color, velocity));\n        }\n\n        function gameLoop() {\n            if (isGameOver) {\n                cancelAnimationFrame(gameLoopId);\n                showGameOver();\n                return;\n            }\n\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n            if (Math.random() < 0.05) {\n                spawnFruit();\n            }\n\n            fruits.forEach((fruit, index) => {\n                fruit.update();\n                fruit.draw();\n                if (fruit.y > canvas.height + fruit.radius) {\n                    if (!fruit.isBomb) {\n                        lives--;\n                        updateUI();\n                        if (lives <= 0) isGameOver = true;\n                    }\n                    fruits.splice(index, 1);\n                }\n            });\n\n            particles.forEach((particle, index) => {\n                particle.update();\n                particle.draw();\n                if (particle.alpha <= 0) {\n                    particles.splice(index, 1);\n                }\n            });\n            \n            drawSlice();\n\n            gameLoopId = requestAnimationFrame(gameLoop);\n        }\n\n        function drawSlice() {\n            if (slicePoints.length > 1) {\n                ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';\n                ctx.lineWidth = 5;\n                ctx.beginPath();\n                ctx.moveTo(slicePoints[0].x, slicePoints[0].y);\n                for (let i = 1; i < slicePoints.length; i++) {\n                    ctx.lineTo(slicePoints[i].x, slicePoints[i].y);\n                }\n                ctx.stroke();\n            }\n            if(slicePoints.length > 10) {\n                slicePoints.shift();\n            }\n        }\n\n        function handleSlice(x, y) {\n            fruits.forEach((fruit, index) => {\n                const dist = Math.hypot(x - fruit.x, y - fruit.y);\n                if (dist < fruit.radius) {\n                    if (fruit.isBomb) {\n                        bombSynth.triggerAttackRelease('C2', '0.5s');\n                        isGameOver = true;\n                    } else {\n                        sliceSynth.triggerAttackRelease('C5', '0.1s');\n                        for (let i = 0; i < 10; i++) {\n                            particles.push(new Particle(fruit.x, fruit.y, Math.random() * 3 + 1, fruit.color, {\n                                x: (Math.random() - 0.5) * 6,\n                                y: (Math.random() - 0.5) * 6\n                            }));\n                        }\n                        score++;\n                        updateUI();\n                    }\n                    fruits.splice(index, 1);\n                }\n            });\n        }\n        \n        function showGameOver() {\n            modalOverlay.innerHTML = `\n                <h2>\u6e38\u620f\u7ed3\u675f!<\/h2>\n                <p>\u4f60\u7684\u5f97\u5206: <span id=\"final-score-text\">${score}<\/span><\/p>\n                <button id=\"restart-button\">\u91cd\u65b0\u5f00\u59cb<\/button>\n            `;\n            document.getElementById('restart-button').addEventListener('click', init);\n            modalOverlay.style.display = 'flex';\n        }\n\n        function startSlice(e) {\n            isSlicing = true;\n            slicePoints = [];\n        }\n\n        function moveSlice(e) {\n            if (!isSlicing) return;\n            e.preventDefault();\n            const rect = canvas.getBoundingClientRect();\n            const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX;\n            const clientY = e.type.includes('touch') ? e.touches[0].clientY : e.clientY;\n            const x = clientX - rect.left;\n            const y = clientY - rect.top;\n            slicePoints.push({x, y});\n            handleSlice(x, y);\n        }\n\n        function endSlice() {\n            isSlicing = false;\n            slicePoints = [];\n        }\n\n        startButton.addEventListener('click', () => {\n             Tone.start(); \/\/ Required for audio to play on user interaction\n             init();\n        });\n\n        \/\/ Event Listeners\n        canvas.addEventListener('mousedown', startSlice);\n        canvas.addEventListener('mousemove', moveSlice);\n        canvas.addEventListener('mouseup', endSlice);\n        canvas.addEventListener('mouseleave', endSlice);\n\n        canvas.addEventListener('touchstart', startSlice);\n        canvas.addEventListener('touchmove', moveSlice);\n        canvas.addEventListener('touchend', endSlice);\n        canvas.addEventListener('touchcancel', endSlice);\n\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>\u5207\u6c34\u679c \u5f97\u5206: 0 \u2764\ufe0f\u2764\ufe0f\u2764\ufe0f \u5207\u6c34\u679c \u5207\u5f00\u6c34\u679c\uff0c\u907f\u5f00\u70b8\u5f39\uff01 \u5f00\u59cb\u6e38\u620f<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-80","post","type-post","status-publish","format-standard","hentry","category-8"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/posts\/80","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/comments?post=80"}],"version-history":[{"count":1,"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions"}],"predecessor-version":[{"id":81,"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions\/81"}],"wp:attachment":[{"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/media?parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/categories?post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/liusaide.cn\/index.php\/wp-json\/wp\/v2\/tags?post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}