refactor spawners
This commit is contained in:
parent
110fe21a23
commit
ce06fa7c29
@ -2,7 +2,6 @@ import { Game } from ".";
|
|||||||
import { Miscellaneous, loadAssets } from "./config";
|
import { Miscellaneous, loadAssets } from "./config";
|
||||||
import {
|
import {
|
||||||
Player,
|
Player,
|
||||||
FunctionBox,
|
|
||||||
Wall,
|
Wall,
|
||||||
LambdaFactory,
|
LambdaFactory,
|
||||||
Key,
|
Key,
|
||||||
@ -14,8 +13,8 @@ import {
|
|||||||
FacingDirection,
|
FacingDirection,
|
||||||
Input,
|
Input,
|
||||||
Render,
|
Render,
|
||||||
LambdaFactory as LambdaFactorySpawnSystem,
|
|
||||||
Collision,
|
Collision,
|
||||||
|
GridSpawner,
|
||||||
} from "./systems";
|
} from "./systems";
|
||||||
|
|
||||||
export class TheAbstractionEngine {
|
export class TheAbstractionEngine {
|
||||||
@ -47,7 +46,7 @@ export class TheAbstractionEngine {
|
|||||||
height: Miscellaneous.GRID_CELL_HEIGHT,
|
height: Miscellaneous.GRID_CELL_HEIGHT,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
new LambdaFactorySpawnSystem(),
|
new GridSpawner(),
|
||||||
new Collision(),
|
new Collision(),
|
||||||
new Render(this.ctx),
|
new Render(this.ctx),
|
||||||
].forEach((system) => this.game.addSystem(system));
|
].forEach((system) => this.game.addSystem(system));
|
||||||
|
@ -8,6 +8,7 @@ export namespace ComponentNames {
|
|||||||
export const Interactable = "Interactable";
|
export const Interactable = "Interactable";
|
||||||
export const Pushable = "Pushable";
|
export const Pushable = "Pushable";
|
||||||
export const Colliding = "Colliding";
|
export const Colliding = "Colliding";
|
||||||
export const LambdaSpawn = "LambdaSpawn";
|
export const GridSpawn = "GridSpawn";
|
||||||
export const Text = "Text";
|
export const Text = "Text";
|
||||||
|
export const LambdaTerm = "LambdaTerm";
|
||||||
}
|
}
|
||||||
|
30
src/engine/components/GridSpawn.ts
Normal file
30
src/engine/components/GridSpawn.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Component, ComponentNames } from ".";
|
||||||
|
import { Entity } from "../entities";
|
||||||
|
import { Direction } from "../interfaces";
|
||||||
|
|
||||||
|
export class GridSpawn extends Component {
|
||||||
|
public direction: Direction;
|
||||||
|
public spawnsLeft: number;
|
||||||
|
public spawner: () => Entity;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
spawnsLeft: number,
|
||||||
|
spawner: () => Entity,
|
||||||
|
direction = Direction.NONE,
|
||||||
|
) {
|
||||||
|
super(ComponentNames.GridSpawn);
|
||||||
|
|
||||||
|
this.spawnsLeft = spawnsLeft;
|
||||||
|
this.direction = direction;
|
||||||
|
this.spawner = spawner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public spawnEntity(direction: Direction): Entity | undefined {
|
||||||
|
if (this.spawnsLeft === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.direction = direction;
|
||||||
|
this.spawnsLeft -= 1;
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
import { Component, ComponentNames } from ".";
|
|
||||||
import { Direction } from "../interfaces";
|
|
||||||
|
|
||||||
export class LambdaSpawn extends Component {
|
|
||||||
public direction: Direction | null;
|
|
||||||
public spawnsLeft: number;
|
|
||||||
public code: string = "";
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
spawnsLeft: number,
|
|
||||||
code: string,
|
|
||||||
direction: Direction | null = null,
|
|
||||||
) {
|
|
||||||
super(ComponentNames.LambdaSpawn);
|
|
||||||
|
|
||||||
this.spawnsLeft = spawnsLeft;
|
|
||||||
this.direction = direction;
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public spawn(direction: Direction) {
|
|
||||||
if (this.spawnsLeft <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.direction = direction;
|
|
||||||
this.spawnsLeft -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
11
src/engine/components/LambdaTerm.ts
Normal file
11
src/engine/components/LambdaTerm.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Component, ComponentNames } from ".";
|
||||||
|
|
||||||
|
export class LambdaTerm extends Component {
|
||||||
|
public code: string;
|
||||||
|
|
||||||
|
constructor(code: string) {
|
||||||
|
super(ComponentNames.LambdaTerm);
|
||||||
|
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
@ -9,5 +9,6 @@ export * from "./Highlight";
|
|||||||
export * from "./Interactable";
|
export * from "./Interactable";
|
||||||
export * from "./Pushable";
|
export * from "./Pushable";
|
||||||
export * from "./Colliding";
|
export * from "./Colliding";
|
||||||
export * from "./LambdaSpawn";
|
export * from "./GridSpawn";
|
||||||
export * from "./Text";
|
export * from "./Text";
|
||||||
|
export * from "./LambdaTerm";
|
||||||
|
@ -6,4 +6,5 @@ export namespace EntityNames {
|
|||||||
export const Key = "Key";
|
export const Key = "Key";
|
||||||
export const LockedDoor = "LockedDoor";
|
export const LockedDoor = "LockedDoor";
|
||||||
export const Curry = "Curry";
|
export const Curry = "Curry";
|
||||||
|
export const FunctionApplication = "FunctionApplication";
|
||||||
}
|
}
|
||||||
|
7
src/engine/entities/FunctionApplication.ts
Normal file
7
src/engine/entities/FunctionApplication.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { Entity, EntityNames } from ".";
|
||||||
|
|
||||||
|
export class FunctionApplication extends Entity {
|
||||||
|
constructor() {
|
||||||
|
super(EntityNames.FunctionApplication);
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import {
|
|||||||
Grid,
|
Grid,
|
||||||
Highlight,
|
Highlight,
|
||||||
Interactable,
|
Interactable,
|
||||||
|
LambdaTerm,
|
||||||
Pushable,
|
Pushable,
|
||||||
Sprite,
|
Sprite,
|
||||||
} from "../components";
|
} from "../components";
|
||||||
@ -23,13 +24,9 @@ export class FunctionBox extends Entity {
|
|||||||
Sprites.FUNCTION_BOX,
|
Sprites.FUNCTION_BOX,
|
||||||
) as SpriteSpec;
|
) as SpriteSpec;
|
||||||
|
|
||||||
private code: string;
|
|
||||||
|
|
||||||
constructor(gridPosition: Coord2D, code: string) {
|
constructor(gridPosition: Coord2D, code: string) {
|
||||||
super(EntityNames.FunctionBox);
|
super(EntityNames.FunctionBox);
|
||||||
|
|
||||||
this.code = code;
|
|
||||||
|
|
||||||
this.addComponent(
|
this.addComponent(
|
||||||
new BoundingBox(
|
new BoundingBox(
|
||||||
{
|
{
|
||||||
@ -61,20 +58,19 @@ export class FunctionBox extends Entity {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addComponent(
|
this.addComponent(new LambdaTerm(code));
|
||||||
new Highlight(
|
|
||||||
(_direction) => this.onHighlight(),
|
|
||||||
() => this.onUnhighlight(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private onUnhighlight() {
|
this.addComponent(makeLambdaTermHighlightComponent(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const makeLambdaTermHighlightComponent = (entity: Entity) => {
|
||||||
|
const onUnhighlight = () => {
|
||||||
closeModal();
|
closeModal();
|
||||||
this.removeComponent(ComponentNames.Interactable);
|
entity.removeComponent(ComponentNames.Interactable);
|
||||||
}
|
};
|
||||||
|
|
||||||
private onHighlight() {
|
const onHighlight = () => {
|
||||||
let modalOpen = false;
|
let modalOpen = false;
|
||||||
const interaction = () => {
|
const interaction = () => {
|
||||||
if (modalOpen) {
|
if (modalOpen) {
|
||||||
@ -82,10 +78,14 @@ export class FunctionBox extends Entity {
|
|||||||
closeModal();
|
closeModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modalOpen = true;
|
|
||||||
|
const code = entity.getComponent<LambdaTerm>(
|
||||||
|
ComponentNames.LambdaTerm,
|
||||||
|
)!.code;
|
||||||
openModal(
|
openModal(
|
||||||
`<div style="text-align:center"><p>${this.code}</p> <br> <button id="close">Close</button></div>`,
|
`<div style="text-align:center"><p>${code}</p> <br> <button id="close">Close</button></div>`,
|
||||||
);
|
);
|
||||||
|
modalOpen = true;
|
||||||
|
|
||||||
document.getElementById("close")!.addEventListener("click", () => {
|
document.getElementById("close")!.addEventListener("click", () => {
|
||||||
closeModal();
|
closeModal();
|
||||||
@ -93,6 +93,8 @@ export class FunctionBox extends Entity {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addComponent(new Interactable(interaction));
|
entity.addComponent(new Interactable(interaction));
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
return new Highlight(onHighlight, onUnhighlight);
|
||||||
|
};
|
||||||
|
@ -5,15 +5,15 @@ import {
|
|||||||
SpriteSpec,
|
SpriteSpec,
|
||||||
Sprites,
|
Sprites,
|
||||||
} from "../config";
|
} from "../config";
|
||||||
import { Entity, EntityNames } from ".";
|
import { Entity, EntityNames, FunctionBox } from ".";
|
||||||
import {
|
import {
|
||||||
BoundingBox,
|
BoundingBox,
|
||||||
Colliding,
|
Colliding,
|
||||||
ComponentNames,
|
ComponentNames,
|
||||||
Grid,
|
Grid,
|
||||||
|
GridSpawn,
|
||||||
Highlight,
|
Highlight,
|
||||||
Interactable,
|
Interactable,
|
||||||
LambdaSpawn,
|
|
||||||
Sprite,
|
Sprite,
|
||||||
Text,
|
Text,
|
||||||
} from "../components";
|
} from "../components";
|
||||||
@ -75,11 +75,13 @@ export class LambdaFactory extends Entity {
|
|||||||
|
|
||||||
private codeEditorState: CodeEditorState | null;
|
private codeEditorState: CodeEditorState | null;
|
||||||
private spawns: number;
|
private spawns: number;
|
||||||
|
private code: string;
|
||||||
|
|
||||||
constructor(gridPosition: Coord2D, code: string, spawns: number) {
|
constructor(gridPosition: Coord2D, code: string, spawns: number) {
|
||||||
super(EntityNames.LambdaFactory);
|
super(EntityNames.LambdaFactory);
|
||||||
|
|
||||||
this.spawns = spawns;
|
this.spawns = spawns;
|
||||||
|
this.code = code;
|
||||||
this.codeEditorState = null;
|
this.codeEditorState = null;
|
||||||
|
|
||||||
this.addComponent(
|
this.addComponent(
|
||||||
@ -100,7 +102,12 @@ export class LambdaFactory extends Entity {
|
|||||||
|
|
||||||
this.addComponent(new Colliding());
|
this.addComponent(new Colliding());
|
||||||
|
|
||||||
this.addComponent(new LambdaSpawn(this.spawns, code));
|
this.addComponent(
|
||||||
|
new GridSpawn(
|
||||||
|
this.spawns,
|
||||||
|
() => new FunctionBox({ x: 0, y: 0 }, this.code),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
this.addComponent(new Grid(gridPosition));
|
this.addComponent(new Grid(gridPosition));
|
||||||
|
|
||||||
@ -131,8 +138,8 @@ export class LambdaFactory extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private spawnNewLambda(direction: Direction) {
|
private spawnNewLambda(direction: Direction) {
|
||||||
const spawner = this.getComponent<LambdaSpawn>(ComponentNames.LambdaSpawn);
|
const spawner = this.getComponent<GridSpawn>(ComponentNames.GridSpawn);
|
||||||
spawner.spawn(direction);
|
spawner.spawnEntity(direction);
|
||||||
|
|
||||||
const text = this.getComponent<Text>(ComponentNames.Text);
|
const text = this.getComponent<Text>(ComponentNames.Text);
|
||||||
text.text = spawner.spawnsLeft.toString();
|
text.text = spawner.spawnsLeft.toString();
|
||||||
@ -144,9 +151,8 @@ export class LambdaFactory extends Entity {
|
|||||||
"<div class='code'><div id='code'></div><br><p id='syntax-error' class='error'></p><button id='close-modal'>Save</button></div>";
|
"<div class='code'><div id='code'></div><br><p id='syntax-error' class='error'></p><button id='close-modal'>Save</button></div>";
|
||||||
openModal(modalContent);
|
openModal(modalContent);
|
||||||
|
|
||||||
const { code } = this.getComponent<LambdaSpawn>(ComponentNames.LambdaSpawn);
|
|
||||||
const startState = EditorState.create({
|
const startState = EditorState.create({
|
||||||
doc: code,
|
doc: this.code,
|
||||||
extensions: [
|
extensions: [
|
||||||
basicSetup,
|
basicSetup,
|
||||||
keymap.of(defaultKeymap),
|
keymap.of(defaultKeymap),
|
||||||
@ -236,9 +242,7 @@ export class LambdaFactory extends Entity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const spawner = this.getComponent<LambdaSpawn>(ComponentNames.LambdaSpawn);
|
this.code = text;
|
||||||
spawner.code = text;
|
|
||||||
this.addComponent(spawner);
|
|
||||||
|
|
||||||
view.destroy();
|
view.destroy();
|
||||||
editorElement.innerHTML = "";
|
editorElement.innerHTML = "";
|
||||||
|
39
src/engine/systems/GridSpawner.ts
Normal file
39
src/engine/systems/GridSpawner.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { System, SystemNames } from ".";
|
||||||
|
import { Game } from "..";
|
||||||
|
import { ComponentNames, Grid, GridSpawn } from "../components";
|
||||||
|
import { Direction } from "../interfaces";
|
||||||
|
|
||||||
|
export class GridSpawner extends System {
|
||||||
|
constructor() {
|
||||||
|
super(SystemNames.GridSpawner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(_dt: number, game: Game) {
|
||||||
|
game.forEachEntityWithComponent(ComponentNames.GridSpawn, (entity) => {
|
||||||
|
const spawn = entity.getComponent<GridSpawn>(ComponentNames.GridSpawn)!;
|
||||||
|
const hasGrid = entity.hasComponent(SystemNames.Grid);
|
||||||
|
|
||||||
|
if (spawn.direction === Direction.NONE || !hasGrid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const grid = entity.getComponent<Grid>(SystemNames.Grid)!;
|
||||||
|
|
||||||
|
const direction = spawn.direction;
|
||||||
|
const spawned = spawn.spawner();
|
||||||
|
if (!spawned) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spawn.direction = Direction.NONE;
|
||||||
|
entity.addComponent(spawn);
|
||||||
|
|
||||||
|
const spawnedGrid = spawned.getComponent<Grid>(SystemNames.Grid)!;
|
||||||
|
spawnedGrid.gridPosition = grid.gridPosition;
|
||||||
|
spawnedGrid.movingDirection = direction;
|
||||||
|
spawned.addComponent(spawnedGrid);
|
||||||
|
|
||||||
|
game.addEntity(spawned);
|
||||||
|
entity.addComponent(spawned);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
import { System, SystemNames } from ".";
|
import { System, SystemNames } from ".";
|
||||||
import { Game } from "..";
|
import { Game } from "..";
|
||||||
import { ComponentNames, Grid, LambdaSpawn } from "../components";
|
import { ComponentNames, Grid, GridSpawn } from "../components";
|
||||||
import { FunctionBox } from "../entities";
|
import { FunctionBox } from "../entities";
|
||||||
|
|
||||||
export class LambdaFactory extends System {
|
export class GridSpawner extends System {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(SystemNames.LambdaFactory);
|
super(SystemNames.GridSpawner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public update(_dt: number, game: Game) {
|
public update(_dt: number, game: Game) {
|
||||||
game.forEachEntityWithComponent(ComponentNames.LambdaSpawn, (entity) => {
|
game.forEachEntityWithComponent(ComponentNames.GridSpawn, (entity) => {
|
||||||
const lambdaSpawn = entity.getComponent<LambdaSpawn>(
|
const lambdaSpawn = entity.getComponent<GridSpawn>(
|
||||||
ComponentNames.LambdaSpawn,
|
ComponentNames.GridSpawn,
|
||||||
)!;
|
)!;
|
||||||
const hasGrid = entity.hasComponent(SystemNames.Grid);
|
const hasGrid = entity.hasComponent(SystemNames.Grid);
|
||||||
|
|
@ -3,6 +3,6 @@ export namespace SystemNames {
|
|||||||
export const Input = "Input";
|
export const Input = "Input";
|
||||||
export const FacingDirection = "FacingDirection";
|
export const FacingDirection = "FacingDirection";
|
||||||
export const Grid = "Grid";
|
export const Grid = "Grid";
|
||||||
export const LambdaFactory = "LambdaFactory";
|
export const GridSpawner = "GridSpawner";
|
||||||
export const Collision = "Collision";
|
export const Collision = "Collision";
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,5 @@ export * from "./Render";
|
|||||||
export * from "./Input";
|
export * from "./Input";
|
||||||
export * from "./FacingDirection";
|
export * from "./FacingDirection";
|
||||||
export * from "./Grid";
|
export * from "./Grid";
|
||||||
export * from "./LambdaFactory";
|
export * from "./GridSpawner";
|
||||||
export * from "./Collision";
|
export * from "./Collision";
|
||||||
|
Loading…
Reference in New Issue
Block a user