Skip to content

Commit b840ed4

Browse files
committed
refactor: actor spawn
1 parent 59718d9 commit b840ed4

11 files changed

Lines changed: 35 additions & 24 deletions

File tree

game/field.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as signal from "../util/signal.ts"
22
import { ceilN, floorN } from "../util/math.ts"
33
import { BLOCK_CHUNK_SIZE, BLOCK_SIZE, CELL_SIZE } from "../util/constants.ts"
44
import type {
5+
Dir,
56
IActor,
67
IField,
78
IItem,
@@ -10,7 +11,7 @@ import type {
1011
IStepper,
1112
LoadOptions,
1213
} from "../model/types.ts"
13-
import { Actor } from "../model/actor.ts"
14+
import { Actor, spawnActor } from "../model/actor.ts"
1415
import { Item } from "../model/item.ts"
1516
import { Prop } from "../model/prop.ts"
1617
import {
@@ -387,7 +388,6 @@ export class Field implements IField {
387388
#loadScope = new BlockLoadScope()
388389
#unloadScope = new BlockUnloadScope()
389390
#activateScope: RectScope
390-
#deactivateScope: RectScope
391391
#mapLoader = new BlockMapLoader(new URL("map/", location.href).href)
392392
#initialBlocksLoaded = false
393393
#initialActivateReady = false
@@ -405,7 +405,6 @@ export class Field implements IField {
405405
) {
406406
this.#el = el
407407
this.#activateScope = activateScope
408-
this.#deactivateScope = deactivateScope
409408
this.#actors = new FieldActors([], deactivateScope)
410409
this.#items = new FieldItems(deactivateScope)
411410
this.#props = new FieldProps(deactivateScope)
@@ -485,6 +484,29 @@ export class Field implements IField {
485484
this.#items.collect(i, j)
486485
}
487486

487+
// Spawns a new actor at the given grid coordinate
488+
// if the actor type is unavailable in the given block, returns null
489+
spawnActor(type: string, i: number, j: number, dir: Dir): IActor | null {
490+
const def = this.#getBlock(i, j).catalog.actors[type]
491+
492+
if (!def) {
493+
console.log("Unable to spawn actor of type:", type)
494+
return null
495+
}
496+
497+
const actor = spawnActor(
498+
`${i}.${j}.${type}.${crypto.randomUUID()}`,
499+
i,
500+
j,
501+
def,
502+
{ dir },
503+
)
504+
this.actors.add(actor)
505+
actor.loadAssets({ loadImage })
506+
507+
return actor
508+
}
509+
488510
#hasBlock(blockId: string) {
489511
return !!this.#blocks[blockId]
490512
}

model/field-block.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ export class FieldBlock {
498498
this.propSpawns = new SpawnMap(map.props)
499499
}
500500

501+
get catalog(): Catalog {
502+
return this.#map.catalog
503+
}
504+
501505
loadCellImage(href: string, options: LoadOptions): Promise<ImageBitmap> {
502506
return options.loadImage
503507
? options.loadImage(href)

model/item.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,13 @@ import { ItemDefinition } from "./catalog.ts"
44
import type { IActor, IField, IItem, ItemType, LoadOptions } from "./types.ts"
55
import { splashColor } from "../game/field.ts"
66
import { seed } from "../util/random.ts"
7-
import { spawnActor } from "./actor.ts"
8-
import { loadImage } from "../util/load.ts"
97
import { DIRS } from "../util/dir.ts"
108
import * as signal from "../util/signal.ts"
119

1210
const fallbackImage = await fetch(
1311
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAADRJREFUOE9jZKAQMFKon2FoGPAfzZsoribGC0PQALxORo92bGEwDAwgKXUTkw7wGjjwBgAAiwgIEW1Cnt4AAAAASUVORK5CYII=",
1412
).then((res) => res.blob()).then((blob) => createImageBitmap(blob))
1513

16-
const lenaDef = {
17-
type: "inertial" as const,
18-
moveEnd: "inertial" as const,
19-
src: "../actor/lena/",
20-
href: "./actor/lena/",
21-
}
22-
2314
export class Item implements IItem {
2415
/** The unique identifier of the item. Only items which are spawned from block map have ids. */
2516
readonly id: string | null
@@ -123,16 +114,9 @@ export class CollectApple implements CollectDelegate {
123114
for (const dir of DIRS) {
124115
if (dir === actor.dir) continue
125116
if (!actor.canGo(dir, field)) continue
126-
const actor_ = spawnActor(
127-
`${actor.i}.${actor.j}.inertial.${crypto.randomUUID()}`,
128-
actor.i,
129-
actor.j,
130-
lenaDef,
131-
{ dir },
132-
)
133-
actor_.loadAssets({ loadImage })
134-
actor_.enqueueActions({ type: "go", dir })
135-
field.actors.add(actor_)
117+
const spawned = field.spawnActor("inertial", actor.i, actor.j, dir)
118+
if (!spawned) continue
119+
spawned.enqueueActions({ type: "go", dir })
136120
}
137121

138122
const hue = 333.3

model/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export type IField = {
5050
/** can enter the cell without considering dynamic objects */
5151
canEnterStatic(i: number, j: number): boolean
5252
peekItem(i: number, j: number): IItem | undefined
53+
spawnActor(type: string, i: number, j: number, dir: Dir): IActor | null
5354
collectItem(i: number, j: number): void
5455
actors: {
5556
iter(): Iterable<IActor>

static/actor/boco/left0.png

25 Bytes
Loading

static/actor/boco/left1.png

32 Bytes
Loading

static/actor/boco/right0.png

25 Bytes
Loading

static/actor/boco/right1.png

32 Bytes
Loading

static/actor/boco/up0.png

25 Bytes
Loading

static/actor/boco/up1.png

32 Bytes
Loading

0 commit comments

Comments
 (0)