<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>昆蟲捕捉遊戲</title>
<script src="https://cdn.tailwindcss.com">
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;500;700&display=swap');
body {
font-family: 'Noto Sans TC', sans-serif;
overflow: hidden;
touch-action: manipulation;
}
.garden {
background: linear-gradient(to bottom, #a8e063, #56ab2f);
position: relative;
overflow: hidden;
}
.fence {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='60' viewBox='0 0 100 60'%3E%3Cpath d='M10,0 L10,40 L15,40 L15,0 M30,0 L30,40 L35,40 L35,0 M50,0 L50,40 L55,40 L55,0 M70,0 L70,40 L75,40 L75,0 M90,0 L90,40 L95,40 L95,0' stroke='%23855E42' stroke-width='5'/%3E%3Cpath d='M0,40 L100,40' stroke='%23855E42' stroke-width='5'/%3E%3C/svg%3E");
background-repeat: repeat-x;
background-size: 100px 60px;
height: 60px;
width: 100%;
position: absolute;
bottom: 0;
z-index: 10;
}
.insect {
position: absolute;
cursor: pointer;
transition: transform 0.3s ease;
z-index: 5;
}
.insect:hover {
transform: scale(1.1);
}
.flower {
position: absolute;
z-index: 1;
opacity: 0.8;
}
.flying-animation {
animation: fly-away 1.5s forwards;
}
@keyframes fly-away {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: translateY(-200px) scale(0.2);
opacity: 0;
}
}
.prompt-box {
background: rgba(255, 255, 255, 0.9);
border: 3px solid #56ab2f;
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
.win-screen {
background: rgba(0, 0, 0, 0.8);
z-index: 50;
}
.dev-button {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 100;
background: #3b82f6;
color: white;
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
cursor: pointer;
transition: all 0.3s ease;
}
.dev-button:hover {
transform: scale(1.1);
background: #2563eb;
}
.code-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 200;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.code-modal.active {
opacity: 1;
pointer-events: auto;
}
.code-container {
background: white;
width: 90%;
max-width: 1000px;
height: 80%;
border-radius: 10px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.code-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background: #f3f4f6;
border-bottom: 1px solid #e5e7eb;
}
.code-content {
flex: 1;
overflow-y: auto;
padding: 20px;
background: #1e293b;
color: #e2e8f0;
font-family: monospace;
white-space: pre;
line-height: 1.5;
font-size: 14px;
}
.copy-success {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: #10b981;
color: white;
padding: 10px 20px;
border-radius: 5px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
opacity: 0;
transition: opacity 0.3s ease;
z-index: 300;
}
.copy-success.active {
opacity: 1;
}
</style>
<style>*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/* ! tailwindcss v3.4.16 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0px}.mx-auto{margin-left:auto;margin-right:auto}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-1{margin-top:0.25rem}.flex{display:flex}.hidden{display:none}.h-96{height:24rem}.h-screen{height:100vh}.w-full{width:100%}.max-w-md{max-width:28rem}.max-w-xl{max-width:36rem}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-3{gap:0.75rem}.rounded-lg{border-radius:0.5rem}.rounded-md{border-radius:0.375rem}.rounded-xl{border-radius:0.75rem}.border-4{border-width:4px}.border-green-800{--tw-border-opacity:1;border-color:rgb(22 101 52 / var(--tw-border-opacity, 1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity:1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-600{--tw-bg-opacity:1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-4{padding:1rem}.p-8{padding:2rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2{padding-top:0.5rem;padding-bottom:0.5rem}.py-3{padding-top:0.75rem;padding-bottom:0.75rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity:1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.transition-colors{transition-property:color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;transition-property:color, background-color, border-color, text-decoration-color, fill, stroke;transition-property:color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-600:hover{--tw-bg-opacity:1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}.hover\:bg-green-700:hover{--tw-bg-opacity:1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}</style>
</head>
<body class="bg-green-100 h-screen flex flex-col items-center justify-center p-4">
<div class="prompt-box w-full max-w-xl mx-auto p-4 mb-4 text-center">
<h2 class="text-xl font-bold text-green-800">請捕捉:<span id="target-insect" class="text-2xl text-red-600">蝴蝶</span>
</h2>
<p class="text-sm mt-1">已捕捉:<span id="caught-count">0</span> / <span id="total-count">7</span>
</p>
</div>
<div class="garden w-full max-w-xl h-96 rounded-xl relative border-4 border-green-800 mx-auto">
<div class="fence">
</div>
<div class="flower" style="left: 334.32482px; top: 239.108317px;">
<svg width="15" height="15" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FFFFFF">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="#FFFFFF">
</path>
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="#FFFFFF">
</path>
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="#FFFFFF">
</path>
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="#FFFFFF">
</path>
</svg>
</div>
<div class="flower" style="left: 436.875151px; top: 195.896609px;">
<svg width="28" height="28" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FF6B6B">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<circle cx="10" cy="10" r="8" fill="#FF6B6B">
</circle>
<circle cx="30" cy="10" r="8" fill="#FF6B6B">
</circle>
<circle cx="10" cy="30" r="8" fill="#FF6B6B">
</circle>
<circle cx="30" cy="30" r="8" fill="#FF6B6B">
</circle>
</svg>
</div>
<div class="flower" style="left: 6.777734px; top: 173.924523px;">
<svg width="26" height="26" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FFCC5C">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="#FFCC5C">
</path>
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="#FFCC5C">
</path>
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="#FFCC5C">
</path>
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="#FFCC5C">
</path>
</svg>
</div>
<div class="flower" style="left: 505.159896px; top: 252.575165px;">
<svg width="24" height="24" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#88D8B0">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="#88D8B0">
</path>
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="#88D8B0">
</path>
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="#88D8B0">
</path>
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="#88D8B0">
</path>
</svg>
</div>
<div class="flower" style="left: 215.36641px; top: 273.332857px;">
<svg width="19" height="19" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FF85A2">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="#FF85A2">
</path>
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="#FF85A2">
</path>
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="#FF85A2">
</path>
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="#FF85A2">
</path>
</svg>
</div>
<div class="flower" style="left: 388.097559px; top: 181.513264px;">
<svg width="18" height="18" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#88D8B0">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<circle cx="10" cy="10" r="8" fill="#88D8B0">
</circle>
<circle cx="30" cy="10" r="8" fill="#88D8B0">
</circle>
<circle cx="10" cy="30" r="8" fill="#88D8B0">
</circle>
<circle cx="30" cy="30" r="8" fill="#88D8B0">
</circle>
</svg>
</div>
<div class="flower" style="left: 172.02284px; top: 89.275272px;">
<svg width="26" height="26" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FFFFFF">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="#FFFFFF">
</path>
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="#FFFFFF">
</path>
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="#FFFFFF">
</path>
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="#FFFFFF">
</path>
</svg>
</div>
<div class="flower" style="left: 138.856404px; top: 210.431362px;">
<svg width="28" height="28" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FFFFFF">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<circle cx="10" cy="10" r="8" fill="#FFFFFF">
</circle>
<circle cx="30" cy="10" r="8" fill="#FFFFFF">
</circle>
<circle cx="10" cy="30" r="8" fill="#FFFFFF">
</circle>
<circle cx="30" cy="30" r="8" fill="#FFFFFF">
</circle>
</svg>
</div>
<div class="flower" style="left: 139.017941px; top: 273.220991px;">
<svg width="22" height="22" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#B5EAD7">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<circle cx="10" cy="10" r="8" fill="#B5EAD7">
</circle>
<circle cx="30" cy="10" r="8" fill="#B5EAD7">
</circle>
<circle cx="10" cy="30" r="8" fill="#B5EAD7">
</circle>
<circle cx="30" cy="30" r="8" fill="#B5EAD7">
</circle>
</svg>
</div>
<div class="flower" style="left: 395.264834px; top: 145.267778px;">
<svg width="23" height="23" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FFFFFF">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="#FFFFFF">
</path>
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="#FFFFFF">
</path>
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="#FFFFFF">
</path>
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="#FFFFFF">
</path>
</svg>
</div>
<div class="flower" style="left: 465.622547px; top: 51.706573px;">
<svg width="32" height="32" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FFFFFF">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<circle cx="10" cy="10" r="8" fill="#FFFFFF">
</circle>
<circle cx="30" cy="10" r="8" fill="#FFFFFF">
</circle>
<circle cx="10" cy="30" r="8" fill="#FFFFFF">
</circle>
<circle cx="30" cy="30" r="8" fill="#FFFFFF">
</circle>
</svg>
</div>
<div class="flower" style="left: 353.912784px; top: 186.652365px;">
<svg width="24" height="24" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="#FF85A2">
</circle>
<circle cx="20" cy="20" r="5" fill="#FFEB3B">
</circle>
<circle cx="10" cy="10" r="8" fill="#FF85A2">
</circle>
<circle cx="30" cy="10" r="8" fill="#FF85A2">
</circle>
<circle cx="10" cy="30" r="8" fill="#FF85A2">
</circle>
<circle cx="30" cy="30" r="8" fill="#FF85A2">
</circle>
</svg>
</div>
<div class="insect" data-name="蝴蝶" style="left: 331.971734px; top: 85.600978px;">
<svg width="60" height="45" viewBox="0 0 100 75">
<path d="M50,20 C60,0 80,5 90,20 C95,35 80,50 50,45 C20,50 5,35 10,20 C20,5 40,0 50,20" fill="#FFCC00" stroke="#000" stroke-width="1.5">
</path>
<path d="M50,20 L50,45" stroke="#000" stroke-width="2">
</path>
<circle cx="50" cy="15" r="5" fill="#000">
</circle>
<path d="M45,10 L40,5" stroke="#000" stroke-width="1">
</path>
<path d="M55,10 L60,5" stroke="#000" stroke-width="1">
</path>
</svg>
</div>
<div class="insect" data-name="蜜蜂" style="left: 389.785328px; top: 166.315536px;">
<svg width="40" height="30" viewBox="0 0 80 60">
<ellipse cx="40" cy="30" rx="20" ry="15" fill="#FFA500" stroke="#000" stroke-width="1.5">
</ellipse>
<path d="M40,15 C50,5 60,10 55,20" fill="rgba(255,255,255,0.7)" stroke="#000" stroke-width="1">
</path>
<path d="M40,15 C30,5 20,10 25,20" fill="rgba(255,255,255,0.7)" stroke="#000" stroke-width="1">
</path>
<path d="M20,30 L60,30" stroke="#000" stroke-width="1.5">
</path>
<path d="M25,25 L55,25" stroke="#000" stroke-width="1.5">
</path>
<path d="M25,35 L55,35" stroke="#000" stroke-width="1.5">
</path>
<circle cx="60" cy="30" r="5" fill="#000">
</circle>
<path d="M65,25 L70,20" stroke="#000" stroke-width="1">
</path>
<path d="M65,35 L70,40" stroke="#000" stroke-width="1">
</path>
</svg>
</div>
<div class="insect" data-name="蜻蜓" style="left: 367.656448px; top: 199.673183px;">
<svg width="70" height="52.5" viewBox="0 0 120 60">
<path d="M30,30 L90,30" stroke="#000" stroke-width="2">
</path>
<ellipse cx="90" cy="30" rx="10" ry="5" fill="#000">
</ellipse>
<path d="M40,30 L20,15" stroke="#000" stroke-width="1">
</path>
<path d="M40,30 L20,45" stroke="#000" stroke-width="1">
</path>
<path d="M60,30 L40,10" stroke="#000" stroke-width="1">
</path>
<path d="M60,30 L40,50" stroke="#000" stroke-width="1">
</path>
<path d="M20,15 L40,10" fill="none" stroke="#000" stroke-width="0.5">
</path>
<path d="M20,45 L40,50" fill="none" stroke="#000" stroke-width="0.5">
</path>
<path d="M20,15 L40,10" fill="#87CEEB" fill-opacity="0.7">
</path>
<path d="M20,45 L40,50" fill="#87CEEB" fill-opacity="0.7">
</path>
<path d="M40,10 L60,30" fill="#87CEEB" fill-opacity="0.7">
</path>
<path d="M40,50 L60,30" fill="#87CEEB" fill-opacity="0.7">
</path>
</svg>
</div>
<div class="insect" data-name="瓢蟲" style="left: 487.431641px; top: 68.897497px;">
<svg width="30" height="22.5" viewBox="0 0 60 40">
<ellipse cx="30" cy="20" rx="20" ry="15" fill="#FF6347" stroke="#000" stroke-width="1.5">
</ellipse>
<path d="M30,5 L30,35" stroke="#000" stroke-width="1">
</path>
<circle cx="20" cy="15" r="3" fill="#000">
</circle>
<circle cx="40" cy="15" r="3" fill="#000">
</circle>
<circle cx="25" cy="25" r="3" fill="#000">
</circle>
<circle cx="35" cy="25" r="3" fill="#000">
</circle>
<circle cx="30" cy="15" r="3" fill="#000">
</circle>
<path d="M10,20 C5,15 5,10 10,5 C15,0 25,0 30,5" fill="#000">
</path>
<path d="M50,20 C55,15 55,10 50,5 C45,0 35,0 30,5" fill="#000">
</path>
</svg>
</div>
<div class="insect" data-name="螳螂" style="left: 505.446832px; top: 220.971985px;">
<svg width="50" height="37.5" viewBox="0 0 80 60">
<path d="M40,10 L40,50" stroke="#000" stroke-width="2">
</path>
<ellipse cx="40" cy="15" rx="5" ry="7" fill="#90EE90" stroke="#000" stroke-width="1.5">
</ellipse>
<path d="M35,12 L30,8" stroke="#000" stroke-width="1">
</path>
<path d="M45,12 L50,8" stroke="#000" stroke-width="1">
</path>
<path d="M40,22 L30,40" stroke="#000" stroke-width="2">
</path>
<path d="M40,22 L50,40" stroke="#000" stroke-width="2">
</path>
<path d="M30,40 L20,35" stroke="#000" stroke-width="2">
</path>
<path d="M50,40 L60,35" stroke="#000" stroke-width="2">
</path>
<path d="M40,30 L20,20" stroke="#000" stroke-width="2">
</path>
<path d="M20,20 L10,30" stroke="#000" stroke-width="2">
</path>
<path d="M40,30 L60,20" stroke="#000" stroke-width="2">
</path>
<path d="M60,20 L70,30" stroke="#000" stroke-width="2">
</path>
</svg>
</div>
<div class="insect" data-name="蟋蟀" style="left: 518.249198px; top: 183.005108px;">
<svg width="36" height="27" viewBox="0 0 80 50">
<ellipse cx="40" cy="25" rx="15" ry="10" fill="#8B4513" stroke="#000" stroke-width="1.5">
</ellipse>
<path d="M25,25 L15,15" stroke="#000" stroke-width="1.5">
</path>
<path d="M25,25 L15,35" stroke="#000" stroke-width="1.5">
</path>
<path d="M55,25 L65,15" stroke="#000" stroke-width="1.5">
</path>
<path d="M55,25 L65,35" stroke="#000" stroke-width="1.5">
</path>
<path d="M40,35 L35,45" stroke="#000" stroke-width="1.5">
</path>
<path d="M40,35 L45,45" stroke="#000" stroke-width="1.5">
</path>
<path d="M55,25 L70,20" stroke="#000" stroke-width="1">
</path>
<path d="M55,25 L70,30" stroke="#000" stroke-width="1">
</path>
<circle cx="50" cy="20" r="2" fill="#000">
</circle>
<circle cx="30" cy="20" r="2" fill="#000">
</circle>
</svg>
</div>
<div class="insect" data-name="蝗蟲" style="left: 281.854144px; top: 191.839125px;">
<svg width="44" height="33" viewBox="0 0 90 50">
<ellipse cx="45" cy="25" rx="20" ry="10" fill="#BDB76B" stroke="#000" stroke-width="1.5">
</ellipse>
<path d="M25,25 L15,15" stroke="#000" stroke-width="1.5">
</path>
<path d="M25,25 L15,35" stroke="#000" stroke-width="1.5">
</path>
<path d="M65,25 L75,15" stroke="#000" stroke-width="1.5">
</path>
<path d="M65,25 L75,35" stroke="#000" stroke-width="1.5">
</path>
<path d="M45,35 L35,50" stroke="#000" stroke-width="2">
</path>
<path d="M45,35 L55,50" stroke="#000" stroke-width="2">
</path>
<path d="M45,15 L35,5" stroke="#000" stroke-width="1">
</path>
<path d="M45,15 L55,5" stroke="#000" stroke-width="1">
</path>
<path d="M35,5 L55,5" fill="none" stroke="#000" stroke-width="0.5">
</path>
<path d="M35,5 L55,5" fill="#BDB76B" fill-opacity="0.7">
</path>
<circle cx="60" cy="20" r="2" fill="#000">
</circle>
<circle cx="30" cy="20" r="2" fill="#000">
</circle>
</svg>
</div>
</div>
<div id="win-screen" class="win-screen hidden fixed inset-0 flex items-center justify-center">
<div class="bg-white p-8 rounded-xl text-center max-w-md">
<h2 class="text-3xl font-bold text-green-600 mb-4">恭喜完成!</h2>
<p class="text-xl mb-6">你成功捕捉了所有的昆蟲!</p>
<button id="restart-btn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-6 rounded-lg transition-colors">再玩一次</button>
</div>
</div>
<!-- 開發人員按鈕 -->
<div id="dev-button" class="dev-button">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="16 18 22 12 16 6">
</polyline>
<polyline points="8 6 2 12 8 18">
</polyline>
</svg>
</div>
<!-- 程式碼顯示模態框 -->
<div id="code-modal" class="code-modal">
<div class="code-container">
<div class="code-header">
<h3 class="font-bold text-lg">完整程式碼</h3>
<div class="flex gap-3">
<button id="copy-btn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md transition-colors">複製程式碼</button>
<button id="close-modal-btn" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-md transition-colors">關閉</button>
</div>
</div>
<div id="code-content" class="code-content">
</div>
</div>
</div>
<!-- 複製成功提示 -->
<div id="copy-success" class="copy-success">已成功複製程式碼!</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const garden = document.querySelector('.garden');
const targetInsectElement = document.getElementById('target-insect');
const caughtCountElement = document.getElementById('caught-count');
const totalCountElement = document.getElementById('total-count');
const winScreen = document.getElementById('win-screen');
const restartBtn = document.getElementById('restart-btn');
// 開發人員功能相關元素
const devButton = document.getElementById('dev-button');
const codeModal = document.getElementById('code-modal');
const codeContent = document.getElementById('code-content');
const copyBtn = document.getElementById('copy-btn');
const closeModalBtn = document.getElementById('close-modal-btn');
const copySuccess = document.getElementById('copy-success');
// 昆蟲資料
const insects = [
{ name: '蝴蝶', color: '#FFCC00', wingSpan: 30, speed: 2 },
{ name: '蜜蜂', color: '#FFA500', wingSpan: 20, speed: 3 },
{ name: '蜻蜓', color: '#87CEEB', wingSpan: 35, speed: 4 },
{ name: '瓢蟲', color: '#FF6347', wingSpan: 15, speed: 1.5 },
{ name: '螳螂', color: '#90EE90', wingSpan: 25, speed: 1 },
{ name: '蟋蟀', color: '#8B4513', wingSpan: 18, speed: 2.5 },
{ name: '蝗蟲', color: '#BDB76B', wingSpan: 22, speed: 2.2 }
];
let insectElements = [];
let caughtInsects = 0;
let targetInsect = null;
let gameActive = true;
// 初始化遊戲
function initGame() {
// 重置遊戲狀態
garden.innerHTML = '<div class="fence">
</div>';
insectElements = [];
caughtInsects = 0;
gameActive = true;
// 添加花朵
addFlowers();
// 添加昆蟲
insects.forEach(insect => {
const insectElement = createInsect(insect);
insectElements.push({
element: insectElement,
data: insect,
caught: false
});
garden.appendChild(insectElement);
});
// 更新計數
totalCountElement.textContent = insects.length;
caughtCountElement.textContent = caughtInsects;
// 選擇目標昆蟲
selectTargetInsect();
// 開始昆蟲移動
animateInsects();
}
// 創建昆蟲元素
function createInsect(insect) {
const insectElement = document.createElement('div');
insectElement.className = 'insect';
insectElement.dataset.name = insect.name;
// 根據昆蟲類型創建SVG
let svgContent = '';
switch(insect.name) {
case '蝴蝶':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 100 75">
<path d="M50,20 C60,0 80,5 90,20 C95,35 80,50 50,45 C20,50 5,35 10,20 C20,5 40,0 50,20" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<path d="M50,20 L50,45" stroke="#000" stroke-width="2" />
<circle cx="50" cy="15" r="5" fill="#000" />
<path d="M45,10 L40,5" stroke="#000" stroke-width="1" />
<path d="M55,10 L60,5" stroke="#000" stroke-width="1" />
</svg>
`;
break;
case '蜜蜂':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 80 60">
<ellipse cx="40" cy="30" rx="20" ry="15" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<path d="M40,15 C50,5 60,10 55,20" fill="rgba(255,255,255,0.7)" stroke="#000" stroke-width="1" />
<path d="M40,15 C30,5 20,10 25,20" fill="rgba(255,255,255,0.7)" stroke="#000" stroke-width="1" />
<path d="M20,30 L60,30" stroke="#000" stroke-width="1.5" />
<path d="M25,25 L55,25" stroke="#000" stroke-width="1.5" />
<path d="M25,35 L55,35" stroke="#000" stroke-width="1.5" />
<circle cx="60" cy="30" r="5" fill="#000" />
<path d="M65,25 L70,20" stroke="#000" stroke-width="1" />
<path d="M65,35 L70,40" stroke="#000" stroke-width="1" />
</svg>
`;
break;
case '蜻蜓':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 120 60">
<path d="M30,30 L90,30" stroke="#000" stroke-width="2" />
<ellipse cx="90" cy="30" rx="10" ry="5" fill="#000" />
<path d="M40,30 L20,15" stroke="#000" stroke-width="1" />
<path d="M40,30 L20,45" stroke="#000" stroke-width="1" />
<path d="M60,30 L40,10" stroke="#000" stroke-width="1" />
<path d="M60,30 L40,50" stroke="#000" stroke-width="1" />
<path d="M20,15 L40,10" fill="none" stroke="#000" stroke-width="0.5" />
<path d="M20,45 L40,50" fill="none" stroke="#000" stroke-width="0.5" />
<path d="M20,15 L40,10" fill="${insect.color}" fill-opacity="0.7" />
<path d="M20,45 L40,50" fill="${insect.color}" fill-opacity="0.7" />
<path d="M40,10 L60,30" fill="${insect.color}" fill-opacity="0.7" />
<path d="M40,50 L60,30" fill="${insect.color}" fill-opacity="0.7" />
</svg>
`;
break;
case '瓢蟲':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 60 40">
<ellipse cx="30" cy="20" rx="20" ry="15" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<path d="M30,5 L30,35" stroke="#000" stroke-width="1" />
<circle cx="20" cy="15" r="3" fill="#000" />
<circle cx="40" cy="15" r="3" fill="#000" />
<circle cx="25" cy="25" r="3" fill="#000" />
<circle cx="35" cy="25" r="3" fill="#000" />
<circle cx="30" cy="15" r="3" fill="#000" />
<path d="M10,20 C5,15 5,10 10,5 C15,0 25,0 30,5" fill="#000" />
<path d="M50,20 C55,15 55,10 50,5 C45,0 35,0 30,5" fill="#000" />
</svg>
`;
break;
case '螳螂':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 80 60">
<path d="M40,10 L40,50" stroke="#000" stroke-width="2" />
<ellipse cx="40" cy="15" rx="5" ry="7" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<path d="M35,12 L30,8" stroke="#000" stroke-width="1" />
<path d="M45,12 L50,8" stroke="#000" stroke-width="1" />
<path d="M40,22 L30,40" stroke="#000" stroke-width="2" />
<path d="M40,22 L50,40" stroke="#000" stroke-width="2" />
<path d="M30,40 L20,35" stroke="#000" stroke-width="2" />
<path d="M50,40 L60,35" stroke="#000" stroke-width="2" />
<path d="M40,30 L20,20" stroke="#000" stroke-width="2" />
<path d="M20,20 L10,30" stroke="#000" stroke-width="2" />
<path d="M40,30 L60,20" stroke="#000" stroke-width="2" />
<path d="M60,20 L70,30" stroke="#000" stroke-width="2" />
</svg>
`;
break;
case '蟋蟀':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 80 50">
<ellipse cx="40" cy="25" rx="15" ry="10" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<path d="M25,25 L15,15" stroke="#000" stroke-width="1.5" />
<path d="M25,25 L15,35" stroke="#000" stroke-width="1.5" />
<path d="M55,25 L65,15" stroke="#000" stroke-width="1.5" />
<path d="M55,25 L65,35" stroke="#000" stroke-width="1.5" />
<path d="M40,35 L35,45" stroke="#000" stroke-width="1.5" />
<path d="M40,35 L45,45" stroke="#000" stroke-width="1.5" />
<path d="M55,25 L70,20" stroke="#000" stroke-width="1" />
<path d="M55,25 L70,30" stroke="#000" stroke-width="1" />
<circle cx="50" cy="20" r="2" fill="#000" />
<circle cx="30" cy="20" r="2" fill="#000" />
</svg>
`;
break;
case '蝗蟲':
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 90 50">
<ellipse cx="45" cy="25" rx="20" ry="10" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<path d="M25,25 L15,15" stroke="#000" stroke-width="1.5" />
<path d="M25,25 L15,35" stroke="#000" stroke-width="1.5" />
<path d="M65,25 L75,15" stroke="#000" stroke-width="1.5" />
<path d="M65,25 L75,35" stroke="#000" stroke-width="1.5" />
<path d="M45,35 L35,50" stroke="#000" stroke-width="2" />
<path d="M45,35 L55,50" stroke="#000" stroke-width="2" />
<path d="M45,15 L35,5" stroke="#000" stroke-width="1" />
<path d="M45,15 L55,5" stroke="#000" stroke-width="1" />
<path d="M35,5 L55,5" fill="none" stroke="#000" stroke-width="0.5" />
<path d="M35,5 L55,5" fill="${insect.color}" fill-opacity="0.7" />
<circle cx="60" cy="20" r="2" fill="#000" />
<circle cx="30" cy="20" r="2" fill="#000" />
</svg>
`;
break;
default:
svgContent = `
<svg width="${insect.wingSpan * 2}" height="${insect.wingSpan * 1.5}" viewBox="0 0 60 40">
<circle cx="30" cy="20" r="15" fill="${insect.color}" stroke="#000" stroke-width="1.5" />
<circle cx="25" cy="15" r="3" fill="#000" />
<circle cx="35" cy="15" r="3" fill="#000" />
<path d="M25,25 Q30,30 35,25" stroke="#000" stroke-width="1.5" fill="none" />
</svg>
`;
}
insectElement.innerHTML = svgContent;
// 隨機位置
const gardenWidth = garden.clientWidth - insect.wingSpan * 2;
const gardenHeight = garden.clientHeight - insect.wingSpan * 2 - 60; // 減去圍欄高度
insectElement.style.left = Math.random() * gardenWidth + 'px';
insectElement.style.top = Math.random() * gardenHeight + 'px';
// 添加點擊事件
insectElement.addEventListener('click', () => handleInsectClick(insectElement));
return insectElement;
}
// 添加花朵
function addFlowers() {
const flowerColors = ['#FF6B6B', '#FFCC5C', '#88D8B0', '#FF85A2', '#FFFFFF', '#B5EAD7'];
for (let i = 0; i < 12; i++) {
const flower = document.createElement('div');
flower.className = 'flower';
const size = Math.floor(Math.random() * 20) + 15;
const color = flowerColors[Math.floor(Math.random() * flowerColors.length)];
flower.innerHTML = `
<svg width="${size}" height="${size}" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="10" fill="${color}" />
<circle cx="20" cy="20" r="5" fill="#FFEB3B" />
${Math.random() > 0.5 ? `
<path d="M20,0 Q25,10 20,20 Q15,10 20,0" fill="${color}" />
<path d="M40,20 Q30,25 20,20 Q30,15 40,20" fill="${color}" />
<path d="M20,40 Q25,30 20,20 Q15,30 20,40" fill="${color}" />
<path d="M0,20 Q10,25 20,20 Q10,15 0,20" fill="${color}" />
` : `
<circle cx="10" cy="10" r="8" fill="${color}" />
<circle cx="30" cy="10" r="8" fill="${color}" />
<circle cx="10" cy="30" r="8" fill="${color}" />
<circle cx="30" cy="30" r="8" fill="${color}" />
`}
</svg>
`;
const gardenWidth = garden.clientWidth - size;
const gardenHeight = garden.clientHeight - size - 60; // 減去圍欄高度
flower.style.left = Math.random() * gardenWidth + 'px';
flower.style.top = Math.random() * gardenHeight + 'px';
garden.appendChild(flower);
}
}
// 選擇目標昆蟲
function selectTargetInsect() {
const availableInsects = insectElements.filter(insect => !insect.caught);
if (availableInsects.length === 0) {
gameOver();
return;
}
const randomIndex = Math.floor(Math.random() * availableInsects.length);
targetInsect = availableInsects[randomIndex];
targetInsectElement.textContent = targetInsect.data.name;
}
// 處理昆蟲點擊
function handleInsectClick(insectElement) {
if (!gameActive) return;
const insectName = insectElement.dataset.name;
if (insectName === targetInsect.data.name && !targetInsect.caught) {
// 正確點擊
targetInsect.caught = true;
caughtInsects++;
// 更新計數
caughtCountElement.textContent = caughtInsects;
// 飛走動畫
insectElement.classList.add('flying-animation');
// 選擇新的目標
setTimeout(() => {
selectTargetInsect();
}, 500);
}
}
// 昆蟲移動動畫
function animateInsects() {
if (!gameActive) return;
insectElements.forEach(insect => {
if (insect.caught) return;
const element = insect.element;
const speed = insect.data.speed;
// 獲取當前位置
let x = parseFloat(element.style.left);
let y = parseFloat(element.style.top);
// 隨機移動方向
const dx = (Math.random() - 0.5) * speed;
const dy = (Math.random() - 0.5) * speed;
// 新位置
x += dx;
y += dy;
// 邊界檢查
const maxX = garden.clientWidth - element.offsetWidth;
const maxY = garden.clientHeight - element.offsetHeight - 60; // 減去圍欄高度
x = Math.max(0, Math.min(x, maxX));
y = Math.max(0, Math.min(y, maxY));
// 更新位置
element.style.left = x + 'px';
element.style.top = y + 'px';
});
requestAnimationFrame(animateInsects);
}
// 遊戲結束
function gameOver() {
gameActive = false;
winScreen.classList.remove('hidden');
}
// 重新開始遊戲
restartBtn.addEventListener('click', () => {
winScreen.classList.add('hidden');
initGame();
});
// 開發人員功能 - 顯示程式碼
devButton.addEventListener('click', () => {
// 獲取當前頁面的HTML代碼
const htmlCode = document.documentElement.outerHTML;
// 格式化HTML代碼(簡單的縮進)
const formattedCode = formatHTML(htmlCode);
// 顯示在模態框中
codeContent.textContent = formattedCode;
codeModal.classList.add('active');
});
// 關閉模態框
closeModalBtn.addEventListener('click', () => {
codeModal.classList.remove('active');
});
// 點擊模態框外部關閉
codeModal.addEventListener('click', (e) => {
if (e.target === codeModal) {
codeModal.classList.remove('active');
}
});
// 複製程式碼
copyBtn.addEventListener('click', () => {
const codeText = codeContent.textContent;
// 使用Clipboard API複製文本
navigator.clipboard.writeText(codeText).then(() => {
// 顯示複製成功提示
copySuccess.classList.add('active');
// 3秒後隱藏提示
setTimeout(() => {
copySuccess.classList.remove('active');
}, 3000);
}).catch(err => {
console.error('複製失敗:', err);
alert('複製失敗,請手動選擇並複製代碼。');
});
});
// 格式化HTML代碼的簡單函數
function formatHTML(html) {
// 這只是一個簡單的格式化,不是完美的HTML格式化
let formatted = '';
let indent = '';
// 將標籤分行並添加縮進
html.split(/>\s*</).forEach(function(node) {
if (node.match(/^\/\w/)) {
// 結束標籤,減少縮進
indent = indent.substring(2);
}
formatted += indent + '<' + node + '>\n';
if (node.match(/^<?\w[^>]*[^\/]$/) && !node.startsWith('input') && !node.startsWith('link') && !node.startsWith('meta')) {
// 開始標籤,增加縮進
indent += ' ';
}
});
return formatted.substring(1, formatted.length - 2);
}
// 初始化遊戲
initGame();
});
</script>
<script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'9474b63794fa4a0c',t:'MTc0ODUwODI4Ni4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
<iframe height="1" width="1" style="position: absolute; top: 0px; left: 0px; border: medium; visibility: hidden;">
</iframe>
</body>
</html>