refactor: fsd 구조로 변환
This commit is contained in:
175
src/features/flight-starfield/model/starfieldModel.ts
Normal file
175
src/features/flight-starfield/model/starfieldModel.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
import { FLIGHT_STARFIELD_TUNING } from '@/shared/config/starfield';
|
||||
import { clamp, randomInRange } from '@/shared/lib/math/number';
|
||||
|
||||
import { FlightStar } from '@/features/flight-starfield/model/types';
|
||||
|
||||
export const getFlightStarCount = (width: number, height: number) => {
|
||||
const isMobile = width < FLIGHT_STARFIELD_TUNING.mobileBreakpoint;
|
||||
const min = isMobile
|
||||
? FLIGHT_STARFIELD_TUNING.starCount.mobile.min
|
||||
: FLIGHT_STARFIELD_TUNING.starCount.desktop.min;
|
||||
const max = isMobile
|
||||
? FLIGHT_STARFIELD_TUNING.starCount.mobile.max
|
||||
: FLIGHT_STARFIELD_TUNING.starCount.desktop.max;
|
||||
const byArea = Math.round((width * height) / FLIGHT_STARFIELD_TUNING.densityDivisor);
|
||||
|
||||
return clamp(byArea, min, max);
|
||||
};
|
||||
|
||||
export const createFlightVanishXJitter = () => {
|
||||
const sign = Math.random() < 0.5 ? -1 : 1;
|
||||
return (
|
||||
sign *
|
||||
randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.vanishXJitter.min,
|
||||
FLIGHT_STARFIELD_TUNING.vanishXJitter.max,
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const createFlightSpeed = () => {
|
||||
const tier = Math.random();
|
||||
|
||||
if (tier < FLIGHT_STARFIELD_TUNING.speedTiers.slow.chance) {
|
||||
return randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.speedTiers.slow.min,
|
||||
FLIGHT_STARFIELD_TUNING.speedTiers.slow.max,
|
||||
);
|
||||
}
|
||||
|
||||
if (tier < FLIGHT_STARFIELD_TUNING.speedTiers.medium.chance) {
|
||||
return randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.speedTiers.medium.min,
|
||||
FLIGHT_STARFIELD_TUNING.speedTiers.medium.max,
|
||||
);
|
||||
}
|
||||
|
||||
return randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.speedTiers.fast.min,
|
||||
FLIGHT_STARFIELD_TUNING.speedTiers.fast.max,
|
||||
);
|
||||
};
|
||||
|
||||
const createFlightVisualTier = () => {
|
||||
const highlight = Math.random() < FLIGHT_STARFIELD_TUNING.radius.highlightChance;
|
||||
const tailRoll = Math.random();
|
||||
const tailLength =
|
||||
tailRoll < FLIGHT_STARFIELD_TUNING.tail.pointChance
|
||||
? randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.tail.pointRange.min,
|
||||
FLIGHT_STARFIELD_TUNING.tail.pointRange.max,
|
||||
)
|
||||
: tailRoll < FLIGHT_STARFIELD_TUNING.tail.shortChance
|
||||
? randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.tail.shortRange.min,
|
||||
FLIGHT_STARFIELD_TUNING.tail.shortRange.max,
|
||||
)
|
||||
: randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.tail.longRange.min,
|
||||
FLIGHT_STARFIELD_TUNING.tail.longRange.max,
|
||||
);
|
||||
|
||||
return {
|
||||
radius: highlight
|
||||
? randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.radius.highlight.min,
|
||||
FLIGHT_STARFIELD_TUNING.radius.highlight.max,
|
||||
)
|
||||
: randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.radius.normal.min,
|
||||
FLIGHT_STARFIELD_TUNING.radius.normal.max,
|
||||
),
|
||||
alpha: highlight
|
||||
? randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.alpha.highlight.min,
|
||||
FLIGHT_STARFIELD_TUNING.alpha.highlight.max,
|
||||
)
|
||||
: randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.alpha.normal.min,
|
||||
FLIGHT_STARFIELD_TUNING.alpha.normal.max,
|
||||
),
|
||||
tailLength,
|
||||
};
|
||||
};
|
||||
|
||||
const createFlightSpawnRadius = (width: number, height: number) => {
|
||||
const roll = Math.random();
|
||||
const maxWideRadius = Math.min(
|
||||
Math.max(width, height) * FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.maxScaleOfViewport,
|
||||
FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.maxAbsolute,
|
||||
);
|
||||
const ringOuter = Math.min(
|
||||
FLIGHT_STARFIELD_TUNING.spawnRadius.ringRange.max,
|
||||
maxWideRadius,
|
||||
);
|
||||
|
||||
if (roll < FLIGHT_STARFIELD_TUNING.spawnRadius.centerChance) {
|
||||
return randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.spawnRadius.centerRange.min,
|
||||
FLIGHT_STARFIELD_TUNING.spawnRadius.centerRange.max,
|
||||
);
|
||||
}
|
||||
|
||||
if (roll < FLIGHT_STARFIELD_TUNING.spawnRadius.ringChance) {
|
||||
return randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.spawnRadius.ringRange.min,
|
||||
Math.max(FLIGHT_STARFIELD_TUNING.spawnRadius.ringRange.min, ringOuter),
|
||||
);
|
||||
}
|
||||
|
||||
return randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.min,
|
||||
Math.max(FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.min, maxWideRadius),
|
||||
);
|
||||
};
|
||||
|
||||
export const createFlightStar = ({
|
||||
width,
|
||||
height,
|
||||
isRespawn,
|
||||
}: {
|
||||
width: number;
|
||||
height: number;
|
||||
isRespawn: boolean;
|
||||
}): FlightStar => {
|
||||
const radius = createFlightSpawnRadius(width, height);
|
||||
const angle = randomInRange(0, Math.PI * 2);
|
||||
const visuals = createFlightVisualTier();
|
||||
|
||||
return {
|
||||
wx: Math.cos(angle) * radius,
|
||||
wy: Math.sin(angle) * radius,
|
||||
z: isRespawn
|
||||
? randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.zRange.respawn.min,
|
||||
FLIGHT_STARFIELD_TUNING.zRange.respawn.max,
|
||||
)
|
||||
: randomInRange(
|
||||
FLIGHT_STARFIELD_TUNING.zRange.initial.min,
|
||||
FLIGHT_STARFIELD_TUNING.zRange.initial.max,
|
||||
),
|
||||
speed: createFlightSpeed(),
|
||||
radius: visuals.radius,
|
||||
alpha: visuals.alpha,
|
||||
tailLength: visuals.tailLength,
|
||||
};
|
||||
};
|
||||
|
||||
export const shouldRecycleFlightStar = ({
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
width,
|
||||
height,
|
||||
}: {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}) =>
|
||||
z <= FLIGHT_STARFIELD_TUNING.zRange.recycleThreshold ||
|
||||
x < -50 ||
|
||||
x > width + 50 ||
|
||||
y < -50 ||
|
||||
y > height + 50;
|
||||
Reference in New Issue
Block a user