From 690e6cbbf5019a887441ba71164cc32004dedc70 Mon Sep 17 00:00:00 2001 From: lpj <81079318+yruh@users.noreply.github.com> Date: Wed, 17 Dec 2025 22:15:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=90=8C=E6=AD=A5=20gameSpeed=20?= =?UTF-8?q?=E5=80=8D=E7=8E=87=E5=B1=95=E7=A4=BA=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E8=B5=84=E6=BA=90=E6=A0=8F=E9=81=AE?= =?UTF-8?q?=E6=8C=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 顶部资源栏/概览页:产量、能耗、明细按 gameSpeed 统一缩放,避免显示与实际产出不一致 - 支持 gameSpeed=0:避免 “|| 1” 抹掉 0,并在循环间隔计算中规避除 0 - 修复移动端资源横向滚动时被菜单按钮遮挡(min-w-0/overflow-hidden + 对齐规则) --- src/App.vue | 86 +++++++++++++++++++++----------------- src/logic/publicLogic.ts | 6 ++- src/logic/resourceLogic.ts | 61 +++++++++++++++++---------- src/utils/speed.ts | 28 +++++++++++++ src/views/OverviewView.vue | 11 +++-- src/views/SettingsView.vue | 6 +-- 6 files changed, 129 insertions(+), 69 deletions(-) create mode 100644 src/utils/speed.ts diff --git a/src/App.vue b/src/App.vue index d801e99..0ab5e89 100644 --- a/src/App.vue +++ b/src/App.vue @@ -200,41 +200,49 @@ - -
-
- -
- - - - -
-
-
+ + +
+
+
+ +
+ + + + +
+
+
+
@@ -407,6 +415,7 @@ import { DIPLOMATIC_CONFIG } from '@/config/gameConfig' import type { VersionInfo } from '@/utils/versionCheck' import { formatNumber, getResourceColor } from '@/utils/format' + import { getGameLoopIntervalMs, scaleNumber, scaleResources } from '@/utils/speed' import { Moon, Sun, @@ -1209,7 +1218,7 @@ clearInterval(gameLoop) } // 根据游戏速度计算间隔时间 - const interval = 1000 / (gameStore.gameSpeed || 1) + const interval = getGameLoopIntervalMs(gameStore.gameSpeed) // 启动新的游戏循环 gameLoop = setInterval(() => { updateGame() @@ -1410,11 +1419,12 @@ if (!planet.value) return null const now = Date.now() const bonuses = officerLogic.calculateActiveBonuses(gameStore.player.officers, now) - return resourceLogic.calculateResourceProduction(planet.value, { + const base = resourceLogic.calculateResourceProduction(planet.value, { resourceProductionBonus: bonuses.resourceProductionBonus, darkMatterProductionBonus: bonuses.darkMatterProductionBonus, energyProductionBonus: bonuses.energyProductionBonus }) + return scaleResources(base, gameStore.gameSpeed) }) const capacity = computed(() => { @@ -1427,7 +1437,7 @@ // 电力消耗 const energyConsumption = computed(() => { if (!planet.value) return 0 - return resourceLogic.calculateEnergyConsumption(planet.value) + return scaleNumber(resourceLogic.calculateEnergyConsumption(planet.value), gameStore.gameSpeed) }) // 净电力(产量 - 消耗) diff --git a/src/logic/publicLogic.ts b/src/logic/publicLogic.ts index 27b9a3b..dba4fa4 100644 --- a/src/logic/publicLogic.ts +++ b/src/logic/publicLogic.ts @@ -8,6 +8,7 @@ import type { Planet, Resources, Officer, BuildingConfig, TechnologyConfig } fro import { OfficerType } from '@/types/game' import * as officerLogic from '@/logic/officerLogic' import * as resourceLogic from '@/logic/resourceLogic' +import { scaleResources } from '@/utils/speed' /** * 获取特定等级的升级条件 @@ -93,11 +94,12 @@ export const checkRequirements = ( * @param officers 玩家的军官对象 * @returns 每小时各类资源的产量 */ -export const getResourceProduction = (planet: Planet, officers: Record): Resources => { +export const getResourceProduction = (planet: Planet, officers: Record, resourceSpeed: number = 1): Resources => { // 计算当前激活的军官加成 const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now()) // 根据建筑等级和军官加成计算资源产量 - return resourceLogic.calculateResourceProduction(planet, bonuses) + const base = resourceLogic.calculateResourceProduction(planet, bonuses) + return scaleResources(base, resourceSpeed) } /** diff --git a/src/logic/resourceLogic.ts b/src/logic/resourceLogic.ts index 4fe065e..42dc32f 100644 --- a/src/logic/resourceLogic.ts +++ b/src/logic/resourceLogic.ts @@ -249,7 +249,8 @@ export interface ConsumptionDetail { export const calculateProductionBreakdown = ( planet: Planet, officers: Record, - currentTime: number + currentTime: number, + resourceSpeed: number = 1 ): ProductionBreakdown => { const metalMineLevel = planet.buildings[BuildingType.MetalMine] || 0 const crystalMineLevel = planet.buildings[BuildingType.CrystalMine] || 0 @@ -435,42 +436,56 @@ export const calculateProductionBreakdown = ( const energyFinal = energyBase * (1 + totalEnergyBonus / 100) + const speed = resourceSpeed + + const scaleBonuses = (bonuses: ProductionBonus[]) => + bonuses.map(bonus => ({ + ...bonus, + value: bonus.value * speed + })) + + const scaleSources = (sources?: ProductionSource[]) => + sources?.map(source => ({ + ...source, + production: source.production * speed + })) + return { metal: { - baseProduction: metalBase, + baseProduction: metalBase * speed, buildingLevel: metalMineLevel, buildingName: 'buildings.metalMine', - bonuses: metalBonuses, - finalProduction: metalFinal + bonuses: scaleBonuses(metalBonuses), + finalProduction: metalFinal * speed }, crystal: { - baseProduction: crystalBase, + baseProduction: crystalBase * speed, buildingLevel: crystalMineLevel, buildingName: 'buildings.crystalMine', - bonuses: crystalBonuses, - finalProduction: crystalFinal + bonuses: scaleBonuses(crystalBonuses), + finalProduction: crystalFinal * speed }, deuterium: { - baseProduction: deuteriumBase, + baseProduction: deuteriumBase * speed, buildingLevel: deuteriumSynthesizerLevel, buildingName: 'buildings.deuteriumSynthesizer', - bonuses: deuteriumBonuses, - finalProduction: deuteriumFinal + bonuses: scaleBonuses(deuteriumBonuses), + finalProduction: deuteriumFinal * speed }, darkMatter: { - baseProduction: darkMatterBase, + baseProduction: darkMatterBase * speed, buildingLevel: darkMatterCollectorLevel, buildingName: 'buildings.darkMatterCollector', - bonuses: darkMatterBonuses, - finalProduction: darkMatterFinal + bonuses: scaleBonuses(darkMatterBonuses), + finalProduction: darkMatterFinal * speed }, energy: { - baseProduction: energyBase, + baseProduction: energyBase * speed, buildingLevel: solarPlantLevel, buildingName: 'buildings.solarPlant', - bonuses: energyBonuses, - finalProduction: energyFinal, - sources: energySources + bonuses: scaleBonuses(energyBonuses), + finalProduction: energyFinal * speed, + sources: scaleSources(energySources) } } } @@ -478,7 +493,7 @@ export const calculateProductionBreakdown = ( /** * 计算能量消耗详细breakdown */ -export const calculateConsumptionBreakdown = (planet: Planet): ConsumptionBreakdown => { +export const calculateConsumptionBreakdown = (planet: Planet, resourceSpeed: number = 1): ConsumptionBreakdown => { const metalMineLevel = planet.buildings[BuildingType.MetalMine] || 0 const crystalMineLevel = planet.buildings[BuildingType.CrystalMine] || 0 const deuteriumSynthesizerLevel = planet.buildings[BuildingType.DeuteriumSynthesizer] || 0 @@ -487,22 +502,24 @@ export const calculateConsumptionBreakdown = (planet: Planet): ConsumptionBreakd const crystalConsumption = crystalMineLevel * 10 * Math.pow(1.1, crystalMineLevel) const deuteriumConsumption = deuteriumSynthesizerLevel * 15 * Math.pow(1.1, deuteriumSynthesizerLevel) + const speed = resourceSpeed + return { metalMine: { buildingLevel: metalMineLevel, buildingName: 'buildings.metalMine', - consumption: metalConsumption + consumption: metalConsumption * speed }, crystalMine: { buildingLevel: crystalMineLevel, buildingName: 'buildings.crystalMine', - consumption: crystalConsumption + consumption: crystalConsumption * speed }, deuteriumSynthesizer: { buildingLevel: deuteriumSynthesizerLevel, buildingName: 'buildings.deuteriumSynthesizer', - consumption: deuteriumConsumption + consumption: deuteriumConsumption * speed }, - total: metalConsumption + crystalConsumption + deuteriumConsumption + total: (metalConsumption + crystalConsumption + deuteriumConsumption) * speed } } diff --git a/src/utils/speed.ts b/src/utils/speed.ts new file mode 100644 index 0000000..9f516d8 --- /dev/null +++ b/src/utils/speed.ts @@ -0,0 +1,28 @@ +import type { Resources } from '@/types/game' + +/** + * 按倍率缩放一个数值 + * - 支持合法的 0(例如用于“暂停”) + */ +export const scaleNumber = (value: number, multiplier: number): number => value * multiplier + +/** + * 按倍率缩放 Resources(常用于“每小时产量/消耗”等展示) + * - 支持合法的 0(例如用于“暂停”) + */ +export const scaleResources = (resources: Resources, multiplier: number): Resources => ({ + metal: resources.metal * multiplier, + crystal: resources.crystal * multiplier, + deuterium: resources.deuterium * multiplier, + darkMatter: resources.darkMatter * multiplier, + energy: resources.energy * multiplier +}) + +/** + * 计算游戏循环的间隔(毫秒) + * - multiplier <= 0 或非有限值时,回退到 baseMs,避免除 0 + */ +export const getGameLoopIntervalMs = (multiplier: number, baseMs: number = 1000): number => { + if (!Number.isFinite(multiplier) || multiplier <= 0) return baseMs + return baseMs / multiplier +} diff --git a/src/views/OverviewView.vue b/src/views/OverviewView.vue index 614bdd2..e9d6433 100644 --- a/src/views/OverviewView.vue +++ b/src/views/OverviewView.vue @@ -201,6 +201,7 @@ import { Badge } from '@/components/ui/badge' import ResourceIcon from '@/components/ResourceIcon.vue' import { formatNumber, getResourceColor } from '@/utils/format' + import { scaleNumber } from '@/utils/speed' import type { Planet } from '@/types/game' import * as publicLogic from '@/logic/publicLogic' import * as resourceLogic from '@/logic/resourceLogic' @@ -209,25 +210,27 @@ const { t } = useI18n() const { SHIPS } = useGameConfig() const planet = computed(() => gameStore.currentPlanet) - const production = computed(() => (planet.value ? publicLogic.getResourceProduction(planet.value, gameStore.player.officers) : null)) + const production = computed(() => + planet.value ? publicLogic.getResourceProduction(planet.value, gameStore.player.officers, gameStore.gameSpeed) : null + ) const capacity = computed(() => (planet.value ? publicLogic.getResourceCapacity(planet.value, gameStore.player.officers) : null)) // 能量消耗 const energyConsumption = computed(() => { if (!planet.value) return 0 - return resourceLogic.calculateEnergyConsumption(planet.value) + return scaleNumber(resourceLogic.calculateEnergyConsumption(planet.value), gameStore.gameSpeed) }) // 资源产量详细breakdown const productionBreakdown = computed(() => { if (!planet.value) return null - return resourceLogic.calculateProductionBreakdown(planet.value, gameStore.player.officers, Date.now()) + return resourceLogic.calculateProductionBreakdown(planet.value, gameStore.player.officers, Date.now(), gameStore.gameSpeed) }) // 资源消耗详细breakdown const consumptionBreakdown = computed(() => { if (!planet.value) return null - return resourceLogic.calculateConsumptionBreakdown(planet.value) + return resourceLogic.calculateConsumptionBreakdown(planet.value, gameStore.gameSpeed) }) // 资源类型配置 diff --git a/src/views/SettingsView.vue b/src/views/SettingsView.vue index 5c35ddd..e7a27cf 100644 --- a/src/views/SettingsView.vue +++ b/src/views/SettingsView.vue @@ -65,10 +65,10 @@

{{ t('settings.gameSpeed') }}

{{ t('settings.gameSpeedDesc') }}

-
-
+
+
- {{ gameStore.gameSpeed || 1 }}x + {{ gameStore.gameSpeed }}x