diff --git "a/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/index.html" "b/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/index.html"
new file mode 100644
index 0000000..4a20b23
--- /dev/null
+++ "b/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/index.html"
@@ -0,0 +1,33 @@
+
+
+
+
+
+ 人体大冒险
+
+
+
+
+
人体大冒险
+
+
+
+
分数: 0
+
健康值: 100
+
+
+
+
+
+
+
diff --git "a/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/script.js" "b/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/script.js"
new file mode 100644
index 0000000..8ee998c
--- /dev/null
+++ "b/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/script.js"
@@ -0,0 +1,837 @@
+class Game {
+ constructor() {
+ this.score = 0;
+ this.health = 100;
+ this.isPlaying = false;
+ this.foodParticle = document.getElementById('food');
+ this.scoreElement = document.getElementById('score');
+ this.healthElement = document.getElementById('health');
+ this.currentPathIndex = 0;
+
+ // 定义食物类型
+ this.foodTypes = {
+ vegetable: { color: '#4CAF50', points: 10, health: 5, speed: 1 },
+ fruit: { color: '#FF9800', points: 15, health: 8, speed: 1.2 },
+ meat: { color: '#F44336', points: 20, health: 10, speed: 0.8 },
+ junkFood: { color: '#9C27B0', points: 5, health: -5, speed: 1.5 }
+ };
+
+ // 定义病毒类型
+ this.virusTypes = {
+ common: { color: '#ff0000', damage: 5, speed: 1, points: 5 },
+ fast: { color: '#ff00ff', damage: 3, speed: 2, points: 10 },
+ strong: { color: '#800000', damage: 10, speed: 0.5, points: 15 }
+ };
+
+ // 消化路径
+ this.digestivePath = [
+ { organ: 'mouth', y: 80, action: this.digestInMouth.bind(this) },
+ { organ: 'stomach', y: 200, action: this.digestInStomach.bind(this) },
+ { organ: 'liver', y: 250, action: this.processInLiver.bind(this) },
+ { organ: 'small-intestine', y: 350, action: this.absorbNutrients.bind(this) },
+ { organ: 'large-intestine', y: 450, action: this.finalProcess.bind(this) },
+ { organ: 'exit', y: 550 }
+ ];
+
+ // 添加器官描述
+ this.organDescriptions = {
+ '心脏': '心脏是人体的血液泵,负责将血液输送到全身',
+ '肺部': '肺部负责呼吸,为血液提供氧气并排出二氧化碳',
+ '肝脏': '肝脏负责解毒和产生胆汁,帮助消化脂肪',
+ '胃': '胃负责消化食物,分泌胃酸帮助分解食物',
+ '小肠': '小肠是主要的营养吸收场所,将食物转化为身体可用的营养',
+ '大肠': '大肠负责吸收水分,处理食物残渣'
+ };
+
+ // 初始化音频上下文
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
+
+ // 创建不同类型的音效
+ this.sounds = {
+ click: this.createClickSound(),
+ digest: this.createDigestSound(),
+ virus: this.createVirusSound(),
+ gameOver: this.createGameOverSound()
+ };
+
+ this.setupOrganHighlighting();
+
+ // 创建战斗机元素
+ this.createFighter();
+
+ // 添加鼠标移动监听
+ document.addEventListener('mousemove', this.moveFighter.bind(this));
+
+ // 添加器官音符频率
+ this.organNotes = {
+ '心脏': 523.25, // C5
+ '肺部': 587.33, // D5
+ '肝脏': 659.25, // E5
+ '胃': 698.46, // F5
+ '小肠': 783.99, // G5
+ '大肠': 880.00 // A5
+ };
+ }
+
+ setupGameControls() {
+ const foodButtons = document.createElement('div');
+ foodButtons.className = 'food-buttons';
+ Object.keys(this.foodTypes).forEach(type => {
+ const btn = document.createElement('button');
+ btn.textContent = this.getFoodName(type);
+ btn.style.backgroundColor = this.foodTypes[type].color;
+ btn.onclick = () => {
+ if (this.isPlaying) {
+ this.startDigestion(type);
+ }
+ };
+ foodButtons.appendChild(btn);
+ });
+ document.querySelector('.game-controls').appendChild(foodButtons);
+ }
+
+ getFoodName(type) {
+ const names = {
+ vegetable: '蔬菜',
+ fruit: '水果',
+ meat: '肉类',
+ junkFood: '垃圾食品'
+ };
+ return names[type];
+ }
+
+ start() {
+ this.isPlaying = true;
+ this.score = 0;
+ this.health = 100;
+ this.updateUI();
+ // 清除之前的食物按钮
+ const oldFoodButtons = document.querySelector('.food-buttons');
+ if (oldFoodButtons) {
+ oldFoodButtons.remove();
+ }
+ // 初始化食物按钮
+ this.setupGameControls();
+ this.spawnVirus();
+ }
+
+ updateUI() {
+ this.scoreElement.textContent = this.score;
+ this.healthElement.textContent = this.health;
+
+ // 根据健康值改变显示效果
+ if (this.health < 30) {
+ this.healthElement.style.color = '#ff0000';
+ } else if (this.health < 60) {
+ this.healthElement.style.color = '#ffa500';
+ } else {
+ this.healthElement.style.color = '#4CAF50';
+ }
+ }
+
+ startDigestion(foodType) {
+ if (!this.isPlaying || this.foodParticle.style.display === 'block') {
+ return; // 如果已经有食物在消化,则不允许新的食物进入
+ }
+
+ this.currentFood = this.foodTypes[foodType];
+ this.currentPathIndex = 0;
+ this.foodParticle.style.display = 'block';
+ this.foodParticle.style.backgroundColor = this.currentFood.color;
+ this.foodParticle.style.top = '80px';
+ this.foodParticle.style.left = '150px';
+ this.moveFood();
+ }
+
+ moveFood() {
+ if (!this.isPlaying) return;
+
+ const currentPosition = this.digestivePath[this.currentPathIndex];
+ this.foodParticle.style.top = currentPosition.y + 'px';
+
+ // 执行当前器官的消化动作
+ if (currentPosition.action) {
+ currentPosition.action(this.currentFood);
+ }
+
+ this.currentPathIndex++;
+ if (this.currentPathIndex >= this.digestivePath.length) {
+ this.finishDigestion();
+ } else {
+ setTimeout(() => this.moveFood(), 1000 / this.currentFood.speed);
+ }
+ }
+
+ // 各个器官的消化过程
+ digestInMouth(food) {
+ // 咀嚼动画效果
+ this.foodParticle.style.animation = 'chew 0.5s ease-in-out';
+ }
+
+ digestInStomach(food) {
+ this.sounds.digest();
+ const stomach = document.querySelector('.stomach');
+ stomach.classList.add('digesting');
+ setTimeout(() => stomach.classList.remove('digesting'), 1000);
+ }
+
+ processInLiver(food) {
+ // 如果是垃圾食品,会损失健康值
+ if (food === this.foodTypes.junkFood) {
+ this.health = Math.max(0, this.health - 5);
+ this.updateUI();
+ }
+ }
+
+ absorbNutrients(food) {
+ // 增加分数和健康值
+ this.score += food.points;
+ this.health = Math.min(100, this.health + food.health);
+ this.updateUI();
+ }
+
+ finalProcess(food) {
+ // 最终处理
+ if (this.health < 30) {
+ this.gameOver();
+ }
+ }
+
+ spawnVirus() {
+ if (!this.isPlaying) return;
+
+ const virusType = this.getRandomVirusType();
+ const virus = this.createVirus(virusType);
+ document.querySelector('.virus-container').appendChild(virus);
+
+ // 病毒移动
+ this.moveVirus(virus, virusType);
+
+ setTimeout(() => this.spawnVirus(), 2000);
+ }
+
+ getRandomVirusType() {
+ const types = Object.keys(this.virusTypes);
+ return this.virusTypes[types[Math.floor(Math.random() * types.length)]];
+ }
+
+ createVirus(virusType) {
+ const virus = document.createElement('div');
+ virus.className = 'virus';
+ virus.style.backgroundColor = virusType.color;
+
+ // 设置病毒初始位置
+ const organs = [
+ {top: 80, left: 150}, // 头部
+ {top: 200, left: 150}, // 胃
+ {top: 250, left: 150}, // 肝脏
+ {top: 350, left: 150}, // 小肠
+ {top: 450, left: 150} // 大肠
+ ];
+
+ const position = organs[Math.floor(Math.random() * organs.length)];
+ virus.style.left = (position.left + (Math.random() * 60 - 30)) + 'px';
+ virus.style.top = (position.top + (Math.random() * 60 - 30)) + 'px';
+
+ virus.onclick = () => this.destroyVirus(virus, virusType);
+
+ return virus;
+ }
+
+ moveVirus(virus, virusType) {
+ const speed = virusType.speed;
+ const angle = Math.random() * Math.PI * 2;
+ const vx = Math.cos(angle) * speed;
+ const vy = Math.sin(angle) * speed;
+
+ const interval = setInterval(() => {
+ if (!this.isPlaying) {
+ clearInterval(interval);
+ return;
+ }
+
+ const left = parseFloat(virus.style.left);
+ const top = parseFloat(virus.style.top);
+
+ virus.style.left = (left + vx) + 'px';
+ virus.style.top = (top + vy) + 'px';
+
+ // 检查是否击中器官
+ this.checkVirusCollision(virus, virusType);
+ }, 50);
+ }
+
+ checkVirusCollision(virus, virusType) {
+ // 如果病毒接触到器官,扣除健康值
+ const organs = document.querySelectorAll('.organ');
+ organs.forEach(organ => {
+ if (this.isColliding(virus, organ)) {
+ this.health = Math.max(0, this.health - virusType.damage);
+ this.updateUI();
+ this.destroyVirus(virus, virusType);
+
+ if (this.health <= 0) {
+ this.gameOver();
+ }
+ }
+ });
+ }
+
+ isColliding(virus, organ) {
+ const virusRect = virus.getBoundingClientRect();
+ const organRect = organ.getBoundingClientRect();
+
+ return !(virusRect.right < organRect.left ||
+ virusRect.left > organRect.right ||
+ virusRect.bottom < organRect.top ||
+ virusRect.top > organRect.bottom);
+ }
+
+ destroyVirus(virus, virusType) {
+ this.sounds.virus();
+ this.score += virusType.points;
+ this.updateUI();
+ this.createVirusDestroyEffect(virus);
+ virus.remove();
+ }
+
+ gameOver() {
+ this.sounds.gameOver();
+ this.isPlaying = false;
+ alert(`游戏结束!\n最终得分:${this.score}`);
+ document.getElementById('start-game').textContent = '重新开始';
+ }
+
+ setupOrganHighlighting() {
+ const organs = document.querySelectorAll('[data-organ]');
+ organs.forEach(organ => {
+ // 为每个器官设置基础颜色
+ const baseColor = this.getOrganBaseColor(organ.getAttribute('data-organ'));
+ organ.style.backgroundColor = baseColor;
+
+ organ.addEventListener('click', () => {
+ const organName = organ.getAttribute('data-organ');
+ // 播放对应器官的音符
+ const woodfishSound = this.createWoodfishSound(organName);
+ woodfishSound();
+
+ // 添加木鱼敲击效果和颜色变化
+ organ.classList.add('organ-hit');
+ organ.style.backgroundColor = this.getOrganActiveColor(organ.getAttribute('data-organ'));
+
+ // 添加发光效果
+ organ.style.boxShadow = '0 0 20px ' + this.getOrganGlowColor(organ.getAttribute('data-organ'));
+
+ // 恢复原始状态
+ setTimeout(() => {
+ organ.classList.remove('organ-hit');
+ organ.style.backgroundColor = baseColor;
+ organ.style.boxShadow = 'none';
+ }, 200);
+
+ // 显示器官信息
+ const description = this.organDescriptions[organName];
+
+ // 创建或更新提示框
+ let tooltip = document.getElementById('organ-tooltip');
+ if (!tooltip) {
+ tooltip = document.createElement('div');
+ tooltip.id = 'organ-tooltip';
+ document.body.appendChild(tooltip);
+ }
+
+ tooltip.textContent = `${organName}: ${description}`;
+ tooltip.style.display = 'block';
+
+ // 定位提示框
+ const rect = organ.getBoundingClientRect();
+ tooltip.style.left = `${rect.left}px`;
+ tooltip.style.top = `${rect.top - tooltip.offsetHeight - 10}px`;
+
+ // 3秒后隐藏提示框
+ setTimeout(() => {
+ tooltip.style.display = 'none';
+ }, 3000);
+ });
+ });
+ }
+
+ // 添加器官基础颜色
+ getOrganBaseColor(organName) {
+ const colors = {
+ '心脏': '#ff6b6b',
+ '肺部': '#ffa07a',
+ '肝脏': '#8b4513',
+ '胃': '#ff9f7f',
+ '小肠': '#ffd700',
+ '大肠': '#deb887'
+ };
+ return colors[organName] || '#ff9f7f';
+ }
+
+ // 添加器官激活时的颜色
+ getOrganActiveColor(organName) {
+ const colors = {
+ '心脏': '#ff4444',
+ '肺部': '#ff8855',
+ '肝脏': '#a52a2a',
+ '胃': '#ff7744',
+ '小肠': '#ffc125',
+ '大肠': '#cd853f'
+ };
+ return colors[organName] || '#ff7744';
+ }
+
+ // 添加器官发光颜色
+ getOrganGlowColor(organName) {
+ const colors = {
+ '心脏': 'rgba(255, 105, 105, 0.6)',
+ '肺部': 'rgba(255, 160, 122, 0.6)',
+ '肝脏': 'rgba(139, 69, 19, 0.6)',
+ '胃': 'rgba(255, 159, 127, 0.6)',
+ '小肠': 'rgba(255, 215, 0, 0.6)',
+ '大肠': 'rgba(222, 184, 135, 0.6)'
+ };
+ return colors[organName] || 'rgba(255, 159, 127, 0.6)';
+ }
+
+ finishDigestion() {
+ // 完成一次消化过程
+ this.score += this.currentFood.points;
+ this.updateUI();
+ this.foodParticle.style.display = 'none';
+ }
+
+ createVirusDestroyEffect(virus) {
+ const effect = document.createElement('div');
+ effect.style.position = 'absolute';
+ effect.style.left = virus.style.left;
+ effect.style.top = virus.style.top;
+ effect.style.width = '30px';
+ effect.style.height = '30px';
+ effect.style.background = 'radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,0,0,0) 70%)';
+ effect.style.animation = 'explode 0.5s ease-out forwards';
+ document.querySelector('.virus-container').appendChild(effect);
+
+ setTimeout(() => effect.remove(), 500);
+ }
+
+ // 创建点击音效
+ createClickSound() {
+ return () => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ oscillator.type = 'sine';
+ oscillator.frequency.setValueAtTime(800, this.audioContext.currentTime);
+ gainNode.gain.setValueAtTime(0.3, this.audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.1);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.1);
+ };
+ }
+
+ // 创建消化音效
+ createDigestSound() {
+ return () => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ oscillator.type = 'triangle';
+ oscillator.frequency.setValueAtTime(200, this.audioContext.currentTime);
+ oscillator.frequency.linearRampToValueAtTime(100, this.audioContext.currentTime + 0.2);
+
+ gainNode.gain.setValueAtTime(0.2, this.audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.2);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.2);
+ };
+ }
+
+ // 创建病毒消灭音效
+ createVirusSound() {
+ return () => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ oscillator.type = 'square';
+ oscillator.frequency.setValueAtTime(600, this.audioContext.currentTime);
+ oscillator.frequency.exponentialRampToValueAtTime(200, this.audioContext.currentTime + 0.1);
+
+ gainNode.gain.setValueAtTime(0.2, this.audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.1);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.1);
+ };
+ }
+
+ // 创建游戏结束音效
+ createGameOverSound() {
+ return () => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ oscillator.type = 'sawtooth';
+ oscillator.frequency.setValueAtTime(400, this.audioContext.currentTime);
+ oscillator.frequency.exponentialRampToValueAtTime(100, this.audioContext.currentTime + 0.5);
+
+ gainNode.gain.setValueAtTime(0.3, this.audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.5);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.5);
+ };
+ }
+
+ createFighter() {
+ const fighter = document.createElement('div');
+ fighter.className = 'fighter';
+ fighter.innerHTML = `
+
+ `;
+ document.body.appendChild(fighter);
+ this.fighter = fighter;
+
+ // 隐藏默认光标
+ document.body.style.cursor = 'none';
+ }
+
+ moveFighter(e) {
+ if (this.fighter) {
+ this.fighter.style.left = (e.clientX - 20) + 'px';
+ this.fighter.style.top = (e.clientY - 20) + 'px';
+
+ // 当点击时添加敲击动画
+ document.addEventListener('mousedown', () => {
+ this.fighter.classList.add('hitting');
+ });
+
+ document.addEventListener('mouseup', () => {
+ this.fighter.classList.remove('hitting');
+ });
+ }
+ }
+
+ // 添加木鱼音效
+ createWoodfishSound(organName) {
+ return () => {
+ const frequency = this.organNotes[organName] || 523.25; // 默认 C5
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ // 木鱼的音色
+ oscillator.type = 'triangle';
+ oscillator.frequency.setValueAtTime(frequency, this.audioContext.currentTime);
+
+ // 音量包络
+ gainNode.gain.setValueAtTime(0, this.audioContext.currentTime);
+ gainNode.gain.linearRampToValueAtTime(0.5, this.audioContext.currentTime + 0.01);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.3);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.3);
+
+ // 添加泛音
+ this.addHarmonics(frequency);
+ };
+ }
+
+ // 添加泛音来模拟木鱼的谐波
+ addHarmonics(fundamental) {
+ const harmonics = [2, 3, 4]; // 泛音序列
+ harmonics.forEach((harmonic, index) => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ oscillator.type = 'triangle';
+ oscillator.frequency.setValueAtTime(fundamental * harmonic, this.audioContext.currentTime);
+
+ // 泛音音量递减
+ const volume = 0.2 / (index + 2);
+ gainNode.gain.setValueAtTime(0, this.audioContext.currentTime);
+ gainNode.gain.linearRampToValueAtTime(volume, this.audioContext.currentTime + 0.01);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.2);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.2);
+ });
+ }
+}
+
+class HumanBodyDrawer {
+ constructor() {
+ this.bodyCanvas = document.getElementById('bodyCanvas');
+ this.skeletonCanvas = document.getElementById('skeletonCanvas');
+ this.organsCanvas = document.getElementById('organsCanvas');
+
+ this.canvases = [this.bodyCanvas, this.skeletonCanvas, this.organsCanvas];
+ this.canvases.forEach(canvas => {
+ canvas.width = 300;
+ canvas.height = 600;
+ });
+
+ this.bodyCtx = this.bodyCanvas.getContext('2d');
+ this.skeletonCtx = this.skeletonCanvas.getContext('2d');
+ this.organsCtx = this.organsCanvas.getContext('2d');
+
+ this.drawAll();
+ }
+
+ drawBody() {
+ const ctx = this.bodyCtx;
+ ctx.fillStyle = '#ffdbac';
+
+ // 头部
+ ctx.beginPath();
+ ctx.arc(150, 50, 30, 0, Math.PI * 2);
+ ctx.fill();
+
+ // 颈部
+ ctx.beginPath();
+ ctx.moveTo(140, 75);
+ ctx.lineTo(160, 75);
+ ctx.lineTo(157, 95);
+ ctx.lineTo(143, 95);
+ ctx.closePath();
+ ctx.fill();
+
+ // 躯干
+ ctx.beginPath();
+ ctx.moveTo(130, 95); // 肩部起点
+ ctx.lineTo(170, 95); // 肩部宽度
+ ctx.lineTo(175, 280); // 腰部
+ ctx.lineTo(165, 400); // 臀部
+ ctx.lineTo(135, 400);
+ ctx.lineTo(125, 280);
+ ctx.closePath();
+ ctx.fill();
+
+ // 左手臂
+ ctx.beginPath();
+ ctx.moveTo(130, 95); // 肩部连接点
+ ctx.lineTo(110, 200); // 上臂
+ ctx.lineTo(105, 300); // 前臂
+ ctx.lineTo(115, 300);
+ ctx.lineTo(120, 200);
+ ctx.closePath();
+ ctx.fill();
+
+ // 右手臂
+ ctx.beginPath();
+ ctx.moveTo(170, 95); // 肩部连接点
+ ctx.lineTo(190, 200); // 上臂
+ ctx.lineTo(195, 300); // 前臂
+ ctx.lineTo(185, 300);
+ ctx.lineTo(180, 200);
+ ctx.closePath();
+ ctx.fill();
+
+ // 左腿
+ ctx.beginPath();
+ ctx.moveTo(135, 400);
+ ctx.lineTo(125, 500);
+ ctx.lineTo(130, 580);
+ ctx.lineTo(145, 580);
+ ctx.lineTo(150, 500);
+ ctx.closePath();
+ ctx.fill();
+
+ // 右腿
+ ctx.beginPath();
+ ctx.moveTo(165, 400);
+ ctx.lineTo(175, 500);
+ ctx.lineTo(170, 580);
+ ctx.lineTo(155, 580);
+ ctx.lineTo(150, 500);
+ ctx.closePath();
+ ctx.fill();
+ }
+
+ drawSkeleton() {
+ const ctx = this.skeletonCtx;
+ ctx.strokeStyle = '#e0e0e0';
+ ctx.lineWidth = 2;
+
+ // 头骨
+ ctx.beginPath();
+ ctx.arc(150, 50, 25, 0, Math.PI * 2);
+ ctx.stroke();
+
+ // 颈椎
+ ctx.beginPath();
+ ctx.moveTo(150, 75);
+ ctx.lineTo(150, 95);
+ ctx.stroke();
+
+ // 脊椎
+ ctx.beginPath();
+ ctx.moveTo(150, 95);
+ for(let y = 95; y < 400; y += 15) {
+ ctx.lineTo(150, y + 7);
+ ctx.moveTo(150, y + 15);
+ }
+ ctx.stroke();
+
+ // 肋骨(更自然的弧度)
+ for(let y = 120; y < 250; y += 25) {
+ ctx.beginPath();
+ // 左侧肋骨
+ ctx.moveTo(150, y);
+ ctx.bezierCurveTo(130, y-5, 120, y, 115, y+5);
+ // 右侧肋骨
+ ctx.moveTo(150, y);
+ ctx.bezierCurveTo(170, y-5, 180, y, 185, y+5);
+ ctx.stroke();
+ }
+
+ // 锁骨
+ ctx.beginPath();
+ ctx.moveTo(130, 95);
+ ctx.quadraticCurveTo(150, 85, 170, 95);
+ ctx.stroke();
+
+ // 骨盆
+ ctx.beginPath();
+ ctx.moveTo(125, 380);
+ ctx.bezierCurveTo(150, 400, 150, 390, 175, 380);
+ ctx.stroke();
+
+ // 手臂骨骼
+ this.drawLimb(ctx, 130, 95, 110, 200, 105, 300); // 左臂
+ this.drawLimb(ctx, 170, 95, 190, 200, 195, 300); // 右臂
+
+ // 腿部骨骼
+ this.drawLimb(ctx, 135, 400, 125, 500, 130, 580); // 左腿
+ this.drawLimb(ctx, 165, 400, 175, 500, 170, 580); // 右腿
+ }
+
+ drawLimb(ctx, x1, y1, x2, y2, x3, y3) {
+ ctx.beginPath();
+ ctx.moveTo(x1, y1);
+ ctx.lineTo(x2, y2);
+ ctx.lineTo(x3, y3);
+ ctx.stroke();
+ }
+
+ drawOrgans() {
+ const ctx = this.organsCtx;
+
+ // 心脏(更自然的形状)
+ ctx.fillStyle = '#ff6b6b';
+ ctx.beginPath();
+ ctx.moveTo(150, 160);
+ ctx.bezierCurveTo(170, 140, 170, 180, 150, 200);
+ ctx.bezierCurveTo(130, 180, 130, 140, 150, 160);
+ ctx.fill();
+
+ // 肺部(更自然的形状)
+ ctx.fillStyle = '#ffa07a';
+ // 左肺
+ ctx.beginPath();
+ ctx.moveTo(120, 150);
+ ctx.bezierCurveTo(100, 170, 100, 220, 120, 240);
+ ctx.bezierCurveTo(130, 220, 130, 170, 120, 150);
+ ctx.fill();
+ // 右肺
+ ctx.beginPath();
+ ctx.moveTo(180, 150);
+ ctx.bezierCurveTo(200, 170, 200, 220, 180, 240);
+ ctx.bezierCurveTo(170, 220, 170, 170, 180, 150);
+ ctx.fill();
+
+ // 肝脏
+ ctx.fillStyle = '#8b4513';
+ ctx.beginPath();
+ ctx.moveTo(130, 250);
+ ctx.bezierCurveTo(170, 240, 190, 260, 170, 280);
+ ctx.bezierCurveTo(150, 290, 130, 280, 130, 250);
+ ctx.fill();
+
+ // 胃
+ ctx.fillStyle = '#ff9f7f';
+ ctx.beginPath();
+ ctx.moveTo(140, 290);
+ ctx.bezierCurveTo(160, 280, 170, 310, 160, 330);
+ ctx.bezierCurveTo(140, 340, 130, 310, 140, 290);
+ ctx.fill();
+
+ // 小肠(更自然的蜿蜒形状)
+ ctx.fillStyle = '#ffd700';
+ this.drawIntestine(ctx, 150, 350, 35, 8, 0.15);
+
+ // 大肠
+ ctx.fillStyle = '#deb887';
+ this.drawIntestine(ctx, 150, 420, 45, 3, 0.25);
+ }
+
+ drawIntestine(ctx, x, y, radius, loops, wavelength) {
+ ctx.beginPath();
+ for(let i = 0; i < Math.PI * 2 * loops; i += 0.1) {
+ const dx = Math.cos(i) * radius + Math.sin(i * 8) * wavelength;
+ const dy = Math.sin(i) * radius + Math.cos(i * 8) * wavelength;
+ if(i === 0) {
+ ctx.moveTo(x + dx, y + dy);
+ } else {
+ ctx.lineTo(x + dx, y + dy);
+ }
+ }
+ ctx.fill();
+ }
+
+ drawAll() {
+ this.drawBody();
+ this.drawSkeleton();
+ this.drawOrgans();
+ }
+}
+
+// 初始化游戏和人体绘制
+document.addEventListener('DOMContentLoaded', () => {
+ const humanBodyDrawer = new HumanBodyDrawer();
+ const game = new Game();
+
+ document.getElementById('start-game').addEventListener('click', () => {
+ game.start();
+ });
+});
+
+const style = document.createElement('style');
+style.textContent = `
+ @keyframes explode {
+ 0% { transform: scale(0.3); opacity: 1; }
+ 100% { transform: scale(2); opacity: 0; }
+ }
+`;
+document.head.appendChild(style);
\ No newline at end of file
diff --git "a/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/styles.css" "b/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/styles.css"
new file mode 100644
index 0000000..708e0ff
--- /dev/null
+++ "b/\344\272\272\344\275\223\345\244\247\345\206\222\351\231\251/styles.css"
@@ -0,0 +1,314 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ cursor: none !important;
+}
+
+.game-container {
+ width: 100%;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background: #f0f0f0;
+ padding: 20px;
+}
+
+.human-body {
+ position: relative;
+ width: 300px;
+ height: 600px;
+ background: transparent;
+}
+
+.body-base {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.body-layer {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 300px;
+ height: 600px;
+ transition: opacity 0.3s;
+}
+
+.skeleton {
+ opacity: 0.7;
+}
+
+.organs {
+ opacity: 0.9;
+}
+
+.organ {
+ position: absolute;
+ background: transparent;
+ cursor: pointer;
+ transition: all 0.2s ease-out;
+ width: 40px;
+ height: 40px;
+ position: absolute;
+ cursor: pointer;
+ transition: filter 0.3s;
+ transform-style: preserve-3d;
+ perspective: 1000px;
+ border-radius: 50%;
+ background-color: transparent;
+}
+
+.organ:hover {
+ filter: brightness(1.2);
+ box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
+}
+
+.organ:active {
+ transform: scale(0.95);
+ filter: brightness(1.4);
+}
+
+.food-particle {
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ background: #4CAF50;
+ border-radius: 50%;
+ display: none;
+ z-index: 10;
+}
+
+.virus {
+ position: absolute;
+ width: 15px;
+ height: 15px;
+ background: #ff0000;
+ border-radius: 50%;
+ cursor: pointer;
+ z-index: 10;
+ animation: pulse 1s infinite;
+}
+
+@keyframes pulse {
+ 0% { transform: scale(1); }
+ 50% { transform: scale(1.2); }
+ 100% { transform: scale(1); }
+}
+
+.game-controls {
+ margin-top: 20px;
+ text-align: center;
+}
+
+button {
+ padding: 10px 20px;
+ font-size: 16px;
+ background: #4CAF50;
+ color: white;
+ border: none;
+ border-radius: 5px;
+ cursor: pointer;
+ transition: background 0.3s;
+}
+
+button:hover {
+ background: #45a049;
+ transform: scale(1.05);
+}
+
+.score {
+ margin-top: 10px;
+ font-size: 18px;
+ color: #333;
+}
+
+[data-organ]:hover::after {
+ content: attr(data-organ);
+ position: absolute;
+ background: rgba(0, 0, 0, 0.8);
+ color: white;
+ padding: 5px 10px;
+ border-radius: 5px;
+ font-size: 14px;
+ top: -25px;
+ left: 50%;
+ transform: translateX(-50%);
+ white-space: nowrap;
+ z-index: 11;
+}
+
+@keyframes digest {
+ 0% { transform: scale(1); }
+ 50% { transform: scale(1.1); }
+ 100% { transform: scale(1); }
+}
+
+.digesting {
+ animation: digest 1s ease-in-out;
+}
+
+.food-buttons {
+ margin-top: 10px;
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.food-buttons button {
+ padding: 8px 15px;
+ border: none;
+ border-radius: 5px;
+ color: white;
+ cursor: pointer;
+ transition: transform 0.2s;
+}
+
+.food-buttons button:hover {
+ transform: scale(1.1);
+}
+
+.health {
+ margin-top: 10px;
+ font-size: 18px;
+ color: #4CAF50;
+}
+
+@keyframes chew {
+ 0% { transform: scale(1); }
+ 50% { transform: scale(1.2) rotate(45deg); }
+ 100% { transform: scale(1); }
+}
+
+.heart {
+ top: 160px;
+ left: 130px;
+}
+
+.lungs {
+ top: 140px;
+ left: 110px;
+ width: 80px;
+}
+
+.liver {
+ top: 250px;
+ left: 130px;
+}
+
+.stomach {
+ top: 200px;
+ left: 140px;
+}
+
+.small-intestine {
+ top: 350px;
+ left: 130px;
+ width: 60px;
+}
+
+.large-intestine {
+ top: 450px;
+ left: 120px;
+ width: 80px;
+}
+
+#organ-tooltip {
+ position: fixed;
+ background: rgba(0, 0, 0, 0.8);
+ color: white;
+ padding: 10px;
+ border-radius: 5px;
+ font-size: 14px;
+ max-width: 200px;
+ z-index: 1000;
+ display: none;
+ pointer-events: none;
+ animation: fadeIn 0.3s ease-in-out;
+}
+
+@keyframes fadeIn {
+ from { opacity: 0; transform: translateY(10px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+.organ {
+ cursor: pointer;
+ transition: filter 0.3s;
+}
+
+.organ:hover {
+ filter: brightness(1.2);
+}
+
+.organ:active {
+ filter: brightness(1.4);
+ transform: scale(0.95);
+}
+
+/* 木鱼和木槌样式 */
+.fighter {
+ position: fixed;
+ width: 40px;
+ height: 40px;
+ pointer-events: none;
+ z-index: 9999;
+ transform-origin: 20px 20px;
+}
+
+.fighter svg {
+ width: 100%;
+ height: 100%;
+ filter: drop-shadow(0 2px 2px rgba(0,0,0,0.2));
+}
+
+/* 敲击动画 */
+.fighter.hitting .mallet {
+ animation: hit 0.1s ease-in-out;
+ transform-origin: 18px 22px;
+}
+
+@keyframes hit {
+ 0% { transform: rotate(0deg); }
+ 50% { transform: rotate(-30deg); }
+ 100% { transform: rotate(0deg); }
+}
+
+/* 木鱼震动效果 */
+.fighter.hitting .woodfish {
+ animation: shake 0.1s ease-in-out;
+}
+
+@keyframes shake {
+ 0% { transform: translateX(0); }
+ 25% { transform: translateX(-2px); }
+ 75% { transform: translateX(2px); }
+ 100% { transform: translateX(0); }
+}
+
+/* 木鱼敲击效果 */
+@keyframes organHit {
+ 0% {
+ transform: scale(1);
+ filter: brightness(1);
+ }
+ 50% {
+ transform: scale(1.2);
+ filter: brightness(1.5);
+ }
+ 100% {
+ transform: scale(1);
+ filter: brightness(1);
+ }
+}
+
+.organ-hit {
+ animation: organHit 0.2s cubic-bezier(.36,.07,.19,.97) both;
+ transform-origin: center;
+}
\ No newline at end of file
diff --git "a/\345\260\217\344\270\221\351\261\274\346\270\270\346\210\217/game.js" "b/\345\260\217\344\270\221\351\261\274\346\270\270\346\210\217/game.js"
new file mode 100644
index 0000000..b1540b5
--- /dev/null
+++ "b/\345\260\217\344\270\221\351\261\274\346\270\270\346\210\217/game.js"
@@ -0,0 +1,627 @@
+// 游戏对象
+class Game {
+ constructor() {
+ this.canvas = document.getElementById('gameCanvas');
+ this.ctx = this.canvas.getContext('2d');
+ this.width = this.canvas.width;
+ this.height = this.canvas.height;
+
+ // 初始化游戏元素
+ this.fishingRod = {
+ x: this.width / 2,
+ y: 50,
+ lineLength: 100, // 增加初始长度
+ maxLength: 500, // 增加最大长度
+ hookSize: 8,
+ isFishing: false,
+ speed: 8 // 增加放线速度
+ };
+
+ // 获取游戏容器
+ this.container = document.querySelector('.game-container');
+
+ // 定义鱼的类型
+ this.fishTypes = [
+ {
+ color: '#800080', // 紫色 - 章鱼
+ finColor: '#9932CC',
+ score: 10, // 章鱼分值最高
+ size: 1.5, // 章鱼最大
+ isOctopus: true // 标记为章鱼
+ },
+ {
+ color: '#FF4D4D', // 红色 - 核心组件
+ finColor: '#FF8080',
+ score: 1,
+ size: 1.4 // 核心组件最大
+ },
+ {
+ color: '#FFD700', // 金色 - 数据处理
+ finColor: '#FFF0B3',
+ score: 2,
+ size: 1.2 // 数据处理较大
+ },
+ {
+ color: '#4D4DFF', // 蓝色 - 数据存储
+ finColor: '#8080FF',
+ score: 3,
+ size: 1.1 // 数据存储中等
+ },
+ {
+ color: '#00FF00', // 绿色 - 工具组件
+ finColor: '#80FF80',
+ score: 4,
+ size: 1.0 // 工具组件标准大小
+ }
+ ];
+
+ // 添加英语单词库
+ this.words = [
+ // 核心组件
+ { word: 'Hadoop', meaning: '分布式计算平台' },
+ { word: 'HDFS', meaning: '分布式文件系统' },
+ { word: 'YARN', meaning: '集群资源管理系统' },
+ { word: 'MapReduce', meaning: '分布式计算框架' },
+
+ // 数据处理
+ { word: 'Spark', meaning: '内存计算引擎' },
+ { word: 'Flink', meaning: '流处理框架' },
+ { word: 'Storm', meaning: '实时计算系统' },
+ { word: 'Pig', meaning: '数据流处理语言' },
+
+ // 数据存储
+ { word: 'HBase', meaning: '分布式列式数据库' },
+ { word: 'Cassandra', meaning: '分布式NoSQL数据库' },
+ { word: 'Hive', meaning: '数据仓库工具' },
+ { word: 'Phoenix', meaning: 'SQL层for HBase' },
+
+ // 工具组件
+ { word: 'ZooKeeper', meaning: '分布式协调服务' },
+ { word: 'Sqoop', meaning: '数据导入导出工具' },
+ { word: 'Flume', meaning: '日志收集系统' },
+ { word: 'Ambari', meaning: '集群管理工具' },
+ { word: 'Oozie', meaning: '工作流调度系统' },
+ { word: 'Kafka', meaning: '分布式消息系统' }
+ ];
+
+ // 分开存储鱼和装饰物
+ this.fishes = [];
+ this.decorations = {
+ seaweeds: [],
+ starfish: []
+ };
+
+ // 先创建装饰物
+ this.createSeaweed();
+ this.createStarfish();
+
+ // 再创建可钓的鱼
+ this.createFishes();
+ this.createOctopus();
+
+ // 绑定事件监听
+ this.canvas.addEventListener('mousemove', (e) => this.handleMouseMove(e));
+
+ // 添加键盘事件监听
+ document.addEventListener('keydown', (e) => this.handleKeyDown(e));
+ document.addEventListener('keyup', (e) => this.handleKeyUp(e));
+
+ // 添加分数
+ this.score = 0;
+
+ // 创建音频上下文
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
+
+ // 创建音效生成器
+ this.createSoundEffects();
+
+ // 添加正在钓鱼的状态
+ this.hasCaughtFish = false;
+
+ // 开始游戏循环
+ this.gameLoop();
+ }
+
+ handleMouseMove(e) {
+ const rect = this.canvas.getBoundingClientRect();
+ this.fishingRod.x = e.clientX - rect.left;
+ }
+
+ // 处理按键按下
+ handleKeyDown(e) {
+ if (e.code === 'Space' && !this.fishingRod.isFishing) {
+ this.fishingRod.isFishing = true;
+ this.startFishing();
+ }
+ }
+
+ // 处理按键释放
+ handleKeyUp(e) {
+ if (e.code === 'Space') {
+ this.fishingRod.isFishing = false;
+ this.pullUp();
+ }
+ }
+
+ // 创建音效
+ createSoundEffects() {
+ // 下降音效生成器
+ this.createDropSound = () => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.type = 'sine';
+ oscillator.frequency.setValueAtTime(200, this.audioContext.currentTime);
+
+ gainNode.gain.setValueAtTime(0.1, this.audioContext.currentTime);
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ return { oscillator, gainNode };
+ };
+
+ // 捕获音效
+ this.playCatchSound = () => {
+ const oscillator = this.audioContext.createOscillator();
+ const gainNode = this.audioContext.createGain();
+
+ oscillator.type = 'sine';
+ oscillator.frequency.setValueAtTime(800, this.audioContext.currentTime);
+ oscillator.frequency.exponentialRampToValueAtTime(400, this.audioContext.currentTime + 0.1);
+
+ gainNode.gain.setValueAtTime(0.1, this.audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.1);
+
+ oscillator.connect(gainNode);
+ gainNode.connect(this.audioContext.destination);
+
+ oscillator.start();
+ oscillator.stop(this.audioContext.currentTime + 0.1);
+ };
+ }
+
+ // 开始钓鱼
+ startFishing() {
+ // 开始播放下降音效
+ this.dropSound = this.createDropSound();
+ this.dropSound.oscillator.start();
+ }
+
+ // 收竿
+ pullUp() {
+ // 停止下降音效
+ if (this.dropSound) {
+ this.dropSound.oscillator.stop();
+ this.dropSound = null;
+ }
+ }
+
+ update() {
+ // 更新鱼线长度
+ if (this.fishingRod.isFishing && this.fishingRod.lineLength < this.fishingRod.maxLength) {
+ // 放线
+ this.fishingRod.lineLength += this.fishingRod.speed;
+
+ // 更新下降音效频率
+ if (this.dropSound) {
+ const freq = 200 + (this.fishingRod.lineLength / this.fishingRod.maxLength) * 100;
+ this.dropSound.oscillator.frequency.setValueAtTime(freq, this.audioContext.currentTime);
+ }
+ } else if (!this.fishingRod.isFishing && this.fishingRod.lineLength > 50) {
+ // 收线
+ this.fishingRod.lineLength -= this.fishingRod.speed;
+
+ // 停止下降音效
+ if (this.dropSound) {
+ this.dropSound.oscillator.stop();
+ this.dropSound = null;
+ }
+
+ // 检查是否有鱼被钓上来
+ this.fishes.forEach(fish => {
+ if (fish.caught) {
+ fish.y = this.fishingRod.y + this.fishingRod.lineLength;
+ }
+ });
+ }
+
+ // 检测碰撞
+ if (this.fishingRod.isFishing && !this.hasCaughtFish) {
+ const hookX = this.fishingRod.x;
+ const hookY = this.fishingRod.y + this.fishingRod.lineLength;
+
+ for (let fish of this.fishes) {
+ if (!fish.caught && this.checkCollision(hookX, hookY, fish)) {
+ fish.caught = true;
+ this.hasCaughtFish = true;
+ this.playCatchSound();
+ break;
+ }
+ }
+ }
+
+ // 只更新鱼的位置
+ this.fishes.forEach(fish => {
+ if (fish.caught) {
+ const hookY = this.fishingRod.y + this.fishingRod.lineLength;
+ fish.x = this.fishingRod.x - fish.width / 2;
+ fish.y = hookY;
+
+ // 如果鱼被拉到顶部,重置
+ if (fish.y <= 100) {
+ this.addScore(fish);
+ this.resetFish(fish);
+ this.hasCaughtFish = false; // 重置钓鱼状态
+ }
+ } else {
+ fish.x += fish.speed * fish.direction;
+
+ if (fish.x <= 0 || fish.x >= this.width) {
+ fish.direction *= -1;
+ }
+ }
+
+ // 更新DOM元素位置
+ if (fish.isOctopus) {
+ // 章鱼的特殊处理
+ fish.element.style.transform = `translate(${fish.x}px, ${fish.y}px)`;
+ if (fish.direction < 0) {
+ fish.element.style.transform += ' scaleX(-1)';
+ }
+ } else {
+ // 普通鱼的处理
+ fish.element.style.transform = `translate(${fish.x}px, ${fish.y}px)`;
+ const body = fish.element.querySelector('.fish-body');
+ const tail = fish.element.querySelector('.fish-tail');
+ const fin = fish.element.querySelector('.fish-fin');
+
+ if (fish.direction < 0) {
+ body.style.transform = 'scaleX(-1)';
+ tail.style.transform = 'scaleX(-1)';
+ fin.style.transform = 'scaleX(-1)';
+ } else {
+ body.style.transform = 'scaleX(1)';
+ tail.style.transform = 'scaleX(1)';
+ fin.style.transform = 'scaleX(1)';
+ }
+ }
+ });
+ }
+
+ checkCollision(x, y, fish) {
+ const tolerance = 10;
+ return x > fish.x - tolerance &&
+ x < fish.x + fish.width + tolerance &&
+ y > fish.y - tolerance &&
+ y < fish.y + fish.height + tolerance;
+ }
+
+ resetFish(fish) {
+ if (fish.isOctopus) {
+ // 章鱼重置到随机位置
+ fish.x = Math.random() * this.width;
+ fish.y = 400 + Math.random() * 100;
+ fish.caught = false;
+ fish.direction = Math.random() < 0.5 ? 1 : -1;
+ return;
+ }
+
+ const fishType = this.fishTypes[Math.floor(Math.random() * this.fishTypes.length)];
+ const wordObj = this.words[Math.floor(Math.random() * this.words.length)];
+
+ // 更新鱼的大小
+ const baseWidth = 50;
+ const baseHeight = 30;
+ const scale = fishType.size;
+
+ fish.element.style.width = `${baseWidth * scale}px`;
+ fish.element.style.height = `${baseHeight * scale}px`;
+ fish.width = baseWidth * scale;
+ fish.height = baseHeight * scale;
+
+ fish.x = Math.random() * this.width;
+ fish.y = 300 + Math.random() * 200;
+ fish.caught = false;
+ fish.direction = Math.random() < 0.5 ? 1 : -1;
+ fish.speed = 1 + Math.random() * 2;
+ fish.type = fishType;
+
+ // 更新鱼的颜色
+ const body = fish.element.querySelector('.fish-body');
+ const tail = fish.element.querySelector('.fish-tail');
+ const fin = fish.element.querySelector('.fish-fin');
+
+ body.style.backgroundColor = fishType.color;
+ tail.style.backgroundColor = fishType.color;
+ fin.style.backgroundColor = fishType.finColor;
+
+ // 更新单词
+ fish.word = wordObj;
+ const wordDiv = fish.element.querySelector('.fish-word');
+ wordDiv.textContent = wordObj.word;
+ }
+
+ draw() {
+ this.ctx.clearRect(0, 0, this.width, this.height);
+
+ // 绘制鱼线
+ this.ctx.beginPath();
+ this.ctx.moveTo(this.fishingRod.x, 0);
+ this.ctx.lineTo(this.fishingRod.x, this.fishingRod.y + this.fishingRod.lineLength);
+ this.ctx.strokeStyle = '#FFFFFF';
+ this.ctx.lineWidth = 2; // 增加线的宽度使其更明显
+ this.ctx.stroke();
+
+ // 绘制鱼钩
+ const hookY = this.fishingRod.y + this.fishingRod.lineLength;
+ this.ctx.beginPath();
+ this.ctx.arc(
+ this.fishingRod.x,
+ hookY,
+ this.fishingRod.hookSize,
+ 0,
+ Math.PI * 1.5,
+ false
+ );
+ this.ctx.strokeStyle = '#FFFFFF';
+ this.ctx.lineWidth = 2;
+ this.ctx.stroke();
+
+ // 绘制分数
+ this.ctx.fillStyle = '#FFFFFF';
+ this.ctx.font = 'bold 24px Arial';
+ this.ctx.fillText(`总分: ${this.score}`, 10, 60);
+
+ // 绘制鱼的说明
+ this.ctx.font = '16px Arial';
+ this.fishTypes.forEach((type, index) => {
+ this.ctx.fillStyle = type.color;
+ let category;
+ switch(index) {
+ case 0: category = '章鱼'; break;
+ case 1: category = '核心组件 (大)'; break;
+ case 2: category = '数据处理 (中大)'; break;
+ case 3: category = '数据存储 (中)'; break;
+ case 4: category = '工具组件 (小)'; break;
+ }
+ this.ctx.fillText(`${category}: ${type.score}分`, 10, 90 + index * 25);
+ });
+
+ // 绘制操作提示
+ this.ctx.font = '20px Arial';
+ this.ctx.fillText('按住空格键放线,松开收线', 10, 30);
+
+ // 添加章鱼说明
+ this.ctx.fillStyle = '#800080';
+ this.ctx.fillText('章鱼: 10分 (特殊奖励)', 10, 90 + this.fishTypes.length * 25);
+ }
+
+ gameLoop() {
+ this.update();
+ this.draw();
+ requestAnimationFrame(() => this.gameLoop());
+ }
+
+ // 添加分数
+ addScore(fish) {
+ this.score += fish.type.score;
+ this.playCatchSound();
+
+ // 创建得分动画
+ const scoreDiv = document.createElement('div');
+ scoreDiv.className = 'score-popup';
+
+ // 先只显示分数和软件名
+ scoreDiv.innerHTML = `
+ +${fish.type.score}
+
+ `;
+ scoreDiv.style.left = `${this.fishingRod.x}px`;
+ scoreDiv.style.top = '100px';
+ scoreDiv.style.color = fish.type.color;
+ this.container.appendChild(scoreDiv);
+
+ // 延迟1秒显示中文含义
+ setTimeout(() => {
+ const meaningDiv = document.createElement('div');
+ meaningDiv.className = 'meaning';
+ meaningDiv.textContent = fish.word.meaning;
+ scoreDiv.querySelector('.word-popup').appendChild(meaningDiv);
+ }, 1000);
+
+ // 6秒后开始淡出动画
+ setTimeout(() => {
+ // 英文先淡出
+ scoreDiv.querySelector('.score-text').style.animation = 'fadeOut 1s ease-out';
+ scoreDiv.querySelector('.english-word').style.animation = 'fadeOut 1s ease-out';
+
+ // 2秒后中文再淡出
+ setTimeout(() => {
+ scoreDiv.querySelector('.meaning').style.animation = 'fadeOut 1s ease-out';
+
+ // 等待中文淡出完成后移除元素
+ setTimeout(() => {
+ this.container.removeChild(scoreDiv);
+ }, 1000);
+ }, 2000);
+ }, 6000);
+ }
+
+ // 创建海草
+ createSeaweed() {
+ // 创建多株海草
+ for (let i = 0; i < 8; i++) {
+ const seaweed = document.createElement('div');
+ seaweed.className = 'seaweed';
+
+ // 每株海草有3片叶子
+ for (let j = 0; j < 3; j++) {
+ const leaf = document.createElement('div');
+ leaf.className = 'seaweed-leaf';
+ leaf.style.bottom = `${j * 30}px`;
+ // 随机调整动画延迟,使得摆动不同步
+ leaf.style.animationDelay = `${Math.random() * 2}s`;
+ seaweed.appendChild(leaf);
+ }
+
+ // 随机位置
+ seaweed.style.left = `${50 + (i * 100) + Math.random() * 30}px`;
+ // 随机高度
+ seaweed.style.height = `${80 + Math.random() * 40}px`;
+
+ this.container.appendChild(seaweed);
+ }
+ }
+
+ // 创建海星
+ createStarfish() {
+ // 创建多个海星
+ for (let i = 0; i < 5; i++) {
+ const starfish = document.createElement('div');
+ starfish.className = 'starfish';
+
+ // 固定位置在底部
+ starfish.style.left = `${100 + (i * 150) + Math.random() * 50}px`;
+ starfish.style.bottom = '20px'; // 使用 bottom 而不是 transform
+ // 随机旋转
+ starfish.style.transform = `rotate(${Math.random() * 360}deg)`;
+ // 随机动画延迟
+ starfish.style.animationDelay = `${Math.random() * 2}s`;
+
+ this.container.appendChild(starfish);
+ this.decorations.starfish.push(starfish);
+ }
+ }
+
+ // 创建章鱼
+ createOctopus() {
+ const octopus = document.createElement('div');
+ octopus.className = 'octopus';
+
+ // 创建章鱼头部
+ const head = document.createElement('div');
+ head.className = 'octopus-head';
+
+ // 创建眼睛
+ const leftEye = document.createElement('div');
+ leftEye.className = 'octopus-eye left';
+ const rightEye = document.createElement('div');
+ rightEye.className = 'octopus-eye right';
+
+ head.appendChild(leftEye);
+ head.appendChild(rightEye);
+ octopus.appendChild(head);
+
+ // 创建触手
+ for (let i = 0; i < 8; i++) {
+ const tentacle = document.createElement('div');
+ tentacle.className = 'octopus-tentacle';
+ tentacle.style.left = `${i * 9}px`;
+ tentacle.style.animationDelay = `${i * 0.2}s`;
+ octopus.appendChild(tentacle);
+ }
+
+ // 添加单词显示
+ const wordDiv = document.createElement('div');
+ wordDiv.className = 'fish-word';
+ const wordObj = { word: 'Octopus', meaning: '章鱼 - 特殊奖励(+10分)' };
+ const wordSpan = document.createElement('span');
+ wordSpan.className = 'word-text';
+ wordSpan.textContent = wordObj.word;
+ wordDiv.appendChild(wordSpan);
+ octopus.appendChild(wordDiv);
+
+ this.container.appendChild(octopus);
+
+ // 添加到鱼群中
+ this.fishes.push({
+ element: octopus,
+ x: Math.random() * this.width,
+ y: 400 + Math.random() * 100,
+ width: 70,
+ height: 70,
+ speed: 0.5 + Math.random() * 1, // 章鱼移动较慢
+ direction: Math.random() < 0.5 ? 1 : -1,
+ caught: false,
+ type: this.fishTypes[0], // 使用章鱼类型
+ word: wordObj,
+ isOctopus: true
+ });
+ }
+
+ // 添加创建普通鱼的方法
+ createFishes() {
+ // 创建10条普通鱼
+ for (let i = 0; i < 10; i++) {
+ // 跳过章鱼类型
+ const fishTypeIndex = 1 + Math.floor(Math.random() * (this.fishTypes.length - 1));
+ const fishType = this.fishTypes[fishTypeIndex];
+ const fishDiv = document.createElement('div');
+ fishDiv.className = 'fish';
+
+ // 设置鱼的基础大小
+ const baseWidth = 50;
+ const baseHeight = 30;
+ const scale = fishType.size;
+
+ fishDiv.style.width = `${baseWidth * scale}px`;
+ fishDiv.style.height = `${baseHeight * scale}px`;
+
+ // 创建鱼的身体部分
+ const body = document.createElement('div');
+ body.className = 'fish-body';
+ body.style.backgroundColor = fishType.color;
+ fishDiv.appendChild(body);
+
+ // 创建鱼尾
+ const tail = document.createElement('div');
+ tail.className = 'fish-tail';
+ tail.style.backgroundColor = fishType.color;
+ fishDiv.appendChild(tail);
+
+ // 创建鱼眼
+ const eye = document.createElement('div');
+ eye.className = 'fish-eye';
+ fishDiv.appendChild(eye);
+
+ // 创建鱼鳍
+ const fin = document.createElement('div');
+ fin.className = 'fish-fin';
+ fin.style.backgroundColor = fishType.finColor;
+ fishDiv.appendChild(fin);
+
+ // 添加单词显示
+ const wordDiv = document.createElement('div');
+ wordDiv.className = 'fish-word';
+ const wordObj = this.words[Math.floor(Math.random() * this.words.length)];
+ const wordSpan = document.createElement('span');
+ wordSpan.className = 'word-text';
+ wordSpan.textContent = wordObj.word;
+ wordDiv.appendChild(wordSpan);
+ fishDiv.appendChild(wordDiv);
+
+ this.container.appendChild(fishDiv);
+
+ this.fishes.push({
+ element: fishDiv,
+ x: Math.random() * this.width,
+ y: 300 + Math.random() * 200,
+ width: baseWidth * scale,
+ height: baseHeight * scale,
+ speed: 1 + Math.random() * 2,
+ direction: Math.random() < 0.5 ? 1 : -1,
+ caught: false,
+ type: fishType,
+ word: wordObj
+ });
+ }
+ }
+}
+
+// 初始化游戏
+window.onload = () => {
+ new Game();
+};
\ No newline at end of file
diff --git "a/\345\260\217\344\270\221\351\261\274\346\270\270\346\210\217/index.html" "b/\345\260\217\344\270\221\351\261\274\346\270\270\346\210\217/index.html"
new file mode 100644
index 0000000..db06c8e
--- /dev/null
+++ "b/\345\260\217\344\270\221\351\261\274\346\270\270\346\210\217/index.html"
@@ -0,0 +1,270 @@
+
+
+
+
+ 抓金鱼游戏
+
+
+
+
+
+
+
+
+
\ No newline at end of file