MagicPot / js /pot.js
zhanglei
fix voice
ab5909a
Raw
History Blame Contribute Delete
14.2 kB
// 魔法锅类
class MagicPot {
constructor(x, y) {
this.x = x;
this.y = y;
this.width = 120;
this.height = 100;
this.state = 'idle'; // idle, activated, cooking, overflowing
// 动画属性
this.animationTime = 0;
this.glowIntensity = 0;
this.shakeAmount = 0;
this.lidOffset = 0;
this.steamParticles = [];
// 颜色配置
this.colors = {
pot: '#8B4513',
potHighlight: '#CD853F',
potShadow: '#654321',
lid: '#A0522D',
lidHighlight: '#DEB887',
glow: '#FFD700',
steam: '#FFFFFF',
magic: '#FF69B4'
};
// 食物和动物素材
this.foodImage = null;
this.animalImage = null;
this.currentFood = null;
// 魔法锅图片
this.potImage = null;
this.imageLoaded = false;
this.loadPotImage();
}
update(deltaTime) {
this.animationTime += deltaTime * 0.001;
// 根据状态更新动画
switch (this.state) {
case 'idle':
this.updateIdleAnimation();
break;
case 'activated':
this.updateActivatedAnimation();
break;
case 'cooking':
this.updateCookingAnimation();
break;
case 'overflowing':
this.updateOverflowingAnimation();
break;
}
// 更新蒸汽粒子
this.updateSteamParticles(deltaTime);
}
updateIdleAnimation() {
// 轻微的呼吸效果
this.glowIntensity = Math.sin(this.animationTime * 0.5) * 0.1 + 0.1;
this.shakeAmount = 0;
this.lidOffset = 0;
}
updateActivatedAnimation() {
// 发光效果
this.glowIntensity = Math.sin(this.animationTime * 2) * 0.3 + 0.5;
this.shakeAmount = 0;
this.lidOffset = 0;
// 生成魔法粒子
if (Math.random() < 0.1) {
this.createMagicParticle();
}
}
updateCookingAnimation() {
// 强烈的发光和轻微震动
this.glowIntensity = Math.sin(this.animationTime * 3) * 0.4 + 0.6;
this.shakeAmount = Math.sin(this.animationTime * 8) * 2;
this.lidOffset = Math.sin(this.animationTime * 4) * 3;
// 生成蒸汽
if (Math.random() < 0.3) {
this.createSteamParticle();
}
// 生成魔法粒子
if (Math.random() < 0.2) {
this.createMagicParticle();
}
}
updateOverflowingAnimation() {
// 剧烈震动,锅盖被顶开
this.glowIntensity = 1;
this.shakeAmount = Math.sin(this.animationTime * 15) * 5;
this.lidOffset = -20 + Math.sin(this.animationTime * 10) * 5;
// 大量蒸汽
if (Math.random() < 0.8) {
this.createSteamParticle();
}
// 魔法粒子
if (Math.random() < 0.5) {
this.createMagicParticle();
}
}
createSteamParticle() {
const particle = {
x: this.x + (Math.random() - 0.5) * this.width * 0.8,
y: this.y - this.height * 0.3,
vx: (Math.random() - 0.5) * 20,
vy: -Math.random() * 50 - 30,
size: Math.random() * 8 + 4,
opacity: 0.8,
life: 1,
maxLife: Math.random() * 2 + 1
};
this.steamParticles.push(particle);
}
createMagicParticle() {
const angle = Math.random() * Math.PI * 2;
const radius = this.width * 0.6;
const particle = {
x: this.x + Math.cos(angle) * radius,
y: this.y + Math.sin(angle) * radius * 0.5,
vx: Math.cos(angle) * 30,
vy: Math.sin(angle) * 30 - 20,
size: Math.random() * 4 + 2,
opacity: 1,
life: 1,
maxLife: Math.random() * 1.5 + 0.5,
color: Math.random() < 0.5 ? '#FFD700' : '#FF69B4'
};
this.steamParticles.push(particle);
}
updateSteamParticles(deltaTime) {
for (let i = this.steamParticles.length - 1; i >= 0; i--) {
const particle = this.steamParticles[i];
// 更新位置
particle.x += particle.vx * deltaTime * 0.001;
particle.y += particle.vy * deltaTime * 0.001;
// 更新生命周期
particle.life -= deltaTime * 0.001 / particle.maxLife;
particle.opacity = particle.life;
// 蒸汽粒子逐渐变大
if (!particle.color) {
particle.size += deltaTime * 0.002;
}
// 移除死亡的粒子
if (particle.life <= 0) {
this.steamParticles.splice(i, 1);
}
}
}
render(ctx) {
const currentX = this.x + (Math.random() - 0.5) * this.shakeAmount;
const currentY = this.y + (Math.random() - 0.5) * this.shakeAmount;
// 绘制发光效果
if (this.glowIntensity > 0) {
this.renderGlow(ctx, currentX, currentY);
}
// 绘制魔法锅(图片或默认绘制)
if (this.imageLoaded && this.potImage) {
this.renderPotImage(ctx, currentX, currentY);
} else {
// 备用绘制方案
this.renderPotBody(ctx, currentX, currentY);
this.renderPotLid(ctx, currentX, currentY + this.lidOffset);
}
// 绘制蒸汽和魔法粒子
this.renderParticles(ctx);
// 绘制装饰
this.renderDecorations(ctx, currentX, currentY);
}
renderPotImage(ctx, x, y) {
ctx.save();
// 如果有发光效果,添加阴影
if (this.glowIntensity > 0) {
ctx.shadowBlur = this.glowIntensity * 30;
ctx.shadowColor = '#FFD700';
}
// 计算图片尺寸和位置
const imageWidth = this.width * 1.5; // 稍微放大一点
const imageHeight = this.height * 1.5;
const imageX = x - imageWidth / 2;
const imageY = y - imageHeight / 2 + this.lidOffset * 0.3; // 锅盖偏移效果
// 绘制魔法锅图片
ctx.drawImage(
this.potImage,
imageX,
imageY,
imageWidth,
imageHeight
);
ctx.restore();
}
renderGlow(ctx, x, y) {
const glowRadius = this.width * 0.8 * this.glowIntensity;
const gradient = ctx.createRadialGradient(x, y, 0, x, y, glowRadius);
gradient.addColorStop(0, `rgba(255, 215, 0, ${this.glowIntensity * 0.3})`);
gradient.addColorStop(0.5, `rgba(255, 105, 180, ${this.glowIntensity * 0.2})`);
gradient.addColorStop(1, 'rgba(255, 215, 0, 0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(x, y, glowRadius, 0, Math.PI * 2);
ctx.fill();
}
renderPotBody(ctx, x, y) {
const potWidth = this.width;
const potHeight = this.height;
// 锅身主体
ctx.fillStyle = this.colors.pot;
ctx.beginPath();
ctx.ellipse(x, y + potHeight * 0.3, potWidth * 0.5, potHeight * 0.4, 0, 0, Math.PI * 2);
ctx.fill();
// 锅身侧面
ctx.fillStyle = this.colors.potShadow;
ctx.fillRect(x - potWidth * 0.5, y - potHeight * 0.2, potWidth, potHeight * 0.5);
// 锅身高光
ctx.fillStyle = this.colors.potHighlight;
ctx.beginPath();
ctx.ellipse(x - potWidth * 0.2, y - potHeight * 0.1, potWidth * 0.15, potHeight * 0.1, 0, 0, Math.PI * 2);
ctx.fill();
// 锅把手
this.renderHandles(ctx, x, y);
}
renderHandles(ctx, x, y) {
ctx.strokeStyle = this.colors.potShadow;
ctx.lineWidth = 8;
ctx.lineCap = 'round';
// 左把手
ctx.beginPath();
ctx.arc(x - this.width * 0.6, y, this.width * 0.15, -Math.PI * 0.3, Math.PI * 0.3);
ctx.stroke();
// 右把手
ctx.beginPath();
ctx.arc(x + this.width * 0.6, y, this.width * 0.15, Math.PI * 0.7, Math.PI * 1.3);
ctx.stroke();
}
renderPotLid(ctx, x, y) {
const lidWidth = this.width * 0.9;
const lidHeight = this.height * 0.2;
// 锅盖主体
ctx.fillStyle = this.colors.lid;
ctx.beginPath();
ctx.ellipse(x, y - this.height * 0.3, lidWidth * 0.5, lidHeight * 0.5, 0, 0, Math.PI * 2);
ctx.fill();
// 锅盖高光
ctx.fillStyle = this.colors.lidHighlight;
ctx.beginPath();
ctx.ellipse(x - lidWidth * 0.1, y - this.height * 0.35, lidWidth * 0.3, lidHeight * 0.3, 0, 0, Math.PI * 2);
ctx.fill();
// 锅盖把手
ctx.fillStyle = this.colors.potShadow;
ctx.beginPath();
ctx.ellipse(x, y - this.height * 0.45, 8, 12, 0, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = this.colors.lidHighlight;
ctx.beginPath();
ctx.ellipse(x - 2, y - this.height * 0.48, 4, 6, 0, 0, Math.PI * 2);
ctx.fill();
}
renderParticles(ctx) {
this.steamParticles.forEach(particle => {
ctx.save();
ctx.globalAlpha = particle.opacity;
if (particle.color) {
// 魔法粒子
ctx.fillStyle = particle.color;
ctx.shadowBlur = 10;
ctx.shadowColor = particle.color;
} else {
// 蒸汽粒子
ctx.fillStyle = this.colors.steam;
}
ctx.beginPath();
ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
});
}
renderDecorations(ctx, x, y) {
// 绘制魔法符文(如果激活)
if (this.state !== 'idle') {
this.renderMagicRunes(ctx, x, y);
}
// 绘制食物图标(如果正在烹饪)
if (this.state === 'cooking' && this.currentFood) {
this.renderFoodIcon(ctx, x, y);
}
}
renderMagicRunes(ctx, x, y) {
const runeRadius = this.width * 0.8;
const runeCount = 6;
const time = this.animationTime * 2;
ctx.strokeStyle = this.colors.magic;
ctx.lineWidth = 2;
ctx.globalAlpha = this.glowIntensity * 0.5;
for (let i = 0; i < runeCount; i++) {
const angle = (i / runeCount) * Math.PI * 2 + time;
const runeX = x + Math.cos(angle) * runeRadius;
const runeY = y + Math.sin(angle) * runeRadius * 0.5;
// 绘制简单的符文形状
ctx.beginPath();
ctx.moveTo(runeX - 5, runeY - 5);
ctx.lineTo(runeX + 5, runeY + 5);
ctx.moveTo(runeX + 5, runeY - 5);
ctx.lineTo(runeX - 5, runeY + 5);
ctx.stroke();
}
ctx.globalAlpha = 1;
}
renderFoodIcon(ctx, x, y) {
// 在锅上方显示食物图标
const iconY = y - this.height * 0.8;
ctx.fillStyle = '#FFD700';
ctx.font = '24px Arial';
ctx.textAlign = 'center';
ctx.fillText(this.getFoodEmoji(this.currentFood), x, iconY);
}
getFoodEmoji(foodName) {
const emojiMap = {
'apple': '🍎',
'banana': '🍌',
'orange': '🍊',
'strawberry': '🍓',
'watermelon': '🍉',
'grape': '🍇',
'pizza': '🍕',
'burger': '🍔',
'cake': '🍰',
'cookie': '🍪',
'bread': '🍞',
'cheese': '🧀',
'fish': '🐟',
'chicken': '🍗',
'rice': '🍚',
'noodles': '🍜'
};
return emojiMap[foodName] || '🍽️';
}
// 状态控制方法
activate() {
this.state = 'activated';
this.animationTime = 0;
}
startCooking(foodName) {
this.state = 'cooking';
this.currentFood = foodName;
this.animationTime = 0;
}
startOverflowing() {
this.state = 'overflowing';
this.animationTime = 0;
}
stopOverflowing() {
this.state = 'activated';
this.lidOffset = 0;
this.shakeAmount = 0;
}
reset() {
this.state = 'idle';
this.currentFood = null;
this.animationTime = 0;
this.glowIntensity = 0;
this.shakeAmount = 0;
this.lidOffset = 0;
this.steamParticles = [];
}
setFoodAssets(foodImage, animalImage) {
this.foodImage = foodImage;
this.animalImage = animalImage;
}
// 碰撞检测
contains(x, y) {
const dx = x - this.x;
const dy = y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
return distance < this.width * 0.5;
}
// 获取锅的边界
getBounds() {
return {
left: this.x - this.width * 0.5,
right: this.x + this.width * 0.5,
top: this.y - this.height * 0.5,
bottom: this.y + this.height * 0.5
};
}
// 加载魔法锅图片
loadPotImage() {
this.potImage = new Image();
this.potImage.onload = () => {
this.imageLoaded = true;
console.log('魔法锅图片加载成功');
};
this.potImage.onerror = () => {
console.warn('魔法锅图片加载失败,使用默认绘制');
this.imageLoaded = false;
};
this.potImage.src = 'assets/images/magic_pot.png';
}
}