Add HUD
This commit is contained in:
		| @@ -80,6 +80,10 @@ export class Size { | ||||
|     this.w = w; | ||||
|     this.h = h; | ||||
|   } | ||||
|  | ||||
|   add(other: Size) { | ||||
|     return new Size(this.w + other.w, this.h + other.h); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export class Rect { | ||||
|   | ||||
							
								
								
									
										62
									
								
								src/game.ts
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/game.ts
									
									
									
									
									
								
							| @@ -1,9 +1,9 @@ | ||||
| import {getScreen} from "./engine/internal/screen.ts"; | ||||
| import {BG_OUTER} from "./colors.ts"; | ||||
| import {D, I} from "./engine/public.ts"; | ||||
| import {IGame, Point, Rect, Size} from "./engine/datatypes.ts"; | ||||
| import {IGame, Point, Size} from "./engine/datatypes.ts"; | ||||
| import {HuntMode} from "./huntmode.ts"; | ||||
| import {getLayoutRect} from "./layout.ts"; | ||||
| import {getPageLocation, getPartLocation, Page, UIPart} from "./layout.ts"; | ||||
| import {getHud} from "./hud.ts"; | ||||
|  | ||||
| class MenuCamera { | ||||
|   // measured in whole screens | ||||
| @@ -26,23 +26,9 @@ class MenuCamera { | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| type GameState = "Gameplay" | "Thralls"; | ||||
|  | ||||
| function getScreenLocation(state: GameState): Point { | ||||
|   if (state === "Gameplay") { | ||||
|     return new Point(0, 0); | ||||
|   } | ||||
|   if (state === "Thralls") { | ||||
|     return new Point(0, 1); | ||||
|   } | ||||
|  | ||||
|   throw `invalid state: ${state}` | ||||
| } | ||||
|  | ||||
| export class Game implements IGame { | ||||
|   camera: MenuCamera; | ||||
|   state: GameState; | ||||
|   page: Page; | ||||
|   huntMode: HuntMode; | ||||
|  | ||||
|   constructor() { | ||||
| @@ -50,20 +36,20 @@ export class Game implements IGame { | ||||
|       position: new Point(0, 0), | ||||
|       target: new Point(0, 0), | ||||
|     }); | ||||
|     this.state = "Gameplay"; | ||||
|     this.page = "Gameplay"; | ||||
|  | ||||
|     this.huntMode = HuntMode.generate({depth: 1}); | ||||
|   } | ||||
|  | ||||
|   update() { | ||||
|     if (I.isKeyPressed("w")) { | ||||
|       this.state = "Gameplay" | ||||
|       this.page = "Gameplay" | ||||
|     } | ||||
|     if (I.isKeyPressed("s")) { | ||||
|       this.state = "Thralls" | ||||
|       this.page = "Thralls" | ||||
|     } | ||||
|  | ||||
|     this.camera.target = getScreenLocation(this.state); | ||||
|     this.camera.target = getPageLocation(this.page); | ||||
|     D.camera = new Point( | ||||
|       D.size.w * this.camera.position.x, | ||||
|       D.size.h * this.camera.position.y, | ||||
| @@ -91,44 +77,24 @@ export class Game implements IGame { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   getGameStateRect(gameState: GameState): Rect { | ||||
|     let baseRect: Rect; | ||||
|     switch(gameState) { | ||||
|       case "Gameplay": | ||||
|       case "Thralls": | ||||
|         baseRect = getLayoutRect(new Size(384, 384)); | ||||
|         break; | ||||
|       default: | ||||
|         throw `not sure what base rect to use: ${gameState}` | ||||
|     } | ||||
|  | ||||
|     // now move that base to a reasonable screen location | ||||
|     let screen = getScreen(); | ||||
|     let {w, h} = screen.size; | ||||
|     let overallScreenLocation = getScreenLocation(gameState); | ||||
|  | ||||
|     let offsetX = overallScreenLocation.x * w; | ||||
|     let offsetY = overallScreenLocation.y * h; | ||||
|  | ||||
|     return baseRect.offset(new Point(offsetX, offsetY)); | ||||
|   } | ||||
|  | ||||
|   #withHuntModeCamera(cb: () => void) { | ||||
|     let region = this.getGameStateRect("Gameplay") | ||||
|   #withCamera(part: UIPart, cb: () => void) { | ||||
|     let region = getPartLocation(part); | ||||
|  | ||||
|     D.withCamera(D.camera.offset(region.top.negate()), cb) | ||||
|   } | ||||
|  | ||||
|   updateGameplay() { | ||||
|     this.#withHuntModeCamera(() => { | ||||
|     this.#withCamera("Gameplay", () => { | ||||
|       this.huntMode.update(); | ||||
|     }); | ||||
|     this.#withCamera("HUD", () => { getHud().update() }) | ||||
|   } | ||||
|  | ||||
|   drawGameplay() { | ||||
|     this.#withHuntModeCamera(() => { | ||||
|     this.#withCamera("Gameplay", () => { | ||||
|       this.huntMode.draw(); | ||||
|     }); | ||||
|     this.#withCamera("HUD", () => { getHud().draw() }) | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										36
									
								
								src/hud.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/hud.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import {D} from "./engine/public.ts"; | ||||
| import {Point, Size} from "./engine/datatypes.ts"; | ||||
| import {FG_BOLD, FG_TEXT} from "./colors.ts"; | ||||
| import {ALL_STATS} from "./datatypes.ts"; | ||||
| import {getPlayerProgress} from "./playerprogress.ts"; | ||||
|  | ||||
| export class Hud { | ||||
|   get size(): Size { | ||||
|     return new Size(96, 160) | ||||
|   } | ||||
|  | ||||
|   update() { } | ||||
|  | ||||
|   draw() { | ||||
|     // D.fillRect(new Point(-4, -4), this.size.add(new Size(8, 8)), BG_INSET) | ||||
|     D.drawText("Pyrex", new Point(0, 0), FG_BOLD) | ||||
|     D.drawText("Level 1", new Point(0, 16), FG_TEXT) | ||||
|  | ||||
|     let y = 48; | ||||
|     let prog = getPlayerProgress(); | ||||
|     for (let s of ALL_STATS.values()) { | ||||
|       D.drawText(`${s}`, new Point(0, y), FG_BOLD) | ||||
|       D.drawText(`${prog.getStat(s)}`, new Point(32, y), FG_TEXT) | ||||
|       y += 16; | ||||
|     } | ||||
|     D.drawText("EXP", new Point(0, 128), FG_BOLD); | ||||
|     D.drawText("0", new Point(32, 128), FG_TEXT); | ||||
|     D.drawText("BLD", new Point(0, 144), FG_BOLD); | ||||
|     D.drawText(`${prog.getBlood()}cc`, new Point(32, 144), FG_TEXT); | ||||
|   } | ||||
| } | ||||
|  | ||||
| let active = new Hud(); | ||||
| export function getHud() : Hud { | ||||
|   return active; | ||||
| } | ||||
| @@ -146,12 +146,14 @@ export class HuntMode { | ||||
|       let stat = present.content.stat; | ||||
|       let amount = 1; | ||||
|       present.content = {type: "empty"}; | ||||
|       getPlayerProgress().spendBlood(90); | ||||
|       getPlayerProgress().add(stat, amount); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   movePlayerTo(newPosition: Point) { | ||||
|     this.player = newPosition; | ||||
|     getPlayerProgress().spendBlood(10); | ||||
|     this.#updateVisibilityAndPossibleMoves(); | ||||
|     this.#collectResources(); | ||||
|   } | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| import {AlignX, AlignY, Point, Rect, Size} from "./engine/datatypes.ts"; | ||||
| import {D} from "./engine/public.ts"; | ||||
| import {getHud} from "./hud.ts"; | ||||
|  | ||||
| // general | ||||
| let margin = 8; | ||||
|  | ||||
| export function getLayoutRect( | ||||
|   size: Size, | ||||
|   options?: {alignX?: AlignX, alignY?: AlignY} | ||||
| @@ -21,6 +22,9 @@ export function getLayoutRect( | ||||
|   let {w: innerW, h: innerH} = size; | ||||
|   let remainingSpaceX = marginalScreenW - innerW; | ||||
|   let remainingSpaceY = marginalScreenH - innerH; | ||||
|   if (options?.alignY == AlignY.Bottom) { | ||||
|     console.log(`Remaining space y: ${remainingSpaceY}`) | ||||
|   } | ||||
|  | ||||
|   let alignXCoef = | ||||
|     options?.alignX == AlignX.Left ? 0.0 : | ||||
| @@ -40,4 +44,59 @@ export function getLayoutRect( | ||||
|     new Point(Math.floor(x), Math.floor(y)), | ||||
|     size | ||||
|   ) | ||||
| } | ||||
|  | ||||
| // specific | ||||
| export type Page = "Gameplay" | "Thralls"; | ||||
| export type UIPart = "HUD" | "Gameplay" | "Thralls"; | ||||
|  | ||||
| export function getPartPage(part: UIPart): Page { | ||||
|   switch (part) { | ||||
|     case "HUD": | ||||
|     case "Gameplay": | ||||
|       return "Gameplay"; | ||||
|     case "Thralls": | ||||
|       return "Thralls"; | ||||
|   } | ||||
|  | ||||
|   throw `invalid part: ${part}` | ||||
| } | ||||
|  | ||||
| export function getPageLocation(page: Page): Point { | ||||
|   // NOTE: Measured in screens, not pixels | ||||
|   switch (page) { | ||||
|     case "Gameplay": | ||||
|       return new Point(0, 0); | ||||
|     case "Thralls": | ||||
|       return new Point(0, 1); | ||||
|   } | ||||
|  | ||||
|   throw `invalid page: ${page}` | ||||
| } | ||||
|  | ||||
| export function getPartLocation(part: UIPart): Rect { | ||||
|   // TODO: in pixels, not screens | ||||
|   let {w: screenW, h: screenH} = D.size; | ||||
|   let pageOffset = getPageLocation(getPartPage(part)); | ||||
|   let layoutRect = internalGetPartLayoutRect(part); | ||||
|  | ||||
|   return layoutRect.offset(new Point( | ||||
|     pageOffset.x * screenW, | ||||
|     pageOffset.y * screenH | ||||
|   )); | ||||
|  | ||||
| } | ||||
|  | ||||
| export function internalGetPartLayoutRect(part: UIPart) { | ||||
|   switch (part) { | ||||
|     case "Gameplay": | ||||
|     case "Thralls": | ||||
|       return getLayoutRect(new Size(384, 384)); | ||||
|     case "HUD": | ||||
|       return getLayoutRect(getHud().size, { | ||||
|         alignX: AlignX.Left, | ||||
|         alignY: AlignY.Middle | ||||
|       }) | ||||
|   } | ||||
|   throw `not sure what layout rect to use ${part}` | ||||
| } | ||||
| @@ -2,6 +2,7 @@ import {Stat} from "./datatypes.ts"; | ||||
|  | ||||
| export class PlayerProgress { | ||||
|   #stats: Record<Stat, number> | ||||
|   #blood: number | ||||
|  | ||||
|   constructor() { | ||||
|     this.#stats = { | ||||
| @@ -10,6 +11,13 @@ export class PlayerProgress { | ||||
|       CHA: 10, | ||||
|       PSI: 10, | ||||
|     } | ||||
|     this.#blood = 0; | ||||
|  | ||||
|     this.refill(); | ||||
|   } | ||||
|  | ||||
|   refill() { | ||||
|     this.#blood = 2000; | ||||
|   } | ||||
|  | ||||
|   add(stat: Stat, amount: number) { | ||||
| @@ -22,9 +30,17 @@ export class PlayerProgress { | ||||
|     this.#stats[stat] += amount; | ||||
|   } | ||||
|  | ||||
|   get(stat: Stat): number { | ||||
|   getStat(stat: Stat): number { | ||||
|     return this.#stats[stat] | ||||
|   } | ||||
|  | ||||
|   getBlood(): number { | ||||
|     return Math.floor(Math.max(this.#blood, 0)); | ||||
|   } | ||||
|  | ||||
|   spendBlood(amt: number) { | ||||
|     this.#blood -= amt; | ||||
|   } | ||||
| } | ||||
|  | ||||
| let active: PlayerProgress = new PlayerProgress(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user