common.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import * as audio from '../audio';
  2. import * as background from '../background';
  3. import * as level from '../level';
  4. export interface Screen {
  5. readonly name: string;
  6. handleInput(key: string): void;
  7. enter(): void;
  8. exit(): void;
  9. transitionExit(): void;
  10. }
  11. export class ScreenManager {
  12. activeScreen: Screen | null = null;
  13. lastScreen: Screen | null = null;
  14. pendingExit: boolean = false;
  15. constructor(readonly container: HTMLElement) {
  16. this.container.addEventListener('transitionend', (event: TransitionEvent) => {
  17. if (this.pendingExit && event.propertyName === 'opacity') {
  18. this.finishExit();
  19. }
  20. });
  21. }
  22. switchScreen(nextScreen: Screen | null): void {
  23. if (this.pendingExit) {
  24. this.finishExit();
  25. }
  26. if (this.activeScreen != null) {
  27. this.container.classList.remove(this.activeScreen.name);
  28. this.pendingExit = true;
  29. this.lastScreen = this.activeScreen;
  30. this.activeScreen.exit();
  31. }
  32. this.activeScreen = nextScreen;
  33. if (nextScreen != null) {
  34. nextScreen.enter();
  35. this.container.classList.add(nextScreen.name);
  36. }
  37. }
  38. finishExit() {
  39. this.pendingExit = false;
  40. if (this.lastScreen !== null) {
  41. this.lastScreen.transitionExit();
  42. this.lastScreen = null;
  43. }
  44. }
  45. }
  46. interface GameSounds {
  47. selectSound: audio.Track | null,
  48. decideSound: audio.Track | null
  49. }
  50. export interface GameContext {
  51. container: HTMLElement;
  52. audioManager: audio.AudioManager;
  53. bgManager: background.BackgroundManager;
  54. loadTemplate: (id: string) => DocumentFragment;
  55. assets: GameSounds | null;
  56. config: level.Config | null;
  57. switchScreen(screen: Screen): void;
  58. }