Endgame screen with fake numbers
This commit is contained in:
		
							
								
								
									
										78
									
								
								src/endgamemodal.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/endgamemodal.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| import {withCamera} from "./layout.ts"; | ||||
| import {D} from "./engine/public.ts"; | ||||
| import {FG_BOLD, FG_TEXT} from "./colors.ts"; | ||||
| import {AlignX, Point, Rect, Size} from "./engine/datatypes.ts"; | ||||
| import {DrawPile} from "./drawpile.ts"; | ||||
| import {addButton} from "./button.ts"; | ||||
|  | ||||
| const WIDTH = 384; | ||||
| const HEIGHT = 384; | ||||
|  | ||||
| export class EndgameModal { | ||||
|   #isShown: boolean; | ||||
|   #drawpile: DrawPile; | ||||
|  | ||||
|   constructor() { | ||||
|     this.#isShown = false; | ||||
|     this.#drawpile = new DrawPile(); | ||||
|  | ||||
|     // debug | ||||
|   } | ||||
|  | ||||
|   get isShown(): boolean { | ||||
|     return this.#isShown; | ||||
|   } | ||||
|  | ||||
|   show() { | ||||
|     this.#isShown = true; | ||||
|   } | ||||
|  | ||||
|   update() { | ||||
|     withCamera("FullscreenPopover", () => this.#update()) | ||||
|   } | ||||
|  | ||||
|   draw() { | ||||
|     withCamera("FullscreenPopover", () => this.#draw()) | ||||
|   } | ||||
|  | ||||
|   #update() { | ||||
|     this.#drawpile.clear(); | ||||
|     addButton( | ||||
|       this.#drawpile, | ||||
|       "Appoint a Successor", | ||||
|       new Rect( | ||||
|         new Point(0, HEIGHT - 32), new Size(WIDTH, 32) | ||||
|       ), | ||||
|       true, | ||||
|       () => { | ||||
|         alert("beep"); | ||||
|       } | ||||
|     ) | ||||
|     this.#drawpile.executeOnClick(); | ||||
|   } | ||||
|  | ||||
|   #draw() { | ||||
|     D.drawText("It is time to announce the sentence of fate.", new Point(0, 0), FG_TEXT) | ||||
|     D.drawText("You are no longer a fledgling. Your new rank:", new Point(0, 32), FG_TEXT) | ||||
|     D.drawText("Progenitor", new Point(WIDTH/2, 64), FG_BOLD, {alignX: AlignX.Center}) | ||||
|     D.drawText("You have achieved a DOMICILE STATUS of:", new Point(0, 96), FG_TEXT) | ||||
|     D.drawText("Guest House", new Point(WIDTH/2, 128), FG_BOLD, {alignX: AlignX.Center}) | ||||
|     D.drawText("where you live with many friends.", new Point(0, 160), FG_TEXT) | ||||
|     D.drawText("You have achieved:", new Point(0, 192), FG_TEXT) | ||||
|     D.drawText("48 items purloined\n96 vampiric skills\n50 mortal servants", new Point(WIDTH/2, 224), FG_TEXT, {alignX: AlignX.Center}) | ||||
|     D.drawText("48                \n96                \n50                ", new Point(WIDTH/2, 224), FG_BOLD, {alignX: AlignX.Center}) | ||||
|     D.drawText("That feels like a lot!", new Point(0, 288), FG_TEXT) | ||||
|     D.drawText("Your reign continues unimpeded from the shadows. It is now time to", new Point(0, 320), FG_TEXT, {forceWidth: WIDTH}) | ||||
|  | ||||
|     this.#drawpile.draw(); | ||||
|   } | ||||
|  | ||||
|   get blocksHud(): boolean { | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  | ||||
| let active = new EndgameModal(); | ||||
| export function getEndgameModal() { | ||||
|   return active; | ||||
| } | ||||
							
								
								
									
										58
									
								
								src/game.ts
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/game.ts
									
									
									
									
									
								
							| @@ -1,13 +1,13 @@ | ||||
| import {BG_OUTER} from "./colors.ts"; | ||||
| import {D, I} from "./engine/public.ts"; | ||||
| import {IGame, Point, Size} from "./engine/datatypes.ts"; | ||||
| import {getHuntMode} from "./huntmode.ts"; | ||||
| import {getPageLocation, Page, withCamera} from "./layout.ts"; | ||||
| import {getHud} from "./hud.ts"; | ||||
| import {getPageLocation, Page} from "./layout.ts"; | ||||
| import {getHotbar, Hotbar} from "./hotbar.ts"; | ||||
| import {getSkillsModal, SkillsModal} from "./skillsmodal.ts"; | ||||
| import {getSleepModal, SleepModal} from "./sleepmodal.ts"; | ||||
| import {getEndgameModal} from "./vnmodal.ts"; | ||||
| import {getVNModal, VNModal} from "./vnmodal.ts"; | ||||
| import {Gameplay, getGameplay} from "./gameplay.ts"; | ||||
| import {getEndgameModal} from "./endgamemodal.ts"; | ||||
|  | ||||
| class MenuCamera { | ||||
|   // measured in whole screens | ||||
| @@ -33,6 +33,7 @@ class MenuCamera { | ||||
| export class Game implements IGame { | ||||
|   camera: MenuCamera; | ||||
|   page: Page; | ||||
|   #mainThing: Gameplay | VNModal | null; | ||||
|   #bottomThing: SkillsModal | SleepModal | Hotbar | null; | ||||
|  | ||||
|   constructor() { | ||||
| @@ -42,16 +43,13 @@ export class Game implements IGame { | ||||
|     }); | ||||
|     this.page = "Gameplay"; | ||||
|  | ||||
|     this.#mainThing = null; | ||||
|     this.#bottomThing = null; | ||||
|   } | ||||
|  | ||||
|   update() { | ||||
|     if (I.isKeyPressed("w")) { | ||||
|       this.page = "Gameplay" | ||||
|     } | ||||
|     if (I.isKeyPressed("s")) { | ||||
|       this.page = "Thralls" | ||||
|     } | ||||
|     if (I.isKeyPressed("w")) { this.page = "Gameplay" } | ||||
|     if (I.isKeyPressed("s")) { this.page = "Thralls" } | ||||
|  | ||||
|     this.camera.target = getPageLocation(this.page); | ||||
|     D.camera = new Point( | ||||
| @@ -82,23 +80,22 @@ export class Game implements IGame { | ||||
|   } | ||||
|  | ||||
|   updateGameplay() { | ||||
|     this.#chooseMainThing(); | ||||
|     this.#chooseBottomThing(); | ||||
|  | ||||
|     withCamera("Gameplay", () => { | ||||
|       getHuntMode().update(); | ||||
|     }); | ||||
|     withCamera("HUD", () => { getHud().update() }) | ||||
|     this.#bottomThing?.update(); | ||||
|     getEndgameModal().update(); | ||||
|     this.#mainThing?.update(); | ||||
|  | ||||
|     if (!this.#mainThing?.blocksHud) { | ||||
|       this.#bottomThing?.update(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   drawGameplay() { | ||||
|     withCamera("Gameplay", () => { | ||||
|       getHuntMode().draw(); | ||||
|     }); | ||||
|     withCamera("HUD", () => { getHud().draw() }) | ||||
|     this.#bottomThing?.draw() | ||||
|     getEndgameModal().draw(); | ||||
|     this.#mainThing?.draw(); | ||||
|  | ||||
|     if (!this.#mainThing?.blocksHud) { | ||||
|       this.#bottomThing?.draw() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   #chooseBottomThing() { | ||||
| @@ -126,8 +123,21 @@ export class Game implements IGame { | ||||
|     this.#bottomThing = getHotbar(); | ||||
|   } | ||||
|  | ||||
|   // withCamera("Hotbar", () => { getHotbar().draw() }) | ||||
|   #chooseMainThing() { | ||||
|     let vnModal = getVNModal(); | ||||
|     if (vnModal.isShown) { | ||||
|       this.#mainThing = vnModal; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     let endgameModal = getEndgameModal(); | ||||
|     if (endgameModal.isShown) { | ||||
|       this.#mainThing = endgameModal; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     this.#mainThing = getGameplay(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| export let game = new Game(); | ||||
							
								
								
									
										29
									
								
								src/gameplay.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/gameplay.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import {withCamera} from "./layout.ts"; | ||||
| import {getHuntMode} from "./huntmode.ts"; | ||||
| import {getHud} from "./hud.ts"; | ||||
|  | ||||
| export class Gameplay { | ||||
|   update() { | ||||
|     withCamera("Gameplay", () => { | ||||
|       getHuntMode().update(); | ||||
|     }); | ||||
|     withCamera("HUD", () => { getHud().update() }) | ||||
|   } | ||||
|  | ||||
|   draw() { | ||||
|     withCamera("Gameplay", () => { | ||||
|       getHuntMode().draw(); | ||||
|     }); | ||||
|     withCamera("HUD", () => { getHud().draw() }) | ||||
|   } | ||||
|  | ||||
|   get blocksHud(): boolean { | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| let active = new Gameplay(); | ||||
| export function getGameplay(): Gameplay { | ||||
|   return active; | ||||
| } | ||||
|  | ||||
| @@ -1,8 +1,9 @@ | ||||
| import {getPlayerProgress} from "./playerprogress.ts"; | ||||
| import {getHuntMode} from "./huntmode.ts"; | ||||
| import {getSleepModal} from "./sleepmodal.ts"; | ||||
| import {getEndgameModal} from "./vnmodal.ts"; | ||||
| import {getVNModal} from "./vnmodal.ts"; | ||||
| import {getScorer} from "./scorer.ts"; | ||||
| import {getEndgameModal} from "./endgamemodal.ts"; | ||||
|  | ||||
| const N_TURNS: number = 9; | ||||
|  | ||||
| @@ -18,16 +19,17 @@ export class StateManager { | ||||
|   } | ||||
|  | ||||
|   advance() { | ||||
|     this.#turn += 1; | ||||
|     getSleepModal().setShown(false); | ||||
|  | ||||
|     if (this.#turn <= N_TURNS) { | ||||
|     if (this.#turn + 1 <= N_TURNS) { | ||||
|       this.#turn += 1; | ||||
|       getPlayerProgress().refill(); | ||||
|       getHuntMode().replaceMap(); | ||||
|       getSleepModal().setShown(false); | ||||
|     } else { | ||||
|       // TODO: Play a specific scene | ||||
|       let ending = getScorer().pickEnding(); | ||||
|       getEndgameModal().play(ending.scene); | ||||
|       getVNModal().play(ending.scene); | ||||
|       getEndgameModal().show(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| import {D, I} from "./engine/public.ts"; | ||||
| import {AlignX, AlignY, Color, Point} from "./engine/datatypes.ts"; | ||||
| import {BG_OUTER, FG_BOLD} from "./colors.ts"; | ||||
| import {AlignX, AlignY, Point} from "./engine/datatypes.ts"; | ||||
| import {FG_BOLD} from "./colors.ts"; | ||||
| import {withCamera} from "./layout.ts"; | ||||
| import {VNScene, VNSceneMessage, VNScenePart} from "./vnscene.ts"; | ||||
|  | ||||
| const WIDTH = 384; | ||||
| const HEIGHT = 384; | ||||
|  | ||||
| class VNModal { | ||||
| export class VNModal { | ||||
|   #scene: VNScene | null; | ||||
|   #nextIndex = 0; | ||||
|   #cathexis: SceneCathexis | null; | ||||
| @@ -18,6 +18,10 @@ class VNModal { | ||||
|     this.#cathexis = null; | ||||
|   } | ||||
|  | ||||
|   get blocksHud(): boolean { | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   get isShown(): boolean { | ||||
|     return this.#scene != null; | ||||
|   } | ||||
| @@ -26,37 +30,40 @@ class VNModal { | ||||
|     this.#scene = scene | ||||
|     this.#nextIndex = 0; | ||||
|     this.#cathexis = null; | ||||
|  | ||||
|     this.#fixCathexis(); | ||||
|   } | ||||
|  | ||||
|   #fixCathexis() { | ||||
|     if (this.#cathexis?.isDone()) { | ||||
|       this.#cathexis = null; | ||||
|     } | ||||
|     if (this.#scene == null) { | ||||
|       return; | ||||
|     } | ||||
|     if (this.#cathexis == null) { | ||||
|       let ix = this.#nextIndex | ||||
|       if (ix < this.#scene?.length) { | ||||
|         this.#cathexis = createCathexis(this.#scene[ix]) | ||||
|         this.#nextIndex += 1; | ||||
|       } else { | ||||
|         this.#scene = null; | ||||
|     while (true) { | ||||
|       if (this.#cathexis?.isDone()) { | ||||
|         this.#cathexis = null; | ||||
|       } | ||||
|       if (this.#cathexis != null) { | ||||
|         return; | ||||
|       } | ||||
|  | ||||
|       if (this.#scene == null) { | ||||
|         return; | ||||
|       } | ||||
|       if (this.#cathexis == null) { | ||||
|         let ix = this.#nextIndex | ||||
|         if (ix < this.#scene?.length) { | ||||
|           this.#cathexis = createCathexis(this.#scene[ix]) | ||||
|           this.#nextIndex += 1; | ||||
|         } else { | ||||
|           this.#scene = null; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   update() { | ||||
|     this.#fixCathexis() | ||||
|     if (!this.isShown) { return } | ||||
|  | ||||
|     withCamera("FullscreenPopover", () => this.#update()) | ||||
|   } | ||||
|  | ||||
|   draw() { | ||||
|     if (!this.isShown) { return } | ||||
|  | ||||
|     D.fillRect(new Point(0, 0), D.size, new Color(BG_OUTER.r, BG_OUTER.g, BG_OUTER.b, 255)); | ||||
|     withCamera("FullscreenPopover", () => this.#draw()) | ||||
|   } | ||||
|  | ||||
| @@ -86,10 +93,12 @@ function createCathexis(part: VNScenePart): SceneCathexis { | ||||
| class SceneMessageCathexis { | ||||
|   #message: VNSceneMessage; | ||||
|   #done: boolean; | ||||
|   #gotOneFrame: boolean; | ||||
|  | ||||
|   constructor (message: VNSceneMessage) { | ||||
|     this.#message = message; | ||||
|     this.#done = false; | ||||
|     this.#gotOneFrame = false; | ||||
|   } | ||||
|  | ||||
|   isDone() { | ||||
| @@ -97,8 +106,11 @@ class SceneMessageCathexis { | ||||
|   } | ||||
|  | ||||
|   update() { | ||||
|     let firstFrame = !this.#gotOneFrame; | ||||
|     this.#gotOneFrame = true; | ||||
|  | ||||
|     // TODO: SFX | ||||
|     if (I.isAnythingPressed()) { | ||||
|     if (!firstFrame && I.isAnythingPressed()) { | ||||
|       this.#done = true; | ||||
|     } | ||||
|   } | ||||
| @@ -113,6 +125,6 @@ class SceneMessageCathexis { | ||||
| } | ||||
|  | ||||
| let active: VNModal = new VNModal(); | ||||
| export function getEndgameModal() { | ||||
| export function getVNModal() { | ||||
|   return active; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user