83 lines
2.5 KiB
JavaScript
83 lines
2.5 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
ENVIRONMENT_ISLANDS,
|
|
environmentWindAt,
|
|
semiRandomWindPattern,
|
|
velocityWithEnvironment,
|
|
} from '../src/environment-physics.js';
|
|
|
|
test('environment exposes collidable island geometry', () => {
|
|
assert.equal(ENVIRONMENT_ISLANDS.length, 2);
|
|
for (const island of ENVIRONMENT_ISLANDS) {
|
|
assert.ok(island.radius > 0);
|
|
assert.ok(island.turbulenceRadius > island.radius);
|
|
}
|
|
});
|
|
|
|
test('semi-random wind varies strength and direction across weather windows', () => {
|
|
const samples = [0, 16000, 32000, 48000, 64000]
|
|
.map((timeMs) => semiRandomWindPattern(timeMs));
|
|
|
|
const roundedStrengths = new Set(samples.map(({ strength }) => Math.round(strength * 10)));
|
|
const roundedHeadings = new Set(samples.map(({ angle }) => Math.round(angle * 10)));
|
|
|
|
assert.ok(roundedStrengths.size >= 3);
|
|
assert.ok(roundedHeadings.size >= 3);
|
|
for (const sample of samples) {
|
|
assert.ok(sample.strength >= 4 && sample.strength < 28);
|
|
}
|
|
});
|
|
|
|
test('semi-random wind changes smoothly instead of jumping each frame', () => {
|
|
const before = semiRandomWindPattern(15950);
|
|
const after = semiRandomWindPattern(16050);
|
|
const vector = ({ angle, strength }) => ({
|
|
x: Math.cos(angle) * strength,
|
|
y: Math.sin(angle) * strength,
|
|
});
|
|
const a = vector(before);
|
|
const b = vector(after);
|
|
|
|
assert.ok(Math.hypot(b.x - a.x, b.y - a.y) < 2.5);
|
|
});
|
|
|
|
test('ambient wind changes over time and remains bounded', () => {
|
|
const first = environmentWindAt({ x: 1200, y: 1200, timeMs: 0 });
|
|
const later = environmentWindAt({ x: 1200, y: 1200, timeMs: 24000 });
|
|
|
|
assert.ok(first.strength > 3 && first.strength < 30);
|
|
assert.ok(later.strength > 3 && later.strength < 30);
|
|
assert.notDeepEqual(
|
|
[Math.round(first.x * 100), Math.round(first.y * 100)],
|
|
[Math.round(later.x * 100), Math.round(later.y * 100)],
|
|
);
|
|
});
|
|
|
|
test('islands produce a local turbulence contribution', () => {
|
|
const island = ENVIRONMENT_ISLANDS[0];
|
|
const near = environmentWindAt({
|
|
x: island.x + island.radius + 20,
|
|
y: island.y,
|
|
timeMs: 6000,
|
|
});
|
|
const far = environmentWindAt({
|
|
x: island.x + island.turbulenceRadius + 300,
|
|
y: island.y,
|
|
timeMs: 6000,
|
|
});
|
|
|
|
assert.notEqual(
|
|
Math.round(near.strength * 100),
|
|
Math.round(far.strength * 100),
|
|
);
|
|
});
|
|
|
|
test('environment velocity adds wind according to exposure', () => {
|
|
const result = velocityWithEnvironment(100, -20, { x: 12, y: 8 }, 0.5);
|
|
|
|
assert.equal(result.x, 106);
|
|
assert.equal(result.y, -16);
|
|
});
|