feat: rewrite main.js with config-driven initialization
This commit is contained in:
+128
@@ -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);
|
||||
Reference in New Issue
Block a user