feat: 星域故事汇小游戏初始版本

This commit is contained in:
2026-03-03 16:57:49 +08:00
commit cc0e39cccc
34 changed files with 6556 additions and 0 deletions

View File

@@ -0,0 +1,745 @@
/**
* 结局场景
*/
import BaseScene from './BaseScene';
export default class EndingScene extends BaseScene {
constructor(main, params) {
super(main, params);
this.storyId = params.storyId;
this.ending = params.ending;
this.showButtons = false;
this.fadeIn = 0;
this.particles = [];
this.isLiked = false;
this.isCollected = false;
// AI改写面板
this.showRewritePanel = false;
this.rewritePrompt = '';
this.rewriteTags = ['主角逆袭', '甜蜜HE', '虐心BE', '反转剧情', '意外重逢'];
this.selectedTag = -1;
this.initParticles();
}
init() {
setTimeout(() => {
this.showButtons = true;
}, 1500);
}
initParticles() {
for (let i = 0; i < 50; i++) {
this.particles.push({
x: Math.random() * this.screenWidth,
y: Math.random() * this.screenHeight,
size: Math.random() * 3 + 1,
speedY: Math.random() * 0.5 + 0.2,
alpha: Math.random() * 0.5 + 0.3
});
}
}
update() {
if (this.fadeIn < 1) {
this.fadeIn += 0.02;
}
this.particles.forEach(p => {
p.y -= p.speedY;
if (p.y < 0) {
p.y = this.screenHeight;
p.x = Math.random() * this.screenWidth;
}
});
}
render(ctx) {
this.renderBackground(ctx);
this.renderParticles(ctx);
this.renderEndingContent(ctx);
if (this.showButtons) {
this.renderButtons(ctx);
}
// AI改写面板
if (this.showRewritePanel) {
this.renderRewritePanel(ctx);
}
}
renderBackground(ctx) {
const gradient = ctx.createLinearGradient(0, 0, 0, this.screenHeight);
switch (this.ending?.type) {
case 'good':
gradient.addColorStop(0, '#0f2027');
gradient.addColorStop(0.5, '#203a43');
gradient.addColorStop(1, '#2c5364');
break;
case 'bad':
gradient.addColorStop(0, '#1a0a0a');
gradient.addColorStop(0.5, '#3a1515');
gradient.addColorStop(1, '#2d1f1f');
break;
case 'hidden':
gradient.addColorStop(0, '#1a1a0a');
gradient.addColorStop(0.5, '#3a3515');
gradient.addColorStop(1, '#2d2d1f');
break;
default:
gradient.addColorStop(0, '#0f0c29');
gradient.addColorStop(0.5, '#302b63');
gradient.addColorStop(1, '#24243e');
}
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, this.screenWidth, this.screenHeight);
}
renderParticles(ctx) {
this.particles.forEach(p => {
ctx.fillStyle = `rgba(255, 255, 255, ${p.alpha * this.fadeIn})`;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fill();
});
}
renderEndingContent(ctx) {
const centerX = this.screenWidth / 2;
const alpha = this.fadeIn;
const padding = 20;
// 结局卡片背景
const cardY = 80;
const cardHeight = 320;
ctx.fillStyle = `rgba(255, 255, 255, ${0.05 * alpha})`;
this.roundRect(ctx, padding, cardY, this.screenWidth - padding * 2, cardHeight, 20);
ctx.fill();
// 装饰线
const lineGradient = ctx.createLinearGradient(padding + 30, cardY + 20, this.screenWidth - padding - 30, cardY + 20);
lineGradient.addColorStop(0, 'transparent');
lineGradient.addColorStop(0.5, this.getEndingColorRgba(alpha * 0.5));
lineGradient.addColorStop(1, 'transparent');
ctx.strokeStyle = lineGradient;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(padding + 30, cardY + 20);
ctx.lineTo(this.screenWidth - padding - 30, cardY + 20);
ctx.stroke();
// 结局标签
ctx.fillStyle = `rgba(255, 255, 255, ${alpha * 0.6})`;
ctx.font = '13px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('— 达成结局 —', centerX, cardY + 50);
// 结局名称(自动调整字号)
const endingName = this.ending?.name || '未知结局';
let fontSize = 24;
ctx.font = `bold ${fontSize}px sans-serif`;
while (ctx.measureText(endingName).width > this.screenWidth - padding * 2 - 40 && fontSize > 14) {
fontSize -= 2;
ctx.font = `bold ${fontSize}px sans-serif`;
}
ctx.fillStyle = this.getEndingColorRgba(alpha);
ctx.fillText(endingName, centerX, cardY + 90);
// 结局类型标签
const typeLabel = this.getTypeLabel();
if (typeLabel) {
ctx.font = '11px sans-serif';
const labelWidth = ctx.measureText(typeLabel).width + 20;
ctx.fillStyle = this.getEndingColorRgba(alpha * 0.3);
this.roundRect(ctx, centerX - labelWidth / 2, cardY + 100, labelWidth, 22, 11);
ctx.fill();
ctx.fillStyle = `rgba(255, 255, 255, ${alpha * 0.9})`;
ctx.fillText(typeLabel, centerX, cardY + 115);
}
// 评分
if (this.ending?.score !== undefined) {
this.renderScore(ctx, centerX, cardY + 155, alpha);
}
// 结局描述(居中显示,限制在卡片内)
ctx.fillStyle = `rgba(255, 255, 255, ${alpha * 0.6})`;
ctx.font = '12px sans-serif';
ctx.textAlign = 'center';
const content = this.ending?.content || '';
const lastParagraph = content.split('\n').filter(p => p.trim()).pop() || '';
const maxWidth = this.screenWidth - padding * 2 - 30;
// 限制只显示2行居中
this.wrapTextCentered(ctx, lastParagraph, centerX, cardY + 250, maxWidth, 20, 2);
}
getTypeLabel() {
switch (this.ending?.type) {
case 'good': return '✨ 完美结局';
case 'bad': return '💔 悲伤结局';
case 'hidden': return '🔮 隐藏结局';
default: return '📖 普通结局';
}
}
truncateText(ctx, text, maxWidth) {
if (!text) return '';
if (ctx.measureText(text).width <= maxWidth) return text;
let truncated = text;
while (truncated.length > 0 && ctx.measureText(truncated + '...').width > maxWidth) {
truncated = truncated.slice(0, -1);
}
return truncated + '...';
}
renderScore(ctx, x, y, alpha) {
const score = this.ending?.score || 0;
const stars = Math.ceil(score / 20);
// 星星
const starSize = 22;
const gap = 6;
const totalWidth = 5 * starSize + 4 * gap;
const startX = x - totalWidth / 2;
for (let i = 0; i < 5; i++) {
const filled = i < stars;
ctx.fillStyle = filled ? `rgba(255, 215, 0, ${alpha})` : `rgba(100, 100, 100, ${alpha * 0.5})`;
ctx.font = `${starSize}px sans-serif`;
ctx.textAlign = 'left';
ctx.fillText(filled ? '★' : '☆', startX + i * (starSize + gap), y);
}
// 分数
ctx.fillStyle = `rgba(255, 215, 0, ${alpha})`;
ctx.font = 'bold 16px sans-serif';
ctx.textAlign = 'center';
ctx.fillText(`${score}`, x, y + 28);
}
getEndingColorRgba(alpha) {
switch (this.ending?.type) {
case 'good': return `rgba(100, 255, 150, ${alpha})`;
case 'bad': return `rgba(255, 100, 100, ${alpha})`;
case 'hidden': return `rgba(255, 215, 0, ${alpha})`;
default: return `rgba(150, 150, 255, ${alpha})`;
}
}
renderButtons(ctx) {
const padding = 15;
const buttonHeight = 38;
const buttonMargin = 8;
const startY = this.screenHeight - 220;
const buttonWidth = (this.screenWidth - padding * 2 - buttonMargin) / 2;
// AI改写按钮突出显示
this.renderGradientButton(ctx, padding, startY, this.screenWidth - padding * 2, buttonHeight, '✨ AI改写结局', ['#a855f7', '#ec4899']);
// 分享按钮
const row2Y = startY + buttonHeight + buttonMargin;
this.renderGradientButton(ctx, padding, row2Y, buttonWidth, buttonHeight, '分享结局', ['#ff6b6b', '#ffd700']);
// 章节选择按钮
this.renderGradientButton(ctx, padding + buttonWidth + buttonMargin, row2Y, buttonWidth, buttonHeight, '章节选择', ['#667eea', '#764ba2']);
// 从头开始
const row3Y = row2Y + buttonHeight + buttonMargin;
ctx.fillStyle = 'rgba(255,255,255,0.1)';
this.roundRect(ctx, padding, row3Y, buttonWidth, buttonHeight, 19);
ctx.fill();
ctx.strokeStyle = 'rgba(255,255,255,0.2)';
ctx.lineWidth = 1;
this.roundRect(ctx, padding, row3Y, buttonWidth, buttonHeight, 19);
ctx.stroke();
ctx.fillStyle = '#ffffff';
ctx.font = '12px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('从头开始', padding + buttonWidth / 2, row3Y + 24);
// 返回首页
ctx.fillStyle = 'rgba(255,255,255,0.1)';
this.roundRect(ctx, padding + buttonWidth + buttonMargin, row3Y, buttonWidth, buttonHeight, 19);
ctx.fill();
ctx.strokeStyle = 'rgba(255,255,255,0.2)';
this.roundRect(ctx, padding + buttonWidth + buttonMargin, row3Y, buttonWidth, buttonHeight, 19);
ctx.stroke();
ctx.fillStyle = '#ffffff';
ctx.fillText('返回首页', padding + buttonWidth + buttonMargin + buttonWidth / 2, row3Y + 24);
// 点赞和收藏
const actionY = row3Y + buttonHeight + 18;
const centerX = this.screenWidth / 2;
ctx.font = '20px sans-serif';
ctx.textAlign = 'center';
ctx.fillText(this.isLiked ? '❤️' : '🤍', centerX - 40, actionY);
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.font = '10px sans-serif';
ctx.fillText('点赞', centerX - 40, actionY + 16);
ctx.font = '20px sans-serif';
ctx.fillText(this.isCollected ? '⭐' : '☆', centerX + 40, actionY);
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.font = '10px sans-serif';
ctx.fillText('收藏', centerX + 40, actionY + 16);
}
renderGradientButton(ctx, x, y, width, height, text, colors) {
const gradient = ctx.createLinearGradient(x, y, x + width, y);
gradient.addColorStop(0, colors[0]);
gradient.addColorStop(1, colors[1]);
ctx.fillStyle = gradient;
this.roundRect(ctx, x, y, width, height, 22);
ctx.fill();
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 14px sans-serif';
ctx.textAlign = 'center';
ctx.fillText(text, x + width / 2, y + height / 2 + 5);
}
renderRewritePanel(ctx) {
const padding = 20;
const panelWidth = this.screenWidth - padding * 2;
const panelHeight = 380;
const panelX = padding;
const panelY = (this.screenHeight - panelHeight) / 2;
// 遮罩层
ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
ctx.fillRect(0, 0, this.screenWidth, this.screenHeight);
// 面板背景渐变
const panelGradient = ctx.createLinearGradient(panelX, panelY, panelX, panelY + panelHeight);
panelGradient.addColorStop(0, '#1a1a3e');
panelGradient.addColorStop(1, '#0d0d1a');
ctx.fillStyle = panelGradient;
this.roundRect(ctx, panelX, panelY, panelWidth, panelHeight, 20);
ctx.fill();
// 面板边框渐变
const borderGradient = ctx.createLinearGradient(panelX, panelY, panelX + panelWidth, panelY);
borderGradient.addColorStop(0, '#a855f7');
borderGradient.addColorStop(1, '#ec4899');
ctx.strokeStyle = borderGradient;
ctx.lineWidth = 2;
this.roundRect(ctx, panelX, panelY, panelWidth, panelHeight, 20);
ctx.stroke();
// 标题
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 18px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('✨ AI改写结局', this.screenWidth / 2, panelY + 35);
// 副标题
ctx.fillStyle = 'rgba(255,255,255,0.6)';
ctx.font = '12px sans-serif';
ctx.fillText('输入你想要的剧情走向AI将为你重新创作', this.screenWidth / 2, panelY + 58);
// 分隔线
const lineGradient = ctx.createLinearGradient(panelX + 20, panelY + 75, panelX + panelWidth - 20, panelY + 75);
lineGradient.addColorStop(0, 'transparent');
lineGradient.addColorStop(0.5, 'rgba(168,85,247,0.5)');
lineGradient.addColorStop(1, 'transparent');
ctx.strokeStyle = lineGradient;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(panelX + 20, panelY + 75);
ctx.lineTo(panelX + panelWidth - 20, panelY + 75);
ctx.stroke();
// 快捷标签标题
ctx.fillStyle = 'rgba(255,255,255,0.8)';
ctx.font = '13px sans-serif';
ctx.textAlign = 'left';
ctx.fillText('快捷选择:', panelX + 15, panelY + 105);
// 快捷标签
const tagStartX = panelX + 15;
const tagY = panelY + 120;
const tagHeight = 32;
const tagGap = 8;
let currentX = tagStartX;
let currentY = tagY;
this.tagRects = [];
this.rewriteTags.forEach((tag, index) => {
ctx.font = '12px sans-serif';
const tagWidth = ctx.measureText(tag).width + 24;
// 换行
if (currentX + tagWidth > panelX + panelWidth - 15) {
currentX = tagStartX;
currentY += tagHeight + tagGap;
}
// 标签背景
const isSelected = index === this.selectedTag;
if (isSelected) {
const tagGradient = ctx.createLinearGradient(currentX, currentY, currentX + tagWidth, currentY);
tagGradient.addColorStop(0, '#a855f7');
tagGradient.addColorStop(1, '#ec4899');
ctx.fillStyle = tagGradient;
} else {
ctx.fillStyle = 'rgba(255,255,255,0.1)';
}
this.roundRect(ctx, currentX, currentY, tagWidth, tagHeight, 16);
ctx.fill();
// 标签边框
ctx.strokeStyle = isSelected ? 'transparent' : 'rgba(255,255,255,0.2)';
ctx.lineWidth = 1;
this.roundRect(ctx, currentX, currentY, tagWidth, tagHeight, 16);
ctx.stroke();
// 标签文字
ctx.fillStyle = '#ffffff';
ctx.textAlign = 'center';
ctx.fillText(tag, currentX + tagWidth / 2, currentY + 21);
// 存储标签位置
this.tagRects.push({ x: currentX, y: currentY, width: tagWidth, height: tagHeight, index });
currentX += tagWidth + tagGap;
});
// 自定义输入提示
ctx.fillStyle = 'rgba(255,255,255,0.8)';
ctx.font = '13px sans-serif';
ctx.textAlign = 'left';
ctx.fillText('或自定义输入:', panelX + 15, panelY + 215);
// 输入框背景
const inputY = panelY + 230;
const inputHeight = 45;
ctx.fillStyle = 'rgba(255,255,255,0.08)';
this.roundRect(ctx, panelX + 15, inputY, panelWidth - 30, inputHeight, 12);
ctx.fill();
ctx.strokeStyle = 'rgba(255,255,255,0.2)';
ctx.lineWidth = 1;
this.roundRect(ctx, panelX + 15, inputY, panelWidth - 30, inputHeight, 12);
ctx.stroke();
// 输入框文字或占位符
ctx.font = '14px sans-serif';
ctx.textAlign = 'left';
if (this.rewritePrompt) {
ctx.fillStyle = '#ffffff';
ctx.fillText(this.rewritePrompt, panelX + 28, inputY + 28);
} else {
ctx.fillStyle = 'rgba(255,255,255,0.4)';
ctx.fillText('点击输入你的改写想法...', panelX + 28, inputY + 28);
}
// 按钮
const btnY = panelY + panelHeight - 70;
const btnWidth = (panelWidth - 50) / 2;
const btnHeight = 44;
// 取消按钮
ctx.fillStyle = 'rgba(255,255,255,0.1)';
this.roundRect(ctx, panelX + 15, btnY, btnWidth, btnHeight, 22);
ctx.fill();
ctx.strokeStyle = 'rgba(255,255,255,0.3)';
ctx.lineWidth = 1;
this.roundRect(ctx, panelX + 15, btnY, btnWidth, btnHeight, 22);
ctx.stroke();
ctx.fillStyle = '#ffffff';
ctx.font = '14px sans-serif';
ctx.textAlign = 'center';
ctx.fillText('取消', panelX + 15 + btnWidth / 2, btnY + 28);
// 确认按钮
const confirmGradient = ctx.createLinearGradient(panelX + 35 + btnWidth, btnY, panelX + 35 + btnWidth * 2, btnY);
confirmGradient.addColorStop(0, '#a855f7');
confirmGradient.addColorStop(1, '#ec4899');
ctx.fillStyle = confirmGradient;
this.roundRect(ctx, panelX + 35 + btnWidth, btnY, btnWidth, btnHeight, 22);
ctx.fill();
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 14px sans-serif';
ctx.fillText('✨ 开始改写', panelX + 35 + btnWidth + btnWidth / 2, btnY + 28);
// 存储按钮区域
this.cancelBtnRect = { x: panelX + 15, y: btnY, width: btnWidth, height: btnHeight };
this.confirmBtnRect = { x: panelX + 35 + btnWidth, y: btnY, width: btnWidth, height: btnHeight };
this.inputRect = { x: panelX + 15, y: inputY, width: panelWidth - 30, height: inputHeight };
}
// 圆角矩形
roundRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
// 文字换行
wrapText(ctx, text, x, y, maxWidth, lineHeight) {
if (!text) return;
let line = '';
let lineY = y;
for (let char of text) {
const testLine = line + char;
if (ctx.measureText(testLine).width > maxWidth) {
ctx.fillText(line, x, lineY);
line = char;
lineY += lineHeight;
} else {
line = testLine;
}
}
ctx.fillText(line, x, lineY);
}
// 限制行数的文字换行
wrapTextLimited(ctx, text, x, y, maxWidth, lineHeight, maxLines) {
if (!text) return;
let line = '';
let lineY = y;
let lineCount = 0;
for (let i = 0; i < text.length; i++) {
const char = text[i];
const testLine = line + char;
if (ctx.measureText(testLine).width > maxWidth) {
lineCount++;
if (lineCount >= maxLines) {
// 最后一行加省略号
while (line.length > 0 && ctx.measureText(line + '...').width > maxWidth) {
line = line.slice(0, -1);
}
ctx.fillText(line + '...', x, lineY);
return;
}
ctx.fillText(line, x, lineY);
line = char;
lineY += lineHeight;
} else {
line = testLine;
}
}
ctx.fillText(line, x, lineY);
}
// 居中显示的限制行数文字换行
wrapTextCentered(ctx, text, centerX, y, maxWidth, lineHeight, maxLines) {
if (!text) return;
// 先分行
const lines = [];
let line = '';
for (let i = 0; i < text.length; i++) {
const char = text[i];
const testLine = line + char;
if (ctx.measureText(testLine).width > maxWidth) {
lines.push(line);
line = char;
if (lines.length >= maxLines) break;
} else {
line = testLine;
}
}
if (line && lines.length < maxLines) {
lines.push(line);
}
// 如果超出行数,最后一行加省略号
if (lines.length >= maxLines && line) {
let lastLine = lines[maxLines - 1];
while (lastLine.length > 0 && ctx.measureText(lastLine + '...').width > maxWidth) {
lastLine = lastLine.slice(0, -1);
}
lines[maxLines - 1] = lastLine + '...';
}
// 居中绘制
lines.slice(0, maxLines).forEach((l, i) => {
ctx.fillText(l, centerX, y + i * lineHeight);
});
}
onTouchEnd(e) {
const touch = e.changedTouches[0];
const x = touch.clientX;
const y = touch.clientY;
// 如果改写面板打开,优先处理
if (this.showRewritePanel) {
this.handleRewritePanelTouch(x, y);
return;
}
if (!this.showButtons) return;
const padding = 15;
const buttonHeight = 38;
const buttonMargin = 8;
const startY = this.screenHeight - 220;
const buttonWidth = (this.screenWidth - padding * 2 - buttonMargin) / 2;
// AI改写按钮
if (this.isInRect(x, y, padding, startY, this.screenWidth - padding * 2, buttonHeight)) {
this.handleAIRewrite();
return;
}
// 分享按钮
const row2Y = startY + buttonHeight + buttonMargin;
if (this.isInRect(x, y, padding, row2Y, buttonWidth, buttonHeight)) {
this.handleShare();
return;
}
// 章节选择按钮
if (this.isInRect(x, y, padding + buttonWidth + buttonMargin, row2Y, buttonWidth, buttonHeight)) {
this.handleChapterSelect();
return;
}
// 从头开始
const row3Y = row2Y + buttonHeight + buttonMargin;
if (this.isInRect(x, y, padding, row3Y, buttonWidth, buttonHeight)) {
this.handleReplay();
return;
}
// 返回首页
if (this.isInRect(x, y, padding + buttonWidth + buttonMargin, row3Y, buttonWidth, buttonHeight)) {
this.main.sceneManager.switchScene('home');
return;
}
// 点赞收藏
const actionY = row3Y + buttonHeight + 18;
const centerX = this.screenWidth / 2;
if (this.isInRect(x, y, centerX - 70, actionY - 20, 60, 45)) {
this.handleLike();
return;
}
if (this.isInRect(x, y, centerX + 10, actionY - 20, 60, 45)) {
this.handleCollect();
return;
}
}
isInRect(x, y, rx, ry, rw, rh) {
return x >= rx && x <= rx + rw && y >= ry && y <= ry + rh;
}
handleShare() {
wx.shareAppMessage({
title: `我在《星域故事汇》达成了「${this.ending?.name}」结局!`,
imageUrl: '',
query: `storyId=${this.storyId}`
});
}
handleChapterSelect() {
this.main.sceneManager.switchScene('chapter', { storyId: this.storyId });
}
handleAIRewrite() {
// 显示AI改写面板
this.showRewritePanel = true;
this.rewritePrompt = '';
this.selectedTag = -1;
}
handleRewritePanelTouch(x, y) {
// 点击标签
if (this.tagRects) {
for (const tag of this.tagRects) {
if (this.isInRect(x, y, tag.x, tag.y, tag.width, tag.height)) {
this.selectedTag = tag.index;
this.rewritePrompt = this.rewriteTags[tag.index];
return true;
}
}
}
// 点击输入框
if (this.inputRect && this.isInRect(x, y, this.inputRect.x, this.inputRect.y, this.inputRect.width, this.inputRect.height)) {
this.showCustomInput();
return true;
}
// 点击取消
if (this.cancelBtnRect && this.isInRect(x, y, this.cancelBtnRect.x, this.cancelBtnRect.y, this.cancelBtnRect.width, this.cancelBtnRect.height)) {
this.showRewritePanel = false;
return true;
}
// 点击确认
if (this.confirmBtnRect && this.isInRect(x, y, this.confirmBtnRect.x, this.confirmBtnRect.y, this.confirmBtnRect.width, this.confirmBtnRect.height)) {
if (this.rewritePrompt) {
this.showRewritePanel = false;
this.callAIRewrite(this.rewritePrompt);
} else {
wx.showToast({ title: '请选择或输入改写内容', icon: 'none' });
}
return true;
}
return false;
}
showCustomInput() {
wx.showModal({
title: '输入改写想法',
editable: true,
placeholderText: '例如:让主角获得逆袭',
content: this.rewritePrompt,
success: (res) => {
if (res.confirm && res.content) {
this.rewritePrompt = res.content;
this.selectedTag = -1;
}
}
});
}
async callAIRewrite(prompt) {
wx.showLoading({ title: 'AI创作中...' });
try {
const result = await this.main.storyManager.rewriteEnding(
this.storyId,
this.ending,
prompt
);
wx.hideLoading();
if (result && result.content) {
// 跳转到故事场景播放新内容
this.main.sceneManager.switchScene('story', {
storyId: this.storyId,
aiContent: result
});
} else {
wx.showToast({ title: '改写失败,请重试', icon: 'none' });
}
} catch (error) {
wx.hideLoading();
wx.showToast({ title: '网络错误', icon: 'none' });
}
}
handleReplay() {
this.main.storyManager.resetStory();
this.main.sceneManager.switchScene('story', { storyId: this.storyId });
}
handleLike() {
this.isLiked = !this.isLiked;
this.main.userManager.likeStory(this.storyId, this.isLiked);
this.main.storyManager.likeStory(this.isLiked);
}
handleCollect() {
this.isCollected = !this.isCollected;
this.main.userManager.collectStory(this.storyId, this.isCollected);
}
}