Files
text-adventure-game/App.vue
Claude cb412544e9 Initial commit: Text Adventure Game
Features:
- Combat system with AP/EP hit calculation and three-layer defense
- Auto-combat/farming mode
- Item system with stacking support
- Skill system with levels, milestones, and parent skill sync
- Shop system with dynamic pricing
- Inventory management with bulk selling
- Event system
- Game loop with offline earnings
- Save/Load system

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 17:13:51 +08:00

247 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
import { useGameStore } from '@/store/game.js'
import { usePlayerStore } from '@/store/player.js'
import {
saveGame,
loadGame,
resetGame as resetGameStorage,
hasSaveData
} from '@/utils/storage.js'
import {
startGameLoop,
stopGameLoop,
isGameLoopRunning,
calculateOfflineEarnings,
applyOfflineEarnings,
updateLastSaveTime,
refreshMarketPrices
} from '@/utils/gameLoop.js'
import { checkAndTriggerEvent } from '@/utils/eventSystem.js'
import { addItemToInventory } from '@/utils/itemSystem.js'
import { unlockSkill } from '@/utils/skillSystem.js'
// 记录应用隐藏时间(用于计算离线收益)
let appHideTime = Date.now()
onLaunch(() => {
try {
console.log('App Launch')
// 初始化Store
const gameStore = useGameStore()
const playerStore = usePlayerStore()
// 设置自动保存触发器
gameStore.triggerAutoSave = () => {
performAutoSave()
}
// 设置事件触发器
gameStore.triggerEvent = (type, context) => {
checkAndTriggerEvent(gameStore, playerStore, type, context)
}
// 加载存档
const loadResult = loadGame(gameStore, playerStore)
if (loadResult.success) {
// 存档加载成功
console.log('Save loaded, version:', loadResult.version)
// 添加欢迎日志
gameStore.addLog('欢迎回来!', 'info')
// 初始化市场价格(如果需要)
if (gameStore.gameTime.day !== gameStore.marketPrices.lastRefreshDay) {
refreshMarketPrices(gameStore)
}
} else if (loadResult.isNewGame) {
// 新游戏
console.log('Starting new game')
initializeNewGame(gameStore, playerStore)
} else {
// 加载失败,重置游戏
console.error('Load failed, resetting game')
resetGameStorage(gameStore, playerStore)
initializeNewGame(gameStore, playerStore)
}
// 启动游戏循环
startGameLoop(gameStore, playerStore)
// 更新保存时间
updateLastSaveTime()
} catch (error) {
console.error('App Launch failed:', error)
// 可以在这里显示友好的错误提示
}
})
onShow(() => {
console.log('App Show')
const gameStore = useGameStore()
const playerStore = usePlayerStore()
// 检查离线收益
checkOfflineEarnings(gameStore, playerStore)
// 确保游戏循环正在运行
if (!isGameLoopRunning()) {
startGameLoop(gameStore, playerStore)
}
})
onHide(() => {
console.log('App Hide')
const gameStore = useGameStore()
const playerStore = usePlayerStore()
// 记录隐藏时间
appHideTime = Date.now()
// 自动保存
performAutoSave()
// 停止游戏循环
stopGameLoop()
})
/**
* 初始化新游戏
* @param {Object} gameStore - 游戏Store
* @param {Object} playerStore - 玩家Store
*/
function initializeNewGame(gameStore, playerStore) {
// 重置所有数据
resetGameStorage(gameStore, playerStore)
// 给予初始货币
playerStore.currency.copper = 500 // 500铜币 = 5银币
// 给予初始物品
addItemToInventory(playerStore, 'wooden_stick', 1)
addItemToInventory(playerStore, 'bread', 5)
// 解锁木棍精通技能
unlockSkill(playerStore, 'stick_mastery')
// 添加欢迎日志
gameStore.addLog('欢迎来到荒野求生!', 'info')
gameStore.addLog('你在营地醒来,身边有一些铜币和物资...', 'story')
// 初始化市场价格
refreshMarketPrices(gameStore)
// 触发初始事件
checkAndTriggerEvent(gameStore, playerStore, 'enter', { locationId: 'camp' })
}
/**
* 检查并应用离线收益
* @param {Object} gameStore - 游戏Store
* @param {Object} playerStore - 玩家Store
*/
function checkOfflineEarnings(gameStore, playerStore) {
const now = Date.now()
const offlineSeconds = Math.floor((now - appHideTime) / 1000)
// 离线时间不足1分钟不计算收益
if (offlineSeconds < 60) {
return
}
// 计算离线收益
const earnings = calculateOfflineEarnings(
gameStore,
playerStore,
offlineSeconds
)
// 应用离线收益
if (earnings && (Object.keys(earnings.skillExp || {}).length > 0 || earnings.currency > 0)) {
applyOfflineEarnings(gameStore, playerStore, earnings)
gameStore.addLog(`离线 ${earnings.timeDisplay} 期间获得了收益`, 'info')
}
// 更新隐藏时间,避免重复计算
appHideTime = now
}
/**
* 执行自动保存
* @returns {boolean} 是否保存成功
*/
function performAutoSave() {
const gameStore = useGameStore()
const playerStore = usePlayerStore()
const success = saveGame(gameStore, playerStore)
if (success) {
console.log('Auto-save completed')
} else {
console.error('Auto-save failed')
}
return success
}
/**
* 手动保存游戏(暴露给全局)
* @returns {boolean}
*/
window.manualSave = function () {
return performAutoSave()
}
/**
* 获取存档信息(暴露给全局)
* @returns {Object|null}
*/
window.getSaveInfo = function () {
const gameStore = useGameStore()
const playerStore = usePlayerStore()
return {
gameTime: gameStore.gameTime,
playerLevel: playerStore.level.current,
location: playerStore.currentLocation,
hasSave: hasSaveData()
}
}
/**
* 解锁木棍精通技能(用于测试)
*/
window.unlockStickSkill = function () {
const playerStore = usePlayerStore()
unlockSkill(playerStore, 'stick_mastery')
return 'stick_mastery unlocked'
}
</script>
<style lang="scss">
/* 全局样式 */
@import '@/uni.scss';
page {
background-color: $bg-primary;
color: $text-primary;
font-size: 28rpx;
line-height: 1.6;
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8rpx;
}
::-webkit-scrollbar-thumb {
background-color: $bg-tertiary;
border-radius: 4rpx;
}
</style>