Scale meteor impacts by size
This commit is contained in:
parent
9df4f3dcde
commit
2c013247a9
7
agent.md
7
agent.md
|
|
@ -1,3 +1,10 @@
|
||||||
|
# Update: Variable Meteor Scale
|
||||||
|
|
||||||
|
- Fire and frost world-effect meteors now randomize their size on each drop.
|
||||||
|
- `WORLD_EFFECT.SIZE_SCALE_VARIANCE` controls the per-drop random range around the base size.
|
||||||
|
- The same random multiplier is applied to both the damage/frost zone bounds and the falling/impact sprite scale.
|
||||||
|
- Meteor screen shake scales from the same size multiplier, with base values in `WORLD_EFFECT.METEOR_SHAKE_DURATION_MS` and `WORLD_EFFECT.METEOR_SHAKE_INTENSITY`.
|
||||||
|
|
||||||
# Update: Team Size Constants
|
# Update: Team Size Constants
|
||||||
|
|
||||||
- The battle setup team-size limit is centralized in `SPAWN.MAX_TEAM_SIZE` inside `src/constants.js`.
|
- The battle setup team-size limit is centralized in `SPAWN.MAX_TEAM_SIZE` inside `src/constants.js`.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
# Update: Variable Meteor Scale
|
||||||
|
|
||||||
|
- `worldEffects.js` resolves a fresh size multiplier for every fire/frost meteor drop.
|
||||||
|
- Tune the base damage/frost zone with `WORLD_EFFECT.AREA_TILES`, the base sprite size with `WORLD_EFFECT.VISUAL_SCALE`, and the shared random spread with `WORLD_EFFECT.SIZE_SCALE_VARIANCE`.
|
||||||
|
- The same multiplier changes both the damage/frost zone bounds and the falling/impact sprite scale.
|
||||||
|
- Meteor impact shake uses the same size multiplier, scaling from `WORLD_EFFECT.METEOR_SHAKE_DURATION_MS` and `WORLD_EFFECT.METEOR_SHAKE_INTENSITY`.
|
||||||
|
|
||||||
# Update: Large Battle Targeting
|
# Update: Large Battle Targeting
|
||||||
|
|
||||||
- `combat.js` now prepares a per-frame target spatial index through `prepareCombatFrame(scene)`.
|
- `combat.js` now prepares a per-frame target spatial index through `prepareCombatFrame(scene)`.
|
||||||
|
|
@ -43,8 +50,8 @@
|
||||||
- **효과**: 메테오 투하 주기가 `SUDDEN_DEATH.INTERVAL_MS`로 단축되며, `FORCE_FROST` 설정 시 빙결 효과를 가진 냉기 메테오가 집중적으로 생성됩니다.
|
- **효과**: 메테오 투하 주기가 `SUDDEN_DEATH.INTERVAL_MS`로 단축되며, `FORCE_FROST` 설정 시 빙결 효과를 가진 냉기 메테오가 집중적으로 생성됩니다.
|
||||||
- **목적**: 장기전을 방지하고 전장에 무작위 변수를 극대화하여 물량 중심 팀에게 리스크를 부여합니다.
|
- **목적**: 장기전을 방지하고 전장에 무작위 변수를 극대화하여 물량 중심 팀에게 리스크를 부여합니다.
|
||||||
- **낙하 방향과 크기**: 대상이 전장 좌측 반면(2, 3사분면)이면 화살표가 좌상단에서 우하단으로, 우측 반면(1, 4사분면)이면 좌우 반전되어 우상단에서 좌하단으로 이동합니다. 스프라이트를 45도로 기울이고 전용 시각 배율을 사용해 전역 마법 규모로 표현합니다.
|
- **낙하 방향과 크기**: 대상이 전장 좌측 반면(2, 3사분면)이면 화살표가 좌상단에서 우하단으로, 우측 반면(1, 4사분면)이면 좌우 반전되어 우상단에서 좌하단으로 이동합니다. 스프라이트를 45도로 기울이고 전용 시각 배율을 사용해 전역 마법 규모로 표현합니다.
|
||||||
- **화염 메테오**: `world_Effect.png`의 7프레임 애니메이션이 낙하하면 화면 흔들림을 적용하고, 5x5 타일 영역의 생존자에게 고정 피해를 줍니다. 자동 관전 진입 전에는 `CAMERA.METEOR_FOCUS_ENABLED`가 켜져 있을 때 착탄 위치를 임시 포커싱합니다. 환경 피해로 인한 사망은 킬 보상을 지급하지 않지만 사망 통계와 승패 판정에는 반영됩니다.
|
- **화염 메테오**: `world_Effect.png`의 7프레임 애니메이션이 낙하하면 크기에 따른 화면 흔들림을 적용하고, 5x5 타일 영역의 생존자에게 고정 피해를 줍니다. 자동 관전 진입 전에는 `CAMERA.METEOR_FOCUS_ENABLED`가 켜져 있을 때 착탄 위치를 임시 포커싱합니다. 환경 피해로 인한 사망은 킬 보상을 지급하지 않지만 사망 통계와 승패 판정에는 반영됩니다.
|
||||||
- **냉기 메테오**: `world_Effect_2.png`의 7프레임 애니메이션으로 착탄을 표시하고, 자동 관전 진입 전에는 같은 설정에 따라 착탄 위치를 임시 포커싱합니다. 착탄 시 별도 조정 가능한 피해를 주며, 생존한 피격 대상은 캐릭터 본체와 실루엣이 얼음색으로 바뀐 채 2초 동안 기절합니다. 이후 남은 5x5 냉각지대 안에서는 공격속도와 이동속도 감속 배율을 적용하며, 영역을 벗어나거나 지속시간이 끝나면 배율을 복구합니다.
|
- **냉기 메테오**: `world_Effect_2.png`의 7프레임 애니메이션으로 착탄을 표시하고 크기에 따른 화면 흔들림을 적용하며, 자동 관전 진입 전에는 같은 설정에 따라 착탄 위치를 임시 포커싱합니다. 착탄 시 별도 조정 가능한 피해를 주며, 생존한 피격 대상은 캐릭터 본체와 실루엣이 얼음색으로 바뀐 채 2초 동안 기절합니다. 이후 남은 5x5 냉각지대 안에서는 공격속도와 이동속도 감속 배율을 적용하며, 영역을 벗어나거나 지속시간이 끝나면 배율을 복구합니다.
|
||||||
|
|
||||||
### 최종교전 슬로우모션
|
### 최종교전 슬로우모션
|
||||||
`COMBAT.FINAL_SLOW_MOTION_ENABLED`가 활성화된 경우:
|
`COMBAT.FINAL_SLOW_MOTION_ENABLED`가 활성화된 경우:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
# Context: Core & Infrastructure
|
# Context: Core & Infrastructure
|
||||||
|
|
||||||
|
# Update: Variable Meteor Scale
|
||||||
|
|
||||||
|
- `WORLD_EFFECT.SIZE_SCALE_VARIANCE` randomizes each fire/frost meteor drop around the base size.
|
||||||
|
- The randomized size applies to both the world-effect damage/frost zone bounds from `WORLD_EFFECT.AREA_TILES` and the sprite scale from `WORLD_EFFECT.VISUAL_SCALE`.
|
||||||
|
- Meteor impact shake strength follows the same size multiplier, using `WORLD_EFFECT.METEOR_SHAKE_DURATION_MS` and `WORLD_EFFECT.METEOR_SHAKE_INTENSITY` as base values.
|
||||||
|
|
||||||
# Update: Team Size Constants
|
# Update: Team Size Constants
|
||||||
|
|
||||||
- `SPAWN.MAX_TEAM_SIZE` is the single source of truth for the battle setup team-size maximum.
|
- `SPAWN.MAX_TEAM_SIZE` is the single source of truth for the battle setup team-size maximum.
|
||||||
|
|
@ -42,6 +48,6 @@
|
||||||
- **물리 수치 조정**: 역할별 기본 체력/속도/사거리/공격 수치는 `src/constants.js`의 `FIGHTER_TYPE_STATS`에서 변경하고, 특정 스킨만 다르게 할 때는 `fighterManifest.js`의 `stats` 또는 `combat` 설정을 사용하십시오.
|
- **물리 수치 조정**: 역할별 기본 체력/속도/사거리/공격 수치는 `src/constants.js`의 `FIGHTER_TYPE_STATS`에서 변경하고, 특정 스킨만 다르게 할 때는 `fighterManifest.js`의 `stats` 또는 `combat` 설정을 사용하십시오.
|
||||||
- **처치 성장 상한 조정**: 처치 보상으로 캐릭터가 커지는 최대치와 공격/이동 배율 상한은 `src/constants.js`의 `KILL_GROWTH_MAX_MULTIPLIER`를 수정합니다.
|
- **처치 성장 상한 조정**: 처치 보상으로 캐릭터가 커지는 최대치와 공격/이동 배율 상한은 `src/constants.js`의 `KILL_GROWTH_MAX_MULTIPLIER`를 수정합니다.
|
||||||
- **공격력 조정**: 역할별 기본 피해량은 `src/constants.js`의 `FIGHTER_TYPE_STATS.<type>.damageMin/damageMax`를 수정합니다. 캐릭터별 특수 공격 방식은 `fighterManifest.js`의 `combat` 설정을 우선 확인합니다.
|
- **공격력 조정**: 역할별 기본 피해량은 `src/constants.js`의 `FIGHTER_TYPE_STATS.<type>.damageMin/damageMax`를 수정합니다. 캐릭터별 특수 공격 방식은 `fighterManifest.js`의 `combat` 설정을 우선 확인합니다.
|
||||||
- **월드 이펙트 조정**: `src/constants.js`의 `WORLD_EFFECT.INTERVAL`, `WORLD_EFFECT.FALL_TRAVEL_TILES`, `WORLD_EFFECT.VISUAL_SCALE`, `WORLD_EFFECT.DOMINANCE_TARGETING_MULTIPLIER`, `WORLD_EFFECT.METEOR_DAMAGE`, `WORLD_EFFECT.FROST_DAMAGE`, `WORLD_EFFECT.FROST_STUN_DURATION`, `WORLD_EFFECT.FROST_STUN_TINT`, `WORLD_EFFECT.FROST_DURATION`, `WORLD_EFFECT.FROST_SPEED_MULTIPLIER`를 수정합니다. 독주 표적 배율은 `0`이면 기존 생존 유닛 비례 추첨이며, `1`이면 구매 배수 지분보다 높은 생존 지분의 초과분을 표적 가중치로 반영합니다. 임시 메테오 카메라는 `CAMERA.METEOR_FOCUS_ENABLED`로 끌 수 있습니다.
|
- **월드 이펙트 조정**: `src/constants.js`의 `WORLD_EFFECT.INTERVAL`, `WORLD_EFFECT.AREA_TILES`, `WORLD_EFFECT.SIZE_SCALE_VARIANCE`, `WORLD_EFFECT.FALL_TRAVEL_TILES`, `WORLD_EFFECT.VISUAL_SCALE`, `WORLD_EFFECT.METEOR_SHAKE_DURATION_MS`, `WORLD_EFFECT.METEOR_SHAKE_INTENSITY`, `WORLD_EFFECT.DOMINANCE_TARGETING_MULTIPLIER`, `WORLD_EFFECT.METEOR_DAMAGE`, `WORLD_EFFECT.FROST_DAMAGE`, `WORLD_EFFECT.FROST_STUN_DURATION`, `WORLD_EFFECT.FROST_STUN_TINT`, `WORLD_EFFECT.FROST_DURATION`, `WORLD_EFFECT.FROST_SPEED_MULTIPLIER`를 수정합니다. 독주 표적 배율은 `0`이면 기존 생존 유닛 비례 추첨이며, `1`이면 구매 배수 지분보다 높은 생존 지분의 초과분을 표적 가중치로 반영합니다. 임시 메테오 카메라는 `CAMERA.METEOR_FOCUS_ENABLED`로 끌 수 있습니다.
|
||||||
- **DOM 접근**: 성능을 위해 `ArenaScene`은 좌측 HUD badge 등 필요한 시점에만 최소한으로 DOM에 접근합니다.
|
- **DOM 접근**: 성능을 위해 `ArenaScene`은 좌측 HUD badge 등 필요한 시점에만 최소한으로 DOM에 접근합니다.
|
||||||
- **패키지 락 파일**: 이 프로젝트는 `package-lock.json`을 저장소에서 제외합니다. 의존성 변경 시 `package.json`을 기준으로 관리합니다.
|
- **패키지 락 파일**: 이 프로젝트는 `package-lock.json`을 저장소에서 제외합니다. 의존성 변경 시 `package.json`을 기준으로 관리합니다.
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,14 @@ export const PROJECTILE = {
|
||||||
export const WORLD_EFFECT = {
|
export const WORLD_EFFECT = {
|
||||||
INTERVAL: 4000,
|
INTERVAL: 4000,
|
||||||
AREA_TILES: 15,
|
AREA_TILES: 15,
|
||||||
|
SIZE_SCALE_VARIANCE: 3,
|
||||||
FRAMES: 7,
|
FRAMES: 7,
|
||||||
FRAME_RATE: 14,
|
FRAME_RATE: 14,
|
||||||
FALL_DURATION: 920,
|
FALL_DURATION: 920,
|
||||||
FALL_TRAVEL_TILES: 8,
|
FALL_TRAVEL_TILES: 8,
|
||||||
VISUAL_SCALE: 50,
|
VISUAL_SCALE: 50,
|
||||||
|
METEOR_SHAKE_DURATION_MS: 150,
|
||||||
|
METEOR_SHAKE_INTENSITY: 0.004,
|
||||||
// 0 keeps target selection proportional to living units.
|
// 0 keeps target selection proportional to living units.
|
||||||
// 1 adds pressure when a team's living share exceeds its paid spawn share.
|
// 1 adds pressure when a team's living share exceeds its paid spawn share.
|
||||||
DOMINANCE_TARGETING_MULTIPLIER: 0.5,
|
DOMINANCE_TARGETING_MULTIPLIER: 0.5,
|
||||||
|
|
@ -144,7 +147,7 @@ export const WORLD_EFFECT = {
|
||||||
FROST_DAMAGE: 45,
|
FROST_DAMAGE: 45,
|
||||||
FROST_STUN_DURATION: 2000,
|
FROST_STUN_DURATION: 2000,
|
||||||
FROST_STUN_TINT: 0x82e9ff,
|
FROST_STUN_TINT: 0x82e9ff,
|
||||||
FROST_DURATION: 20000,
|
FROST_DURATION: 2000,
|
||||||
FROST_SPEED_MULTIPLIER: 0.55,
|
FROST_SPEED_MULTIPLIER: 0.55,
|
||||||
SUDDEN_DEATH: {
|
SUDDEN_DEATH: {
|
||||||
ENABLED: false,
|
ENABLED: false,
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ function triggerWorldEffect(scene) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = chooseWorldEffectTarget(livingFighters);
|
const target = chooseWorldEffectTarget(livingFighters);
|
||||||
const zone = createEffectZone(target);
|
const zone = createEffectZone(target, resolveWorldEffectSizeScale());
|
||||||
|
|
||||||
// Sudden Death 상태이고 냉기 고정 설정이 되어있으면 무조건 냉기 메테오
|
// Sudden Death 상태이고 냉기 고정 설정이 되어있으면 무조건 냉기 메테오
|
||||||
if ((scene.isSuddenDeath && WORLD_EFFECT.SUDDEN_DEATH.FORCE_FROST) || Phaser.Math.Between(0, 1) === 0) {
|
if ((scene.isSuddenDeath && WORLD_EFFECT.SUDDEN_DEATH.FORCE_FROST) || Phaser.Math.Between(0, 1) === 0) {
|
||||||
|
|
@ -218,7 +218,7 @@ function spawnMeteor(scene, zone) {
|
||||||
onImpact: () => {
|
onImpact: () => {
|
||||||
scene.tweens.killTweensOf(marker);
|
scene.tweens.killTweensOf(marker);
|
||||||
marker.setAlpha(1);
|
marker.setAlpha(1);
|
||||||
scene.cameras.main.shake(150, 0.004);
|
applyMeteorImpactShake(scene, zone);
|
||||||
resolveImpactDamage(scene, zone, WORLD_EFFECT.METEOR_DAMAGE);
|
resolveImpactDamage(scene, zone, WORLD_EFFECT.METEOR_DAMAGE);
|
||||||
},
|
},
|
||||||
onAnimationComplete: () => {
|
onAnimationComplete: () => {
|
||||||
|
|
@ -239,6 +239,7 @@ function spawnFrostZone(scene, zone) {
|
||||||
disposeCombatObject(scene, marker);
|
disposeCombatObject(scene, marker);
|
||||||
},
|
},
|
||||||
onImpact: () => {
|
onImpact: () => {
|
||||||
|
applyMeteorImpactShake(scene, zone);
|
||||||
resolveImpactDamage(scene, zone, WORLD_EFFECT.FROST_DAMAGE, (fighter) => {
|
resolveImpactDamage(scene, zone, WORLD_EFFECT.FROST_DAMAGE, (fighter) => {
|
||||||
applyFrostStun(scene, fighter);
|
applyFrostStun(scene, fighter);
|
||||||
});
|
});
|
||||||
|
|
@ -261,7 +262,7 @@ function dropWorldEffectSprite(
|
||||||
const sprite = scene.add
|
const sprite = scene.add
|
||||||
.sprite(trajectory.startX, trajectory.startY, effectKey, 0)
|
.sprite(trajectory.startX, trajectory.startY, effectKey, 0)
|
||||||
.setDepth(3)
|
.setDepth(3)
|
||||||
.setScale(WORLD_EFFECT.VISUAL_SCALE)
|
.setScale(resolveWorldEffectVisualScale(zone))
|
||||||
.setFlipX(trajectory.flipX)
|
.setFlipX(trajectory.flipX)
|
||||||
.setAngle(trajectory.angle)
|
.setAngle(trajectory.angle)
|
||||||
.setAlpha(0.9);
|
.setAlpha(0.9);
|
||||||
|
|
@ -300,6 +301,40 @@ function worldEffectAnimationKey(effectKey) {
|
||||||
return `${effectKey}-anim`;
|
return `${effectKey}-anim`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveWorldEffectSizeScale() {
|
||||||
|
const variance = Math.max(0, Number(WORLD_EFFECT.SIZE_SCALE_VARIANCE) || 0);
|
||||||
|
|
||||||
|
if (variance === 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const minScale = Math.max(0.1, 1 - variance);
|
||||||
|
const maxScale = 1 + variance;
|
||||||
|
|
||||||
|
return Phaser.Math.FloatBetween(minScale, maxScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveWorldEffectVisualScale(zone) {
|
||||||
|
const baseScale = Math.max(0.01, Number(WORLD_EFFECT.VISUAL_SCALE) || 1);
|
||||||
|
return baseScale * Math.max(0.1, Number(zone?.sizeScale) || 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMeteorImpactShake(scene, zone) {
|
||||||
|
const sizeScale = Math.max(0.1, Number(zone?.sizeScale) || 1);
|
||||||
|
const duration = Math.round(
|
||||||
|
Math.max(0, Number(WORLD_EFFECT.METEOR_SHAKE_DURATION_MS) || 0)
|
||||||
|
* Math.sqrt(sizeScale),
|
||||||
|
);
|
||||||
|
const intensity =
|
||||||
|
Math.max(0, Number(WORLD_EFFECT.METEOR_SHAKE_INTENSITY) || 0) * sizeScale;
|
||||||
|
|
||||||
|
if (duration <= 0 || intensity <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene.cameras.main.shake(duration, intensity);
|
||||||
|
}
|
||||||
|
|
||||||
function createFallTrajectory(zone) {
|
function createFallTrajectory(zone) {
|
||||||
const distance = ARENA.TILE_SIZE * WORLD_EFFECT.FALL_TRAVEL_TILES;
|
const distance = ARENA.TILE_SIZE * WORLD_EFFECT.FALL_TRAVEL_TILES;
|
||||||
const isLeftHalf = zone.centerX < ARENA.SIZE / 2;
|
const isLeftHalf = zone.centerX < ARENA.SIZE / 2;
|
||||||
|
|
@ -313,16 +348,22 @@ function createFallTrajectory(zone) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEffectZone(target) {
|
function createEffectZone(target, sizeScale = 1) {
|
||||||
const size = ARENA.TILE_SIZE * WORLD_EFFECT.AREA_TILES;
|
const areaTiles = Math.max(
|
||||||
|
1,
|
||||||
|
(Number(WORLD_EFFECT.AREA_TILES) || 1) * Math.max(0.1, Number(sizeScale) || 1),
|
||||||
|
);
|
||||||
|
const size = ARENA.TILE_SIZE * areaTiles;
|
||||||
const centerX = target.body?.center.x ?? target.x;
|
const centerX = target.body?.center.x ?? target.x;
|
||||||
const centerY = target.body?.center.y ?? target.y;
|
const centerY = target.body?.center.y ?? target.y;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
areaTiles,
|
||||||
bounds: new Phaser.Geom.Rectangle(centerX - size / 2, centerY - size / 2, size, size),
|
bounds: new Phaser.Geom.Rectangle(centerX - size / 2, centerY - size / 2, size, size),
|
||||||
centerX,
|
centerX,
|
||||||
centerY,
|
centerY,
|
||||||
marker: null,
|
marker: null,
|
||||||
|
sizeScale,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -336,7 +377,7 @@ function createZoneMarker(scene, zone, color) {
|
||||||
marker.strokeRect(x, y, width, height);
|
marker.strokeRect(x, y, width, height);
|
||||||
marker.lineStyle(1, color, 0.34);
|
marker.lineStyle(1, color, 0.34);
|
||||||
|
|
||||||
for (let index = 1; index < WORLD_EFFECT.AREA_TILES; index += 1) {
|
for (let index = 1; index < zone.areaTiles; index += 1) {
|
||||||
const offset = index * ARENA.TILE_SIZE;
|
const offset = index * ARENA.TILE_SIZE;
|
||||||
marker.lineBetween(x + offset, y, x + offset, y + height);
|
marker.lineBetween(x + offset, y, x + offset, y + height);
|
||||||
marker.lineBetween(x, y + offset, x + width, y + offset);
|
marker.lineBetween(x, y + offset, x + width, y + offset);
|
||||||
|
|
|
||||||
8
todo.md
8
todo.md
|
|
@ -229,7 +229,7 @@
|
||||||
- **조치 사항**:
|
- **조치 사항**:
|
||||||
- 생존 캐릭터가 30명 미만이거나 최종 2팀만 남으면 후반 자동 줌과 교전 중심 포커싱이 시작되도록 관전 조건을 확장.
|
- 생존 캐릭터가 30명 미만이거나 최종 2팀만 남으면 후반 자동 줌과 교전 중심 포커싱이 시작되도록 관전 조건을 확장.
|
||||||
- 치명타의 `Critical!` 표기와 즉시 처치는 유지하면서 카메라 흔들림을 제거.
|
- 치명타의 `Critical!` 표기와 즉시 처치는 유지하면서 카메라 흔들림을 제거.
|
||||||
- 화염 메테오가 착탄할 때 화면 흔들림을 적용하고, 냉각지대 착탄과 피해 계산에서는 흔들림을 분리.
|
- 화염 메테오 착탄 화면 흔들림을 먼저 적용했으며, 이후 모든 메테오 착탄이 크기 기반 흔들림을 공유하도록 확장.
|
||||||
|
|
||||||
37. 자동 관전 이전 메테오 임시 포커싱 추가 (완료)
|
37. 자동 관전 이전 메테오 임시 포커싱 추가 (완료)
|
||||||
- **조치 사항**:
|
- **조치 사항**:
|
||||||
|
|
@ -285,3 +285,9 @@
|
||||||
- Added `FIGHTER.DEAD_DESPAWN_DELAY_MS` in `src/constants.js` so corpse lifetime is easy to tune.
|
- Added `FIGHTER.DEAD_DESPAWN_DELAY_MS` in `src/constants.js` so corpse lifetime is easy to tune.
|
||||||
- Updated `combat.js` to keep a dead fighter at initial opacity, fade it toward `FIGHTER.DEAD_DESPAWN_ALPHA`, then remove it from `scene.fighters` and destroy the sprite after the configured delay.
|
- Updated `combat.js` to keep a dead fighter at initial opacity, fade it toward `FIGHTER.DEAD_DESPAWN_ALPHA`, then remove it from `scene.fighters` and destroy the sprite after the configured delay.
|
||||||
- Kept death bookkeeping, kill rewards, split-on-death, and winner checks ahead of the despawn schedule.
|
- Kept death bookkeeping, kill rewards, split-on-death, and winner checks ahead of the despawn schedule.
|
||||||
|
|
||||||
|
46. Variable meteor impact and visual scale (completed)
|
||||||
|
- **Changes**:
|
||||||
|
- Added `WORLD_EFFECT.SIZE_SCALE_VARIANCE` so each fire/frost meteor drop can pick a different size multiplier.
|
||||||
|
- Updated `worldEffects.js` to apply the same per-drop multiplier to both the damage/frost zone bounds and the falling/impact sprite scale.
|
||||||
|
- Added `WORLD_EFFECT.METEOR_SHAKE_DURATION_MS` and `WORLD_EFFECT.METEOR_SHAKE_INTENSITY`, then scaled fire/frost meteor camera shake from the meteor size multiplier.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue