2022-01-29 01:37:01 -08:00
|
|
|
import { ContextI } from "../ContextI"
|
2022-01-29 03:44:34 -08:00
|
|
|
import { segments } from "../shared/segments"
|
2022-01-29 19:46:15 -08:00
|
|
|
import { audio, playSong, disableSound, enableSound } from '../shared/audio'
|
2022-01-29 01:37:01 -08:00
|
|
|
import { StateI } from "./StateI"
|
2022-01-29 03:44:34 -08:00
|
|
|
import * as PIXI from 'pixi.js'
|
2022-01-29 16:31:40 -08:00
|
|
|
import * as planck from 'planck'
|
2022-01-29 03:44:34 -08:00
|
|
|
import { DecorationInstance } from "../shared/decors"
|
2022-01-29 16:31:40 -08:00
|
|
|
import { SpriteInstance, sprites } from "../shared/sprites"
|
|
|
|
import { ShapeCircle, ShapePoints } from "../data/sprite"
|
2022-01-29 17:54:53 -08:00
|
|
|
import { SegmentZone } from "../data/segment"
|
2022-01-29 18:25:51 -08:00
|
|
|
import { Zone } from "../live/Zone"
|
2022-01-29 23:48:13 -08:00
|
|
|
import { Entity, Sensor } from "../live/Entity"
|
2022-01-29 22:39:20 -08:00
|
|
|
import { AnimalEntity, isAnimalEntity } from "../live/AnimalEntity"
|
2022-01-30 00:24:51 -08:00
|
|
|
import { Action, adjustAction } from "../live/Action"
|
2022-01-29 21:43:20 -08:00
|
|
|
import { WorldContext } from "../live/World"
|
2022-01-29 23:48:13 -08:00
|
|
|
import { animals } from "../data/animals"
|
2022-01-29 18:25:51 -08:00
|
|
|
|
2022-01-29 19:46:15 -08:00
|
|
|
export interface PIXIMissingColorMatrix extends PIXI.Filter {
|
|
|
|
night(intensity: number, multiply: boolean): void
|
|
|
|
contrast(amount: number, multiply: boolean): void
|
|
|
|
brightness(amount: number, multiply: boolean): void
|
|
|
|
saturate(amount: number, multiply: boolean): void
|
|
|
|
hue(rotation: number, multiply: boolean): void
|
|
|
|
colorTone(desaturation: number, toned: number, lightColor: number, darkColor: number, multiple: boolean): void
|
|
|
|
reset(): void
|
|
|
|
}
|
|
|
|
|
2022-01-29 18:25:51 -08:00
|
|
|
export interface Layer {
|
|
|
|
title: string
|
|
|
|
container: PIXI.Container
|
|
|
|
decorations: DecorationInstance[]
|
2022-01-29 19:46:15 -08:00
|
|
|
colorMatrix: PIXIMissingColorMatrix
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
2022-01-29 01:37:01 -08:00
|
|
|
|
|
|
|
export function GameState(ctx: ContextI): StateI {
|
2022-01-29 20:02:31 -08:00
|
|
|
//disableSound()
|
|
|
|
let isNight = false
|
|
|
|
let modeTimer = 0
|
2022-01-29 22:14:01 -08:00
|
|
|
let nightTime = 30 * 1000
|
|
|
|
let dayTime = 30 * 1000
|
2022-01-29 21:43:20 -08:00
|
|
|
let lastTime: number = performance.now()
|
2022-01-29 23:48:13 -08:00
|
|
|
let player: AnimalEntity
|
2022-01-29 20:02:31 -08:00
|
|
|
|
2022-01-29 16:31:40 -08:00
|
|
|
let world: planck.World = planck.World({
|
|
|
|
gravity: planck.Vec2(0, 0),
|
|
|
|
})
|
2022-01-29 17:54:53 -08:00
|
|
|
let worldBody: planck.Body = world.createBody({
|
|
|
|
type: 'static',
|
|
|
|
})
|
2022-01-29 21:43:20 -08:00
|
|
|
world.on('begin-contact', (contact: planck.Contact) => {
|
|
|
|
let a = contact.getFixtureA().getUserData()
|
|
|
|
let b = contact.getFixtureB().getUserData()
|
|
|
|
if (a instanceof Zone) {
|
|
|
|
if (b instanceof Entity) {
|
|
|
|
b.addZoneContact(a)
|
|
|
|
}
|
|
|
|
} else if (a instanceof Entity) {
|
|
|
|
if (b instanceof Entity) {
|
|
|
|
a.addEntityContact(b)
|
|
|
|
b.addEntityContact(a)
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 23:48:13 -08:00
|
|
|
if (a instanceof Sensor && a.entity instanceof AnimalEntity) {
|
|
|
|
if (b instanceof AnimalEntity) {
|
|
|
|
a.entity.sense(a, b)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (b instanceof Sensor && b.entity instanceof AnimalEntity) {
|
|
|
|
if (a instanceof AnimalEntity) {
|
|
|
|
b.entity.sense(b, a)
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 21:43:20 -08:00
|
|
|
})
|
|
|
|
world.on('end-contact', (contact: planck.Contact) => {
|
|
|
|
let a = contact.getFixtureA().getUserData()
|
|
|
|
let b = contact.getFixtureB().getUserData()
|
|
|
|
if (a instanceof Zone) {
|
|
|
|
if (b instanceof Entity) {
|
|
|
|
b.removeZoneContact(a)
|
|
|
|
}
|
|
|
|
} else if (a instanceof Entity) {
|
|
|
|
if (b instanceof Entity) {
|
|
|
|
a.removeEntityContact(b)
|
|
|
|
b.removeEntityContact(a)
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 23:48:13 -08:00
|
|
|
if (a instanceof Sensor && a.entity instanceof AnimalEntity) {
|
|
|
|
if (b instanceof AnimalEntity) {
|
|
|
|
a.entity.lost(a, b)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (b instanceof Sensor && b.entity instanceof AnimalEntity) {
|
|
|
|
if (a instanceof AnimalEntity) {
|
|
|
|
b.entity.lost(b, a)
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 21:43:20 -08:00
|
|
|
})
|
2022-01-29 01:37:01 -08:00
|
|
|
|
2022-01-29 03:44:34 -08:00
|
|
|
let rootContainer = new PIXI.Container()
|
2022-01-29 18:25:51 -08:00
|
|
|
let playLayer: Layer
|
|
|
|
let layers: Layer[] = []
|
2022-01-29 04:57:01 -08:00
|
|
|
let entities: Entity[] = []
|
2022-01-29 17:54:53 -08:00
|
|
|
let zones: Zone[] = []
|
2022-01-30 03:23:41 -08:00
|
|
|
let spawnZones: Record<string, Zone[]> = {}
|
2022-01-29 03:44:34 -08:00
|
|
|
|
2022-01-29 01:37:01 -08:00
|
|
|
let enter = () => {
|
2022-01-29 21:43:20 -08:00
|
|
|
lastTime = performance.now()
|
2022-01-29 04:57:01 -08:00
|
|
|
hookKeyboard()
|
2022-01-29 03:44:34 -08:00
|
|
|
// Load the world segment.
|
|
|
|
let w = segments.world
|
|
|
|
if (!w) return ctx.pop()
|
2022-01-30 00:37:11 -08:00
|
|
|
|
|
|
|
// Add our world border.
|
2022-01-30 00:39:02 -08:00
|
|
|
let borderShape = planck.Chain([planck.Vec2(0, 0), planck.Vec2(w.width, 0), planck.Vec2(w.width, w.height), planck.Vec2(0, w.height), planck.Vec2(0, 0)], true)
|
2022-01-30 00:37:11 -08:00
|
|
|
let borderFixture = worldBody.createFixture({
|
|
|
|
shape: borderShape,
|
|
|
|
})
|
|
|
|
|
2022-01-29 03:44:34 -08:00
|
|
|
rootContainer.width = w.width
|
|
|
|
rootContainer.height = w.height
|
|
|
|
rootContainer.scale.set(2, 2)
|
|
|
|
for (let l of w.layers) {
|
2022-01-29 18:25:51 -08:00
|
|
|
let layer: Layer = {
|
|
|
|
title: l.title,
|
|
|
|
container: new PIXI.Container(),
|
|
|
|
decorations: [],
|
2022-01-29 19:46:15 -08:00
|
|
|
colorMatrix: new PIXI.filters.ColorMatrixFilter()
|
2022-01-29 18:25:51 -08:00
|
|
|
}
|
2022-01-29 19:46:15 -08:00
|
|
|
layer.container.filters = [layer.colorMatrix]
|
2022-01-29 18:25:51 -08:00
|
|
|
layer.container.width = w.width
|
|
|
|
layer.container.height = w.height
|
|
|
|
|
|
|
|
if (l.title === 'objects') {
|
|
|
|
playLayer = layer
|
|
|
|
layer.container.sortableChildren = true
|
|
|
|
}
|
|
|
|
layers.push(layer)
|
2022-01-29 03:44:34 -08:00
|
|
|
|
|
|
|
for (let d of l.decorations) {
|
|
|
|
let di = new DecorationInstance(d.decor, d.decoration)
|
|
|
|
di.elapsed = d.timeOffset
|
|
|
|
di.container.x = d.x
|
|
|
|
di.container.y = d.y
|
2022-01-29 16:31:40 -08:00
|
|
|
if (d.rotation !== 0) {
|
|
|
|
di.container.angle = d.rotation
|
|
|
|
}
|
2022-01-29 03:44:34 -08:00
|
|
|
if (d.flip) {
|
|
|
|
di.container.pivot.y = 1
|
|
|
|
di.container.scale.y *= -1
|
2022-01-29 16:31:40 -08:00
|
|
|
if (d.rotation === 0) {
|
|
|
|
di.container.position.y--
|
|
|
|
}
|
2022-01-29 03:44:34 -08:00
|
|
|
}
|
|
|
|
if (d.mirror) {
|
|
|
|
di.container.pivot.x = 1
|
|
|
|
di.container.scale.x *= -1
|
|
|
|
di.container.position.x--
|
2022-01-29 16:31:40 -08:00
|
|
|
if (d.rotation !== 0) {
|
|
|
|
di.container.angle = -d.rotation
|
|
|
|
di.container.position.x++
|
|
|
|
di.container.position.y--
|
|
|
|
}
|
2022-01-29 03:44:34 -08:00
|
|
|
}
|
2022-01-29 18:25:51 -08:00
|
|
|
if (l.title === 'objects') {
|
|
|
|
di.container.zIndex = di.container.position.y + di.container.height/4
|
|
|
|
}
|
|
|
|
layer.container.addChild(di.container)
|
|
|
|
layer.decorations.push(di)
|
2022-01-29 03:44:34 -08:00
|
|
|
}
|
|
|
|
|
2022-01-29 18:25:51 -08:00
|
|
|
rootContainer.addChild(layer.container)
|
2022-01-29 03:44:34 -08:00
|
|
|
}
|
|
|
|
|
2022-01-29 17:54:53 -08:00
|
|
|
for (let z of w.zones) {
|
|
|
|
addZone(new Zone(z))
|
|
|
|
}
|
|
|
|
|
2022-01-30 03:23:41 -08:00
|
|
|
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)
|
|
|
|
}
|
2022-01-29 22:39:20 -08:00
|
|
|
|
|
|
|
// Add fake others
|
2022-01-30 03:23:41 -08:00
|
|
|
// 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])
|
2022-01-29 04:57:01 -08:00
|
|
|
|
2022-01-30 03:23:41 -08:00
|
|
|
addEntity(new AnimalEntity(animals[animal]), 'objects', x, y)
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 03:44:34 -08:00
|
|
|
ctx.app.stage.addChild(rootContainer)
|
2022-01-29 01:37:01 -08:00
|
|
|
}
|
|
|
|
let leave = () => {
|
2022-01-29 04:57:01 -08:00
|
|
|
unhookKeyboard()
|
|
|
|
for (let entity of entities) {
|
|
|
|
removeEntity(entity)
|
|
|
|
}
|
2022-01-29 03:44:34 -08:00
|
|
|
ctx.app.stage.removeChild(rootContainer)
|
2022-01-29 01:37:01 -08:00
|
|
|
}
|
2022-01-29 16:31:40 -08:00
|
|
|
let elapsed: number = 0
|
2022-01-29 01:37:01 -08:00
|
|
|
let update = (delta: number) => {
|
2022-01-29 21:43:20 -08:00
|
|
|
let time = performance.now()
|
|
|
|
let realDelta = time - lastTime
|
|
|
|
lastTime = time
|
2022-01-29 20:30:48 -08:00
|
|
|
checkGamepads()
|
2022-01-29 16:31:40 -08:00
|
|
|
elapsed += delta
|
2022-01-29 21:43:20 -08:00
|
|
|
modeTimer += realDelta
|
2022-01-29 20:02:31 -08:00
|
|
|
if (isNight && modeTimer >= nightTime) {
|
|
|
|
modeTimer = 0
|
|
|
|
nightfall(false)
|
|
|
|
} else if (!isNight && modeTimer >= dayTime) {
|
|
|
|
modeTimer = 0
|
|
|
|
nightfall(true)
|
|
|
|
}
|
2022-01-29 16:31:40 -08:00
|
|
|
// Run world sim.
|
2022-01-30 03:23:41 -08:00
|
|
|
while (elapsed >= 1/5) {
|
|
|
|
world.step(1/5)
|
|
|
|
elapsed -= 1/5
|
2022-01-29 16:31:40 -08:00
|
|
|
}
|
|
|
|
// Update/render.
|
2022-01-29 18:25:51 -08:00
|
|
|
for (let layer of layers) {
|
|
|
|
for (let decoration of layer.decorations) {
|
2022-01-29 21:43:20 -08:00
|
|
|
decoration.update(realDelta)
|
2022-01-29 18:25:51 -08:00
|
|
|
}
|
2022-01-29 03:44:34 -08:00
|
|
|
}
|
2022-01-29 04:57:01 -08:00
|
|
|
for (let entity of entities) {
|
2022-01-29 23:48:13 -08:00
|
|
|
if (isAnimalEntity(entity)) {
|
|
|
|
if (entity.isPlayer) {
|
|
|
|
entity.act(desiredActions)
|
|
|
|
// FIXME: This isn't the right place for this.
|
|
|
|
rootContainer.position.set(Math.round(ctx.app.renderer.width/2), Math.round(ctx.app.renderer.height/2))
|
|
|
|
rootContainer.pivot.set(Math.max(rootContainer.width/6, Math.min(entity.x, rootContainer.width/3)), Math.max(rootContainer.height/6, Math.min(entity.y, rootContainer.height/3)))
|
|
|
|
} else {
|
2022-01-30 00:24:51 -08:00
|
|
|
entity.think(realDelta)
|
2022-01-29 23:48:13 -08:00
|
|
|
}
|
2022-01-29 22:14:01 -08:00
|
|
|
} else {
|
|
|
|
//console.log('hmm, we do be tickin', entity, entity.x, entity.y)
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
2022-01-29 21:43:20 -08:00
|
|
|
entity.update(realDelta, worldContext)
|
2022-01-29 16:31:40 -08:00
|
|
|
// I guess...
|
|
|
|
entity.sprite.container.x = entity.x
|
|
|
|
entity.sprite.container.y = entity.y
|
2022-01-29 22:39:20 -08:00
|
|
|
entity.sprite.container.zIndex = entity.y + (entity.sprite.frame?entity.sprite.frame.originY??0:0)
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-29 22:14:01 -08:00
|
|
|
let addEntity = (entity: Entity, layerTitle: string, x: number, y: number) => {
|
2022-01-29 04:57:01 -08:00
|
|
|
if (entities.find(v=>v===entity)) return
|
|
|
|
entities.push(entity)
|
2022-01-29 22:14:01 -08:00
|
|
|
let layer = layers.find(v=>v.title===layerTitle)
|
|
|
|
if (!layer) layer = playLayer
|
|
|
|
layer.container.addChild(entity.sprite.container)
|
2022-01-29 16:31:40 -08:00
|
|
|
// I guess this is a fair enough place to create physics and add it to the entity.
|
|
|
|
let spriteShape = entity.sprite.getBodyShape()
|
|
|
|
if (spriteShape) {
|
|
|
|
let shape: planck.Shape|undefined
|
|
|
|
if (spriteShape instanceof ShapeCircle) {
|
|
|
|
shape = planck.Circle(planck.Vec2(spriteShape.x, spriteShape.y), spriteShape.radius)
|
|
|
|
} else if (spriteShape instanceof ShapePoints) {
|
|
|
|
shape = planck.Polygon(spriteShape.points.map(v=>planck.Vec2(v[0], v[1])))
|
|
|
|
}
|
|
|
|
if (shape !== undefined) {
|
|
|
|
let body = world.createDynamicBody({
|
|
|
|
position: planck.Vec2(entity.x, entity.y),
|
|
|
|
fixedRotation: true,
|
|
|
|
})
|
|
|
|
let fixture = body.createFixture({
|
|
|
|
shape,
|
|
|
|
density: 1,
|
|
|
|
friction: 0.9,
|
|
|
|
restitution: 0.05,
|
|
|
|
})
|
2022-01-29 21:43:20 -08:00
|
|
|
fixture.setUserData(entity)
|
2022-01-29 16:31:40 -08:00
|
|
|
entity.body = body
|
|
|
|
body.setUserData(entity)
|
2022-01-29 23:48:13 -08:00
|
|
|
// Sensors
|
|
|
|
let defaultShort = 50
|
|
|
|
let defaultLong = 100
|
|
|
|
if (entity instanceof AnimalEntity) {
|
|
|
|
defaultLong = entity.def.animal.scent
|
|
|
|
defaultShort = entity.def.animal.sight
|
|
|
|
}
|
2022-01-30 03:23:41 -08:00
|
|
|
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'))
|
|
|
|
}
|
2022-01-29 16:31:40 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
entity.x = x
|
|
|
|
entity.y = y
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
|
|
|
let removeEntity = (entity: Entity) => {
|
|
|
|
entities = entities.filter(v=>v!==entity)
|
2022-01-29 22:14:01 -08:00
|
|
|
entity.sprite.container.parent.removeChild(entity.sprite.container)
|
2022-01-29 16:31:40 -08:00
|
|
|
if (entity.body) {
|
|
|
|
world.destroyBody(entity.body)
|
|
|
|
entity.body = undefined
|
|
|
|
}
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
|
|
|
|
2022-01-29 17:54:53 -08:00
|
|
|
// Zonage
|
|
|
|
let addZone = (zone: Zone) => {
|
|
|
|
if (zones.find(v=>v===zone)) return
|
2022-01-30 03:23:41 -08:00
|
|
|
// 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)
|
2022-01-29 17:54:53 -08:00
|
|
|
}
|
2022-01-30 03:23:41 -08:00
|
|
|
zones.push(zone)
|
2022-01-29 17:54:53 -08:00
|
|
|
}
|
|
|
|
let removeZone = (zone: Zone) => {
|
|
|
|
zones = zones.filter(v=>v!==zone)
|
|
|
|
if (zone.fixture) {
|
|
|
|
worldBody.destroyFixture(zone.fixture)
|
|
|
|
}
|
|
|
|
}
|
2022-01-30 03:23:41 -08:00
|
|
|
let getSpawnZone = (name: string): Zone|undefined => {
|
|
|
|
if (!spawnZones[name] || !spawnZones[name].length) {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
return spawnZones[name][Math.floor(Math.random()*spawnZones[name].length)]
|
|
|
|
}
|
2022-01-29 17:54:53 -08:00
|
|
|
|
2022-01-29 21:43:20 -08:00
|
|
|
let worldContext: WorldContext = {
|
|
|
|
addEntity,
|
|
|
|
removeEntity,
|
|
|
|
}
|
|
|
|
|
2022-01-29 17:54:53 -08:00
|
|
|
let desiredActions: Action[] = []
|
2022-01-29 04:57:01 -08:00
|
|
|
let keyup = (e: KeyboardEvent) => {
|
|
|
|
if (e.key === 'ArrowLeft') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'west', 0)
|
2022-01-29 04:57:01 -08:00
|
|
|
} else if (e.key === 'ArrowRight') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'east', 0)
|
2022-01-29 04:57:01 -08:00
|
|
|
} else if (e.key === 'ArrowUp') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'north', 0)
|
2022-01-29 04:57:01 -08:00
|
|
|
} else if (e.key === 'ArrowDown') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'south', 0)
|
2022-01-30 01:01:27 -08:00
|
|
|
} else if (e.key === 'z' || e.key === 'Control') {
|
|
|
|
desiredActions = adjustAction(desiredActions, 'attack', 0)
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
let keydown = (e: KeyboardEvent) => {
|
|
|
|
if (e.repeat) return
|
|
|
|
if (e.key === 'ArrowLeft') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'west', 1)
|
2022-01-29 04:57:01 -08:00
|
|
|
} else if (e.key === 'ArrowRight') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'east', 1)
|
2022-01-29 04:57:01 -08:00
|
|
|
} else if (e.key === 'ArrowUp') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'north', 1)
|
2022-01-29 04:57:01 -08:00
|
|
|
} else if (e.key === 'ArrowDown') {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'south', 1)
|
2022-01-30 01:01:27 -08:00
|
|
|
} else if (e.key === 'z' || e.key === 'Control') {
|
|
|
|
desiredActions = adjustAction(desiredActions, 'attack', 2)
|
2022-01-29 04:57:01 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
let hookKeyboard = () => {
|
|
|
|
window.addEventListener('keyup', keyup)
|
|
|
|
window.addEventListener('keydown', keydown)
|
|
|
|
}
|
|
|
|
let unhookKeyboard = () => {
|
|
|
|
window.removeEventListener('keyup', keyup)
|
|
|
|
window.removeEventListener('keydown', keydown)
|
2022-01-29 01:37:01 -08:00
|
|
|
}
|
|
|
|
|
2022-01-29 20:30:48 -08:00
|
|
|
let gamepads: Record<string, Gamepad> = {}
|
|
|
|
window.addEventListener('gamepadconnected', (ev: GamepadEvent) => {
|
|
|
|
gamepads[ev.gamepad.id] = ev.gamepad
|
|
|
|
})
|
|
|
|
window.removeEventListener('gamepaddisconnected', (ev: GamepadEvent) => {
|
|
|
|
delete gamepads[ev.gamepad.id]
|
|
|
|
})
|
|
|
|
function checkGamepads() {
|
|
|
|
//for (let gp of Object.values(gamepads)) {
|
|
|
|
for (let gp of navigator.getGamepads()) {
|
|
|
|
if (!gp || !gp.connected) break
|
|
|
|
if (gp.axes[0] < 0) {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'west', Math.abs(gp.axes[0]))
|
2022-01-29 20:30:48 -08:00
|
|
|
} else if (gp.axes[0] > 0) {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'east', gp.axes[0])
|
2022-01-29 20:30:48 -08:00
|
|
|
} else {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'east', 0)
|
|
|
|
desiredActions = adjustAction(desiredActions, 'west', 0)
|
2022-01-29 20:30:48 -08:00
|
|
|
}
|
|
|
|
if (gp.axes[1] < 0) {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'north', Math.abs(gp.axes[1]))
|
2022-01-29 20:30:48 -08:00
|
|
|
} else if (gp.axes[1] > 0) {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'south', gp.axes[1])
|
2022-01-29 20:30:48 -08:00
|
|
|
} else {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'north', 0)
|
|
|
|
desiredActions = adjustAction(desiredActions, 'south', 0)
|
2022-01-29 20:30:48 -08:00
|
|
|
}
|
|
|
|
let attackHeld = false
|
|
|
|
for (let i = 0; i < 4; i++) {
|
|
|
|
let btn = gp.buttons[i]
|
|
|
|
if (btn.pressed) {
|
|
|
|
attackHeld = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (attackHeld) {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'attack', 2)
|
2022-01-29 20:30:48 -08:00
|
|
|
} else if (desiredActions.find(v=>v.type==='attack')) {
|
2022-01-30 00:24:51 -08:00
|
|
|
desiredActions = adjustAction(desiredActions, 'attack', 0)
|
2022-01-29 20:30:48 -08:00
|
|
|
}
|
|
|
|
}
|
2022-01-29 20:02:31 -08:00
|
|
|
}
|
|
|
|
|
2022-01-29 19:46:15 -08:00
|
|
|
let nightfall = (b: boolean) => {
|
|
|
|
if (b) {
|
2022-01-29 20:02:31 -08:00
|
|
|
playSong('GGJ-ScaryMusic')
|
2022-01-29 19:46:15 -08:00
|
|
|
for (let l of layers) {
|
|
|
|
//l.colorMatrix.brightness(0.25, false)
|
|
|
|
l.colorMatrix.night(0.2, true)
|
|
|
|
l.colorMatrix.saturate(-0.75, true)
|
|
|
|
//l.colorMatrix.hue(160, true)
|
|
|
|
}
|
|
|
|
for (let e of entities) {
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
playSong('GGJ-HappyMusic')
|
|
|
|
for (let l of layers) {
|
|
|
|
l.colorMatrix.reset()
|
|
|
|
}
|
|
|
|
for (let e of entities) {
|
|
|
|
}
|
|
|
|
}
|
2022-01-29 20:02:31 -08:00
|
|
|
isNight = b
|
2022-01-29 19:46:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
nightfall(false)
|
|
|
|
|
2022-01-29 01:37:01 -08:00
|
|
|
return {
|
|
|
|
enter,
|
|
|
|
leave,
|
|
|
|
update,
|
|
|
|
}
|
|
|
|
}
|