diff --git a/Engine/src/data/segment.ts b/Engine/src/data/segment.ts index c38abf6..d10aa55 100644 --- a/Engine/src/data/segment.ts +++ b/Engine/src/data/segment.ts @@ -71,7 +71,8 @@ export class SegmentDecoration { export class SegmentZone { uuid: string points: [number, number][] = [] - type: 'solid'|'fluid' + type: 'solid'|'fluid'|'trigger' + event: string = '' constructor(o: any) { this.uuid = o.uuid this.points = o.points.map((v: any) => { @@ -79,6 +80,9 @@ export class SegmentZone { }) if (o.data.type === 'fluid') { this.type = o.data.type + } else if (o.data.type === 'trigger') { + this.type = 'trigger' + this.event = o.data.event } else { this.type = 'solid' } diff --git a/Engine/src/live/AnimalEntity.ts b/Engine/src/live/AnimalEntity.ts index 4b9be2a..eb60eb7 100644 --- a/Engine/src/live/AnimalEntity.ts +++ b/Engine/src/live/AnimalEntity.ts @@ -204,7 +204,7 @@ export class AnimalEntity extends Entity { this.desiredActions = adjustAction([], this.getCardinal(Math.random()*360), 1) } if (Math.random() > 1 - this.mode.noisiness) { - this.yell(0.25) + this.yell(0.1) } this.wanderTimer = 0 } diff --git a/Engine/src/live/Zone.ts b/Engine/src/live/Zone.ts index 2da4a7b..e74e778 100644 --- a/Engine/src/live/Zone.ts +++ b/Engine/src/live/Zone.ts @@ -3,11 +3,27 @@ import { SegmentZone } from '../data/segment' export class Zone { fixture: planck.Fixture|undefined - type: 'solid'|'fluid' + type: 'solid'|'fluid'|'trigger' points: [number, number][] + event: string = '' constructor(z: SegmentZone) { this.type = z.type this.points = z.points.map(v=>[v[0], v[1]]) + this.event = z.event + } + get bounds(): [number, number, number, number] { + let xs = this.points.map(v=>v[0]) + let ys = this.points.map(v=>v[1]) + let minX = Math.min(...xs) + let minY = Math.min(...ys) + let maxX = Math.max(...xs) + let maxY = Math.max(...ys) + return [ + minX, + minY, + maxX-minX, + maxY-maxY, + ] } } diff --git a/Engine/src/shared/audio.ts b/Engine/src/shared/audio.ts index 00221e5..dab061b 100644 --- a/Engine/src/shared/audio.ts +++ b/Engine/src/shared/audio.ts @@ -100,8 +100,6 @@ export function playSound(name: string, volume: number): HTMLAudioElement|undefi s.addEventListener('ended', () => { audioCache.push(s as HTMLAudioElement) }) - } else { - console.log('reused') } diff --git a/Engine/src/states/Game.ts b/Engine/src/states/Game.ts index a92e4da..c422c25 100644 --- a/Engine/src/states/Game.ts +++ b/Engine/src/states/Game.ts @@ -101,6 +101,7 @@ export function GameState(ctx: ContextI): StateI { let layers: Layer[] = [] let entities: Entity[] = [] let zones: Zone[] = [] + let spawnZones: Record = {} let enter = () => { lastTime = performance.now() @@ -174,18 +175,33 @@ export function GameState(ctx: ContextI): StateI { addZone(new Zone(z)) } - // Add player entity - player = new AnimalEntity(animals.deer) - player.isPlayer = true - addEntity(player, 'objects', 300, 100) + let playerSpawn = getSpawnZone('spawn') + if (!playerSpawn) { + // return to menu with an error? + } else { + let bounds = playerSpawn.bounds + let x = bounds[0] + Math.floor(Math.random() * bounds[2]) + let y = bounds[1] + Math.floor(Math.random() * bounds[3]) + // Add player entity + player = new AnimalEntity(animals.deer) + player.isPlayer = true + addEntity(player, 'objects', x, y) + } // Add fake others - addEntity(new AnimalEntity(animals.turkey), 'objects', 200, 200) - addEntity(new AnimalEntity(animals.nutria), 'objects', Math.random()*w.width, Math.random()*w.height) - addEntity(new AnimalEntity(animals.deer), 'objects', Math.random()*w.width, Math.random()*w.height) - addEntity(new AnimalEntity(animals.salamander), 'objects', Math.random()*w.width, Math.random()*w.height) - addEntity(new AnimalEntity(animals.rabbit), 'objects', Math.random()*w.width, Math.random()*w.height) + // MOVE ME + for (let animal of ['turkey','nutria','deer','salamander','rabbit']) { + let count = 2 + Math.floor(Math.random() * 8) + for (let i = 0; i < count; i++) { + let spawn = getSpawnZone(animal) + if (!spawn) break + let bounds = spawn.bounds + let x = bounds[0] + Math.floor(Math.random() * bounds[2]) + let y = bounds[1] + Math.floor(Math.random() * bounds[3]) + addEntity(new AnimalEntity(animals[animal]), 'objects', x, y) + } + } ctx.app.stage.addChild(rootContainer) } let leave = () => { @@ -211,9 +227,9 @@ export function GameState(ctx: ContextI): StateI { nightfall(true) } // Run world sim. - while (elapsed >= 1/60) { - world.step(1/60) - elapsed -= 1/60 + while (elapsed >= 1/5) { + world.step(1/5) + elapsed -= 1/5 } // Update/render. for (let layer of layers) { @@ -243,9 +259,7 @@ export function GameState(ctx: ContextI): StateI { } let addEntity = (entity: Entity, layerTitle: string, x: number, y: number) => { - console.log('add called with', x, y) if (entities.find(v=>v===entity)) return - console.log('add somethin', entity) entities.push(entity) let layer = layers.find(v=>v.title===layerTitle) if (!layer) layer = playLayer @@ -280,23 +294,26 @@ export function GameState(ctx: ContextI): StateI { defaultLong = entity.def.animal.scent defaultShort = entity.def.animal.sight } - // Create a short sensor (vision). - let senseFixture = body.createFixture({ - shape: planck.Circle(planck.Vec2(entity.x, entity.y), defaultShort), - isSensor: true, - }) - senseFixture.setUserData(new Sensor(entity, senseFixture, 'short')) - // Create a long sensor (scent). - let longSenseFixture = body.createFixture({ - shape: planck.Circle(planck.Vec2(entity.x, entity.y), defaultLong), - isSensor: true, - }) - longSenseFixture.setUserData(new Sensor(entity, longSenseFixture, 'long')) + if (entity instanceof AnimalEntity && !entity.isPlayer) { + // Create a short sensor (vision). + let senseFixture = body.createFixture({ + shape: planck.Circle(planck.Vec2(entity.x, entity.y), defaultShort), + isSensor: true, + filterGroupIndex: -8 + }) + senseFixture.setUserData(new Sensor(entity, senseFixture, 'short')) + // Create a long sensor (scent). + let longSenseFixture = body.createFixture({ + shape: planck.Circle(planck.Vec2(entity.x, entity.y), defaultLong), + isSensor: true, + filterGroupIndex: -8 + }) + longSenseFixture.setUserData(new Sensor(entity, longSenseFixture, 'long')) + } } } entity.x = x entity.y = y - console.log('set entity xy', entity.x, entity.y) } let removeEntity = (entity: Entity) => { entities = entities.filter(v=>v!==entity) @@ -310,14 +327,23 @@ export function GameState(ctx: ContextI): StateI { // Zonage let addZone = (zone: Zone) => { if (zones.find(v=>v===zone)) return - let shape = planck.Polygon(zone.points.map(v=>planck.Vec2(v[0],v[1]))) - zone.fixture = worldBody.createFixture({ - shape: shape, - }) - if (zone.type === 'fluid') { - zone.fixture.setSensor(true) + // We're using triggers for spawning due to laziness. + if (zone.type === 'trigger') { + if (!spawnZones[zone.event]) { + spawnZones[zone.event] = [] + } + spawnZones[zone.event].push(zone) + } else { + let shape = planck.Polygon(zone.points.map(v=>planck.Vec2(v[0],v[1]))) + zone.fixture = worldBody.createFixture({ + shape: shape, + }) + if (zone.type === 'fluid') { + zone.fixture.setSensor(true) + } + zone.fixture.setUserData(zone) } - zone.fixture.setUserData(zone) + zones.push(zone) } let removeZone = (zone: Zone) => { zones = zones.filter(v=>v!==zone) @@ -325,6 +351,12 @@ export function GameState(ctx: ContextI): StateI { worldBody.destroyFixture(zone.fixture) } } + let getSpawnZone = (name: string): Zone|undefined => { + if (!spawnZones[name] || !spawnZones[name].length) { + return undefined + } + return spawnZones[name][Math.floor(Math.random()*spawnZones[name].length)] + } let worldContext: WorldContext = { addEntity,