support underscores in function application, add sign entity
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
4da17f6ded
commit
32879581e5
BIN
public/assets/sign.png
Normal file
BIN
public/assets/sign.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 996 B |
@ -11,7 +11,7 @@ export interface GameCanvasProps {
|
|||||||
export const GameCanvas = ({ width, height }: GameCanvasProps) => {
|
export const GameCanvas = ({ width, height }: GameCanvasProps) => {
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const [game, setGame] = useState<TheAbstractionEngine>();
|
const [game, setGame] = useState<TheAbstractionEngine>();
|
||||||
const [ready, setReady] = useState(false);
|
const [ready, setReady] = useState(true); // false);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -33,7 +33,7 @@ export class TheAbstractionEngine {
|
|||||||
const facingDirectionSystem = new FacingDirection(inputSystem);
|
const facingDirectionSystem = new FacingDirection(inputSystem);
|
||||||
|
|
||||||
[
|
[
|
||||||
new Level(LevelNames.LevelSelection),
|
new Level(LevelNames.Tutorial),
|
||||||
inputSystem,
|
inputSystem,
|
||||||
facingDirectionSystem,
|
facingDirectionSystem,
|
||||||
new Grid(
|
new Grid(
|
||||||
|
@ -11,6 +11,7 @@ export enum Sprites {
|
|||||||
BUBBLE,
|
BUBBLE,
|
||||||
PORTAL,
|
PORTAL,
|
||||||
GRASS,
|
GRASS,
|
||||||
|
SIGN,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SpriteSpec {
|
export interface SpriteSpec {
|
||||||
@ -126,3 +127,12 @@ const grassSpriteSpec = {
|
|||||||
sheet: "/assets/grass.png",
|
sheet: "/assets/grass.png",
|
||||||
};
|
};
|
||||||
SPRITE_SPECS.set(Sprites.GRASS, grassSpriteSpec);
|
SPRITE_SPECS.set(Sprites.GRASS, grassSpriteSpec);
|
||||||
|
|
||||||
|
const signSpriteSpec = {
|
||||||
|
msPerFrame: 200,
|
||||||
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
frames: 3,
|
||||||
|
sheet: "/assets/sign.png",
|
||||||
|
};
|
||||||
|
SPRITE_SPECS.set(Sprites.SIGN, signSpriteSpec);
|
||||||
|
@ -10,4 +10,5 @@ export namespace EntityNames {
|
|||||||
export const Particles = "Particles";
|
export const Particles = "Particles";
|
||||||
export const Portal = "Portal";
|
export const Portal = "Portal";
|
||||||
export const Grass = "Grass";
|
export const Grass = "Grass";
|
||||||
|
export const Sign = "Sign";
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,10 @@ import {
|
|||||||
interpret,
|
interpret,
|
||||||
} from "../../interpreter";
|
} from "../../interpreter";
|
||||||
|
|
||||||
|
const APPLICATION_RESULTS: Record<string, (gridPosition: Coord2D) => Entity> = {
|
||||||
|
_KEY: (gridPosition: Coord2D) => new Key(gridPosition),
|
||||||
|
};
|
||||||
|
|
||||||
export class FunctionApplication extends Entity {
|
export class FunctionApplication extends Entity {
|
||||||
private static spriteSpec = SPRITE_SPECS.get(Sprites.BUBBLE) as SpriteSpec;
|
private static spriteSpec = SPRITE_SPECS.get(Sprites.BUBBLE) as SpriteSpec;
|
||||||
|
|
||||||
@ -43,7 +47,9 @@ export class FunctionApplication extends Entity {
|
|||||||
super(EntityNames.FunctionApplication);
|
super(EntityNames.FunctionApplication);
|
||||||
|
|
||||||
this.symbolTable = new SymbolTable();
|
this.symbolTable = new SymbolTable();
|
||||||
this.symbolTable.add("key");
|
Object.keys(APPLICATION_RESULTS).forEach((key) => {
|
||||||
|
this.symbolTable.add(key);
|
||||||
|
});
|
||||||
|
|
||||||
const dimension = {
|
const dimension = {
|
||||||
width: FunctionApplication.spriteSpec.width,
|
width: FunctionApplication.spriteSpec.width,
|
||||||
@ -109,9 +115,10 @@ export class FunctionApplication extends Entity {
|
|||||||
ComponentNames.LambdaTerm
|
ComponentNames.LambdaTerm
|
||||||
);
|
);
|
||||||
const newCode = applicationTerm.code.replace("_INPUT", functionTerm.code);
|
const newCode = applicationTerm.code.replace("_INPUT", functionTerm.code);
|
||||||
|
|
||||||
let result: DebrujinifiedLambdaTerm | null = null;
|
let result: DebrujinifiedLambdaTerm | null = null;
|
||||||
try {
|
try {
|
||||||
result = interpret(newCode, this.symbolTable);
|
result = interpret(newCode, this.symbolTable, true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
fail();
|
fail();
|
||||||
@ -131,8 +138,9 @@ export class FunctionApplication extends Entity {
|
|||||||
applicationResultingEntity = new FunctionBox(grid.gridPosition, code);
|
applicationResultingEntity = new FunctionBox(grid.gridPosition, code);
|
||||||
} else if ("name" in result) {
|
} else if ("name" in result) {
|
||||||
const { name } = result;
|
const { name } = result;
|
||||||
if (name === "key") {
|
const entityFactory = APPLICATION_RESULTS[name];
|
||||||
applicationResultingEntity = new Key(grid.gridPosition);
|
if (entityFactory) {
|
||||||
|
game.addEntity(entityFactory(nextPosition));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fail();
|
fail();
|
||||||
|
@ -67,7 +67,10 @@ export class FunctionBox extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeLambdaTermHighlightComponent = (entity: Entity) => {
|
export const makeLambdaTermHighlightComponent = (
|
||||||
|
entity: Entity,
|
||||||
|
text?: string
|
||||||
|
) => {
|
||||||
const onUnhighlight = () => {
|
const onUnhighlight = () => {
|
||||||
closeModal();
|
closeModal();
|
||||||
entity.removeComponent(ComponentNames.Interactable);
|
entity.removeComponent(ComponentNames.Interactable);
|
||||||
@ -87,9 +90,9 @@ export const makeLambdaTermHighlightComponent = (entity: Entity) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = entity.getComponent<LambdaTerm>(
|
const code =
|
||||||
ComponentNames.LambdaTerm
|
text ??
|
||||||
)!.code;
|
entity.getComponent<LambdaTerm>(ComponentNames.LambdaTerm)!.code;
|
||||||
openModal(
|
openModal(
|
||||||
`<div style="text-align:center"><p>${code}</p> <br> <button id="close">Close</button></div>`
|
`<div style="text-align:center"><p>${code}</p> <br> <button id="close">Close</button></div>`
|
||||||
);
|
);
|
||||||
|
49
src/engine/entities/Sign.ts
Normal file
49
src/engine/entities/Sign.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { Entity, EntityNames, makeLambdaTermHighlightComponent } from ".";
|
||||||
|
import { BoundingBox, Colliding, Grid, Sprite } from "../components";
|
||||||
|
import { IMAGES, SPRITE_SPECS, SpriteSpec, Sprites } from "../config";
|
||||||
|
import { Coord2D } from "../interfaces";
|
||||||
|
|
||||||
|
export class Sign extends Entity {
|
||||||
|
private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
|
||||||
|
Sprites.SIGN
|
||||||
|
) as SpriteSpec;
|
||||||
|
|
||||||
|
private text: string;
|
||||||
|
|
||||||
|
constructor(text: string, gridPosition: Coord2D) {
|
||||||
|
super(EntityNames.Sign);
|
||||||
|
this.text = text;
|
||||||
|
|
||||||
|
const dimension = {
|
||||||
|
width: Sign.spriteSpec.width,
|
||||||
|
height: Sign.spriteSpec.height,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addComponent(
|
||||||
|
new Sprite(
|
||||||
|
IMAGES.get(Sign.spriteSpec.sheet)!,
|
||||||
|
{ x: 0, y: 0 },
|
||||||
|
dimension,
|
||||||
|
Sign.spriteSpec.msPerFrame,
|
||||||
|
Sign.spriteSpec.frames
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addComponent(
|
||||||
|
new BoundingBox(
|
||||||
|
{
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
dimension,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addComponent(new Grid(gridPosition));
|
||||||
|
|
||||||
|
this.addComponent(new Colliding());
|
||||||
|
|
||||||
|
this.addComponent(makeLambdaTermHighlightComponent(this, this.text));
|
||||||
|
}
|
||||||
|
}
|
@ -11,3 +11,4 @@ export * from "./FunctionApplication";
|
|||||||
export * from "./Particles";
|
export * from "./Particles";
|
||||||
export * from "./Portal";
|
export * from "./Portal";
|
||||||
export * from "./Grass";
|
export * from "./Grass";
|
||||||
|
export * from "./Sign";
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
LambdaFactory,
|
LambdaFactory,
|
||||||
LockedDoor,
|
LockedDoor,
|
||||||
Player,
|
Player,
|
||||||
|
Sign,
|
||||||
Wall,
|
Wall,
|
||||||
} from "../entities";
|
} from "../entities";
|
||||||
|
|
||||||
@ -16,14 +17,15 @@ export class Tutorial extends Level {
|
|||||||
|
|
||||||
public init(game: Game): void {
|
public init(game: Game): void {
|
||||||
const entities = [
|
const entities = [
|
||||||
new Player({ x: 2, y: 2 }),
|
new Sign("TODO: Explain entities", { x: 4, y: 3 }),
|
||||||
new Wall({ x: 10, y: 9 }),
|
new Wall({ x: 10, y: 9 }),
|
||||||
new Wall({ x: 10, y: 11 }),
|
new Wall({ x: 10, y: 11 }),
|
||||||
new Wall({ x: 11, y: 10 }),
|
new Wall({ x: 11, y: 10 }),
|
||||||
new Curry({ x: 10, y: 10 }),
|
new Curry({ x: 10, y: 10 }),
|
||||||
new LockedDoor({ x: 9, y: 10 }),
|
new LockedDoor({ x: 9, y: 10 }),
|
||||||
new LambdaFactory({ x: 6, y: 3 }, "// TODO: Remove line\n(λ (x) . x)", 3),
|
new LambdaFactory({ x: 6, y: 3 }, "// TODO: Remove line\n(λ (x) . x)", 3),
|
||||||
new FunctionApplication({ x: 6, y: 6 }, "(_INPUT key)"),
|
new FunctionApplication({ x: 6, y: 6 }, "(_INPUT _KEY)"),
|
||||||
|
new Player({ x: 2, y: 2 }),
|
||||||
];
|
];
|
||||||
|
|
||||||
entities.forEach((entity) => game.addEntity(entity));
|
entities.forEach((entity) => game.addEntity(entity));
|
||||||
|
@ -215,7 +215,7 @@ export default (function () {
|
|||||||
var peg$c2 = ".";
|
var peg$c2 = ".";
|
||||||
var peg$c3 = "\r\n";
|
var peg$c3 = "\r\n";
|
||||||
|
|
||||||
var peg$r0 = /^[a-zA-Z0-9]/;
|
var peg$r0 = options.allowUnderscores ? /^[a-zA-Z0-9_]/ : /^[a-zA-Z0-9]/;
|
||||||
var peg$r1 = /^[\\\u03BB]/;
|
var peg$r1 = /^[\\\u03BB]/;
|
||||||
var peg$r2 = /^[\t-\n ]/;
|
var peg$r2 = /^[\t-\n ]/;
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ export const isVariable = (term: LambdaTerm): term is Variable => {
|
|||||||
return typeof term === "string";
|
return typeof term === "string";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parse = (term: string, library = false) => {
|
export const parse = (
|
||||||
return peggyParser.parse(term, { peg$library: library });
|
term: string,
|
||||||
|
allowUnderscores = false,
|
||||||
|
library = false
|
||||||
|
) => {
|
||||||
|
return peggyParser.parse(term, { peg$library: library, allowUnderscores });
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user