feat: rewrite main.js with config-driven initialization

This commit is contained in:
2026-05-13 04:27:27 +00:00
parent cd04cf6625
commit 4b56d70b22
+128
View File
@@ -0,0 +1,128 @@
// ==================== 游戏入口 ====================
import { createInitialState, resetForRebirth } from './engine/state.js';
import { setCareerConfig } from './engine/careerEngine.js';
import { setEventConfig } from './engine/eventEngine.js';
import { setShopConfig } from './engine/shopEngine.js';
import { startGameLoop, stopGameLoop, setSpeed } from './engine/tickLoop.js';
import { applyEffect } from './engine/effectApplier.js';
import { processDeath } from './engine/deathEngine.js';
import { evaluateCondition } from './engine/conditionEvaluator.js';
import { initRenderer, renderAll, showDeathScreen, hideChoiceEvent } from './ui/renderer.js';
const state = createInitialState();
// ==================== 配置加载 ====================
async function loadConfigs() {
const [careers, events, shop, identities, talents] = await Promise.all([
fetch('./src/config/careers.json').then(r => r.json()),
fetch('./src/config/events.json').then(r => r.json()),
fetch('./src/config/shop.json').then(r => r.json()),
fetch('./src/config/identities.json').then(r => r.json()),
fetch('./src/config/talents.json').then(r => r.json()),
]);
setCareerConfig(careers);
setEventConfig(events);
setShopConfig(shop);
return { careers, events, shop, identities, talents };
}
// ==================== 新游戏 ====================
function startNewGame(configs) {
resetForRebirth(state);
// 随机选择可用身份
const available = configs.identities.identities.filter(id => {
if (!id.unlockConditions || id.unlockConditions.length === 0) return true;
return id.unlockConditions.every(c => evaluateCondition(c, state));
});
const identity = available[Math.floor(Math.random() * available.length)];
state.identity = identity.id;
if (identity.startingStats) Object.assign(state.stats, identity.startingStats);
if (identity.startingItems) {
for (const itemId of identity.startingItems) {
applyEffect({ type: 'addItem', itemId }, state);
}
}
// 从已解锁词条池抽取(简化:先不实现)
startGameLoop(state, configs.careers, configs.events, configs.shop, () => {
renderAll(state, configs.careers, configs.shop);
});
}
// ==================== 选择事件处理 ====================
function handleChoice(choiceIndex) {
if (!state.currentEvent) return;
const choice = state.currentEvent.choices[choiceIndex];
if (!choice) return;
if (choice.effects) {
for (const effect of choice.effects) applyEffect(effect, state);
}
state.paused = false;
state.currentEvent = null;
hideChoiceEvent();
}
// ==================== UI事件绑定 ====================
function bindUIEvents() {
// 速度按钮
document.querySelectorAll('.speed-btn').forEach(btn => {
btn.addEventListener('click', () => {
const level = parseInt(btn.dataset.speed, 10);
setSpeed(state, level);
});
});
// 暂停按钮
const pauseBtn = document.getElementById('pause-btn');
if (pauseBtn) {
pauseBtn.addEventListener('click', () => {
state.paused = !state.paused;
});
}
// 选择按钮委托
const eventChoices = document.getElementById('event-choices');
if (eventChoices) {
eventChoices.addEventListener('click', (e) => {
const btn = e.target.closest('[data-index]');
if (!btn) return;
const idx = parseInt(btn.dataset.index, 10);
if (!isNaN(idx)) {
handleChoice(idx);
}
});
}
// 重生按钮(死亡界面)
document.addEventListener('click', (e) => {
if (e.target.id === 'rebirth-btn') {
location.reload();
}
});
}
// ==================== 主流程 ====================
async function init() {
const configs = await loadConfigs();
initRenderer();
bindUIEvents();
startNewGame(configs);
setInterval(() => {
if (!state.alive && state.deathReason) {
stopGameLoop();
processDeath(state, configs.careers, configs.talents);
showDeathScreen(state, configs.careers);
}
}, 500);
}
init().catch(console.error);