diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.tsx | 2 | ||||
-rw-r--r-- | src/components/GameCanvas.tsx | 4 | ||||
-rw-r--r-- | src/engine/components/Sprite.ts | 14 | ||||
-rw-r--r-- | src/engine/entities/FunctionApplication.ts | 2 | ||||
-rw-r--r-- | src/engine/levels/CarCadr.ts | 60 | ||||
-rw-r--r-- | src/engine/levels/LevelNames.ts | 1 | ||||
-rw-r--r-- | src/engine/levels/LevelSelection.ts | 47 | ||||
-rw-r--r-- | src/engine/levels/Tutorial.ts | 2 | ||||
-rw-r--r-- | src/engine/levels/index.ts | 10 | ||||
-rw-r--r-- | src/engine/systems/Level.ts | 1 |
10 files changed, 118 insertions, 25 deletions
diff --git a/src/App.tsx b/src/App.tsx index b8582de..89b7cbc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,7 +21,7 @@ export const App = () => { <div className="footer"> <span> built by{" "} - <a href="https://github.com/simponic" target="_blank" className="tf"> + <a href="https://git.simponic.xyz/simponic" target="_blank" className="tf"> simponic </a>{" "} | inspired by{" "} diff --git a/src/components/GameCanvas.tsx b/src/components/GameCanvas.tsx index b6c585d..98ba506 100644 --- a/src/components/GameCanvas.tsx +++ b/src/components/GameCanvas.tsx @@ -11,7 +11,9 @@ export interface GameCanvasProps { export const GameCanvas = ({ width, height }: GameCanvasProps) => { const canvasRef = useRef<HTMLCanvasElement>(null); const [game, setGame] = useState<TheAbstractionEngine>(); - const [ready, setReady] = useState(false); + // TODO: go back to this after done + // const [ready, setReady] = useState(false); + const [ready, setReady] = useState(document.location.hostname.includes("localhost")); const [loading, setLoading] = useState(true); useEffect(() => { diff --git a/src/engine/components/Sprite.ts b/src/engine/components/Sprite.ts index fdf9675..6c0549b 100644 --- a/src/engine/components/Sprite.ts +++ b/src/engine/components/Sprite.ts @@ -55,7 +55,7 @@ export class Sprite extends Component implements Renderable { ctx.save(); ctx.translate(center.x, center.y); - if (rotation != undefined && rotation != 0) { + if (typeof rotation !== "undefined" && rotation != 0) { ctx.rotate(rotation * (Math.PI / 180)); } ctx.translate(-center.x, -center.y); @@ -64,6 +64,12 @@ export class Sprite extends Component implements Renderable { ctx.globalAlpha = opacity; } + ctx.drawImage( + this.sheet, + ...this.getSpriteArgs(), + ...this.getDrawArgs(drawArgs), + ); + if (backgroundText) { // draw text const { fillStyle, font, textAlign, text } = backgroundText; @@ -75,12 +81,6 @@ export class Sprite extends Component implements Renderable { ctx.fillText(text, center.x, center.y + height / 2); } - ctx.drawImage( - this.sheet, - ...this.getSpriteArgs(), - ...this.getDrawArgs(drawArgs), - ); - if (tint) { ctx.globalAlpha = 0.5; ctx.globalCompositeOperation = "source-atop"; diff --git a/src/engine/entities/FunctionApplication.ts b/src/engine/entities/FunctionApplication.ts index f15fcb9..bd88bda 100644 --- a/src/engine/entities/FunctionApplication.ts +++ b/src/engine/entities/FunctionApplication.ts @@ -155,7 +155,6 @@ export class FunctionApplication extends Entity { return; } - const { dimension } = gridSystem; const nextPosition = gridSystem.getNewGridPosition( grid.gridPosition, entityGrid.previousDirection @@ -194,6 +193,7 @@ export class FunctionApplication extends Entity { } SOUNDS.get(LambdaTransformSound.name)!.play(); + const { dimension } = gridSystem; const particles = new Particles({ center: gridSystem.gridToScreenPosition(nextPosition), spawnerDimensions: { diff --git a/src/engine/levels/CarCadr.ts b/src/engine/levels/CarCadr.ts new file mode 100644 index 0000000..e3d1eb9 --- /dev/null +++ b/src/engine/levels/CarCadr.ts @@ -0,0 +1,60 @@ +import { Level, LevelNames } from "."; +import { Game } from ".."; +import { + Curry, + FunctionApplication, + Grass, + LambdaFactory, + LockedDoor, + Player, + Wall, +} from "../entities"; +import { Grid, SystemNames } from "../systems"; +import { normalRandom } from "../utils"; + +export class CarCadr extends Level { + constructor() { + super(LevelNames.CarCadr); + } + + public init(game: Game) { + const grid = game.getSystem<Grid>(SystemNames.Grid); + const dimensions = grid.getGridDimensions(); + + const grasses = Array.from({ length: dimensions.width }) + .fill(0) + .map(() => { + // random grass + return new Grass({ + x: Math.floor( + normalRandom(dimensions.width / 2, dimensions.width / 4, 1.5), + ), + y: Math.floor( + normalRandom(dimensions.height / 2, dimensions.height / 4, 1.5), + ), + }); + }); + + const entities = [ + ...grasses, + new Player({ x: 9, y: 5 }), + new Wall({ x: 4, y: 3 }), + new Wall({ x: 4, y: 4 }), + new LambdaFactory({ x: 6, y: 4 }, "(\\ (x) . x)", 1), + new FunctionApplication({ x: 5, y: 5 }, "(_INPUT _KEY)"), + new Wall({ x: 4, y: 5 }), + new Wall({ x: 6, y: 5 }), + new FunctionApplication({ x: 4, y: 6 }, "(_INPUT _NULL)"), + new Wall({ x: 6, y: 7 }), + new Wall({ x: 5, y: 7 }), + new Wall({ x: 4, y: 7 }), + new LockedDoor({ x: 3, y: 8 }), + new Curry({ x: 3, y: 9 }), + new Wall({ x: 2, y: 9 }), + new Wall({ x: 4, y: 9 }), + new Wall({ x: 3, y: 10 }), + ]; + + entities.forEach((entity) => game.addEntity(entity)); + } +}
\ No newline at end of file diff --git a/src/engine/levels/LevelNames.ts b/src/engine/levels/LevelNames.ts index e90b29a..7f3c4f1 100644 --- a/src/engine/levels/LevelNames.ts +++ b/src/engine/levels/LevelNames.ts @@ -1,4 +1,5 @@ export namespace LevelNames { export const Tutorial = "0"; + export const CarCadr = "1"; export const LevelSelection = "LevelSelection"; } diff --git a/src/engine/levels/LevelSelection.ts b/src/engine/levels/LevelSelection.ts index a970d9c..9e46274 100644 --- a/src/engine/levels/LevelSelection.ts +++ b/src/engine/levels/LevelSelection.ts @@ -1,9 +1,12 @@ import { LEVELS, Level, LevelNames } from "."; import { Game } from ".."; -import { Player, Portal } from "../entities"; +import { Grass, Player, Portal } from "../entities"; import { Grid, Level as LevelSystem, SystemNames } from "../systems"; +import { normalRandom } from "../utils"; export class LevelSelection extends Level { + public static RADIUS = 5; + constructor() { super(LevelNames.LevelSelection); } @@ -11,23 +14,43 @@ export class LevelSelection extends Level { public init(game: Game): void { const gridSystem = game.getSystem<Grid>(SystemNames.Grid); const center = gridSystem.getCenterGrid(); + const dimensions = gridSystem.getGridDimensions(); const levelSystem = game.getSystem<LevelSystem>(SystemNames.Level); const unlocked = levelSystem.getUnlockedLevels(); - LEVELS.forEach((level, i) => { - if ( - !unlocked.has(level.name) || - level.name === LevelNames.LevelSelection - ) { - return; - } - - const portal = new Portal(level.name, { x: i, y: 7 }); - game.addEntity(portal); - }); + const renderableLevels = LEVELS.filter( + ({ name }) => name !== LevelNames.LevelSelection + ); + const radiansPerLevel = (2 * Math.PI) / renderableLevels.length; + renderableLevels + .filter(({ name }) => unlocked.has(name)) + .map((level, i) => { + const radians = i * radiansPerLevel; + const coords = { + x: Math.floor(Math.cos(radians) * LevelSelection.RADIUS + center.x), + y: Math.floor(Math.sin(radians) * LevelSelection.RADIUS + center.y), + }; + return new Portal(level.name, coords); + }) + .forEach((e) => game.addEntity(e)); const player = new Player(center); game.addEntity(player); + + Array.from({ length: dimensions.width }) + .fill(0) + .map(() => { + // random grass + return new Grass({ + x: Math.floor( + normalRandom(dimensions.width / 2, dimensions.width / 4, 1.5) + ), + y: Math.floor( + normalRandom(dimensions.height / 2, dimensions.height / 4, 1.5) + ), + }); + }) + .forEach((e) => game.addEntity(e)); } } diff --git a/src/engine/levels/Tutorial.ts b/src/engine/levels/Tutorial.ts index 895b569..97a6826 100644 --- a/src/engine/levels/Tutorial.ts +++ b/src/engine/levels/Tutorial.ts @@ -43,7 +43,7 @@ export class Tutorial extends Level { { x: 4, y: 3 }, ), new Sign( - "this is a Term Application; interact to view its code<br><br>push the term ➡️ created by the factory any direction into the Application to produce a new one 💭<br><br>note that:<br><br>+ _INPUT is the term replaced by the pushed term<br><br>+ in this case _KEY is applied to the function to make a new KEY! 🔑", + "<div>this is a Term Application; interact to view its code<br><br>push the term ➡️ created by the factory any direction into the Application to produce a new one 💭<br><br>note that:<br><br>+ _INPUT is the term replaced by the pushed term<br><br>+ in this case _KEY is applied to the function to make a new KEY! 🔑</div>", { x: 4, y: 6 }, ), new Wall({ x: 10, y: 9 }), diff --git a/src/engine/levels/index.ts b/src/engine/levels/index.ts index bae7fea..216453c 100644 --- a/src/engine/levels/index.ts +++ b/src/engine/levels/index.ts @@ -2,11 +2,17 @@ export * from "./LevelNames"; export * from "./Level"; export * from "./LevelSelection"; export * from "./Tutorial"; +export * from "./CarCadr"; import { LevelNames } from "."; -import { LevelSelection, Tutorial, Level } from "."; +import { CarCadr, LevelSelection, Tutorial, Level } from "."; -export const LEVELS: Level[] = [new LevelSelection(), new Tutorial()]; +export const LEVELS: Level[] = [ + new LevelSelection(), + new Tutorial(), + new CarCadr(), +]; export const LEVEL_PROGRESSION: Record<string, string[]> = { [LevelNames.LevelSelection]: [LevelNames.Tutorial], + [LevelNames.Tutorial]: [LevelNames.CarCadr], }; diff --git a/src/engine/systems/Level.ts b/src/engine/systems/Level.ts index 824895d..99fe452 100644 --- a/src/engine/systems/Level.ts +++ b/src/engine/systems/Level.ts @@ -3,6 +3,7 @@ import { Game } from ".."; import { type Level as LevelType, LEVELS, LEVEL_PROGRESSION } from "../levels"; export class Level extends System { + // TODO: read from localstorage private unlockedLevels: Set<string> = new Set(); private currentLevel: LevelType | null = null; private moveToLevel: string | null; |