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>
247 lines
5.7 KiB
Vue
247 lines
5.7 KiB
Vue
<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>
|