brick-engine-js 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.local.example +2 -0
- package/.github/workflows/publish.yml +73 -0
- package/.prettierignore +2 -0
- package/.prettierrc.json +8 -0
- package/README.adoc +84 -0
- package/dist/8e23286c2fdf41fd795f.svg +32 -0
- package/dist/CNAME +1 -0
- package/dist/app.js +2 -0
- package/dist/app.js.map +1 -0
- package/dist/brick-engine.js +2 -0
- package/dist/brick-engine.js.map +1 -0
- package/dist/config/configs.d.ts +180 -0
- package/dist/config/configs.test.d.ts +1 -0
- package/dist/config/env.d.ts +2 -0
- package/dist/config/env.test.d.ts +1 -0
- package/dist/config/styles.d.ts +0 -0
- package/dist/core/Game.d.ts +107 -0
- package/dist/core/Game.test.d.ts +1 -0
- package/dist/core/InitialStateSnapshot.d.ts +19 -0
- package/dist/core/InitialStateSnapshot.test.d.ts +1 -0
- package/dist/core/helpers/CellHelper.d.ts +13 -0
- package/dist/core/helpers/CellHelper.test.d.ts +1 -0
- package/dist/core/helpers/ControlInputHandlerHelper.d.ts +32 -0
- package/dist/core/helpers/ControlInputHandlerHelper.test.d.ts +1 -0
- package/dist/core/helpers/CoordinateHelper.d.ts +54 -0
- package/dist/core/helpers/CoordinateHelper.test.d.ts +1 -0
- package/dist/core/helpers/InterfaceIdentifierHelper.d.ts +7 -0
- package/dist/core/helpers/InterfaceIdentifierHelper.test.d.ts +1 -0
- package/dist/core/helpers/RelativeValuesHelper.d.ts +23 -0
- package/dist/core/helpers/RelativeValuesHelper.test.d.ts +1 -0
- package/dist/core/module/control/GameControl.d.ts +62 -0
- package/dist/core/module/control/GameControl.test.d.ts +1 -0
- package/dist/core/module/control/GameControlKeyBinding.d.ts +36 -0
- package/dist/core/module/control/GameControlKeyBinding.test.d.ts +1 -0
- package/dist/core/module/grid/GameGrid.d.ts +399 -0
- package/dist/core/module/grid/GameGrid.test.d.ts +1 -0
- package/dist/core/module/grid/GameHudGrid.d.ts +24 -0
- package/dist/core/module/grid/GameHudGrid.test.d.ts +1 -0
- package/dist/core/module/grid/engines/GridAnalysisEngine.d.ts +29 -0
- package/dist/core/module/grid/engines/GridAnalysisEngine.test.d.ts +1 -0
- package/dist/core/module/grid/engines/GridLineEngine.d.ts +56 -0
- package/dist/core/module/grid/engines/GridLineEngine.test.d.ts +1 -0
- package/dist/core/module/grid/engines/GridMovementEngine.d.ts +29 -0
- package/dist/core/module/grid/engines/GridMovementEngine.test.d.ts +1 -0
- package/dist/core/module/grid/engines/GridRegionEngine.d.ts +26 -0
- package/dist/core/module/grid/engines/GridRegionEngine.test.d.ts +1 -0
- package/dist/core/module/grid/engines/GridTransformEngine.d.ts +24 -0
- package/dist/core/module/grid/engines/GridTransformEngine.test.d.ts +1 -0
- package/dist/core/module/renderer/DisplayRenderer.d.ts +51 -0
- package/dist/core/module/renderer/DisplayRenderer.test.d.ts +1 -0
- package/dist/core/module/renderer/GameRenderer.d.ts +59 -0
- package/dist/core/module/renderer/GameRenderer.test.d.ts +1 -0
- package/dist/core/module/renderer/HudRenderer.d.ts +56 -0
- package/dist/core/module/renderer/HudRenderer.test.d.ts +1 -0
- package/dist/core/module/score/GameScore.d.ts +117 -0
- package/dist/core/module/score/GameScore.test.d.ts +1 -0
- package/dist/core/module/session/GameSession.d.ts +20 -0
- package/dist/core/module/session/GameSession.test.d.ts +1 -0
- package/dist/core/module/sound/GameSound.d.ts +85 -0
- package/dist/core/module/sound/GameSound.test.d.ts +1 -0
- package/dist/core/module/state/GameState.d.ts +172 -0
- package/dist/core/module/state/GameState.test.d.ts +1 -0
- package/dist/core/module/text/GameText.d.ts +87 -0
- package/dist/core/module/text/GameText.test.d.ts +1 -0
- package/dist/core/module/time/GameTime.d.ts +76 -0
- package/dist/core/module/time/GameTime.test.d.ts +1 -0
- package/dist/core/types/Interfaces.d.ts +53 -0
- package/dist/core/types/Types.d.ts +114 -0
- package/dist/core/types/enums.d.ts +106 -0
- package/dist/core/types/modules.d.ts +723 -0
- package/dist/css/app.743066d8e4172b0e73f9.css +824 -0
- package/dist/css/app.743066d8e4172b0e73f9.css.map +1 -0
- package/dist/docs/GAME_DEVELOPER_GUIDE.html +727 -0
- package/dist/docs/brick-engine-guide.html +610 -0
- package/dist/docs/diagrams/lifecycle.mmd +19 -0
- package/dist/docs/documentation_style_guide.html +994 -0
- package/dist/docs/getting-started.html +648 -0
- package/dist/docs/images/lifecycle.svg +1 -0
- package/dist/docs/index.html +593 -0
- package/dist/docs/jsdoc_standard.html +656 -0
- package/dist/docs/publishing.html +573 -0
- package/dist/docs/reference/enums/Color.html +533 -0
- package/dist/docs/reference/enums/ControlEventType.html +505 -0
- package/dist/docs/reference/enums/ControlKey.html +529 -0
- package/dist/docs/reference/enums/FontAlignment.html +545 -0
- package/dist/docs/reference/enums/FontSize.html +517 -0
- package/dist/docs/reference/enums/Sound.html +558 -0
- package/dist/docs/reference/enums/StateProperty.html +525 -0
- package/dist/docs/reference/helpers/CellHelper.html +520 -0
- package/dist/docs/reference/helpers/ControlInputHandlerHelper.html +569 -0
- package/dist/docs/reference/helpers/CoordinateHelper.html +703 -0
- package/dist/docs/reference/helpers/RelativeValuesHelper.html +560 -0
- package/dist/docs/reference/interfaces/Debuggable.html +501 -0
- package/dist/docs/reference/interfaces/GameModules.html +544 -0
- package/dist/docs/reference/interfaces/Initializable.html +495 -0
- package/dist/docs/reference/interfaces/RendererInitializable.html +517 -0
- package/dist/docs/reference/interfaces/StateSyncable.html +542 -0
- package/dist/docs/reference/interfaces/modules/Control.html +648 -0
- package/dist/docs/reference/interfaces/modules/Grid.html +1256 -0
- package/dist/docs/reference/interfaces/modules/Renderer.html +522 -0
- package/dist/docs/reference/interfaces/modules/RendererComposite.html +577 -0
- package/dist/docs/reference/interfaces/modules/Score.html +669 -0
- package/dist/docs/reference/interfaces/modules/Session.html +585 -0
- package/dist/docs/reference/interfaces/modules/State.html +897 -0
- package/dist/docs/reference/interfaces/modules/Text.html +668 -0
- package/dist/docs/reference/interfaces/modules/Time.html +684 -0
- package/dist/docs/reference/modules/Debugger.html +579 -0
- package/dist/docs/reference/modules/DisplayRenderer.html +557 -0
- package/dist/docs/reference/modules/Game.html +909 -0
- package/dist/docs/reference/modules/GameControl.html +716 -0
- package/dist/docs/reference/modules/GameGrid.html +1910 -0
- package/dist/docs/reference/modules/GameHudGrid.html +508 -0
- package/dist/docs/reference/modules/GameMenu.html +538 -0
- package/dist/docs/reference/modules/GameRenderer.html +589 -0
- package/dist/docs/reference/modules/GameScore.html +664 -0
- package/dist/docs/reference/modules/GameSession.html +533 -0
- package/dist/docs/reference/modules/GameSound.html +636 -0
- package/dist/docs/reference/modules/GameState.html +922 -0
- package/dist/docs/reference/modules/GameText.html +701 -0
- package/dist/docs/reference/modules/GameTime.html +696 -0
- package/dist/docs/reference/modules/HudRenderer.html +568 -0
- package/dist/docs/reference/modules/InitialStateSnapshot.html +557 -0
- package/dist/docs/reference/modules/SessionModal.html +520 -0
- package/dist/docs/reference/types/Axis.html +505 -0
- package/dist/docs/reference/types/Cell.html +514 -0
- package/dist/docs/reference/types/ControlCallback.html +488 -0
- package/dist/docs/reference/types/Coordinate.html +510 -0
- package/dist/docs/reference/types/GameEntry.html +514 -0
- package/dist/docs/reference/types/GameEvent.html +514 -0
- package/dist/docs/reference/types/Piece.html +506 -0
- package/dist/docs/reference/types/RendererMetrics.html +514 -0
- package/dist/docs/reference/types/Vector.html +509 -0
- package/dist/docs/testing_best_practices.html +770 -0
- package/dist/favicon.ico +0 -0
- package/dist/fonts/digital-7.monoitalic.ttf +0 -0
- package/dist/images/cell.svg +32 -0
- package/dist/images/close.png +0 -0
- package/dist/images/games.png +0 -0
- package/dist/images/github.png +0 -0
- package/dist/images/letter-a.png +0 -0
- package/dist/images/letter-d.png +0 -0
- package/dist/images/letter-j.png +0 -0
- package/dist/images/letter-s.png +0 -0
- package/dist/images/letter-w.png +0 -0
- package/dist/images/meta-image.png +0 -0
- package/dist/images/number-1.png +0 -0
- package/dist/images/number-2.png +0 -0
- package/dist/images/number-3.png +0 -0
- package/dist/images/number-4.png +0 -0
- package/dist/images/number-5.png +0 -0
- package/dist/images/number-6.png +0 -0
- package/dist/images/splash.gif +0 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.html +1 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.test.d.ts +1 -0
- package/dist/menu/GameMenu.d.ts +15 -0
- package/dist/menu/GameMenu.test.d.ts +1 -0
- package/dist/menu/GameMenuSingleton.d.ts +6 -0
- package/dist/menu/GameMenuSingleton.test.d.ts +1 -0
- package/dist/menu/GameRepository.d.ts +7 -0
- package/dist/menu/GameRepository.test.d.ts +1 -0
- package/dist/menu/manager/GameManager.d.ts +6 -0
- package/dist/menu/manager/GameManager.test.d.ts +1 -0
- package/dist/sounds/sound_00.wav +0 -0
- package/dist/sounds/sound_01.wav +0 -0
- package/dist/sounds/sound_02.wav +0 -0
- package/dist/sounds/sound_03.wav +0 -0
- package/dist/sounds/sound_04.wav +0 -0
- package/dist/sounds/sound_05.wav +0 -0
- package/dist/sounds/sound_06.wav +0 -0
- package/dist/sounds/sound_07.wav +0 -0
- package/dist/sounds/sound_08.wav +0 -0
- package/dist/sounds/sound_09.wav +0 -0
- package/dist/sounds/sound_10.wav +0 -0
- package/dist/sounds/sound_11.wav +0 -0
- package/dist/sounds/sound_12.wav +0 -0
- package/dist/sounds/sound_13.wav +0 -0
- package/dist/sounds/sound_14.wav +0 -0
- package/dist/sounds/sound_15.wav +0 -0
- package/dist/types/interfaces.d.ts +5 -0
- package/dist/vendor/p5.min.js +1 -0
- package/dist/view/Debugger.d.ts +12 -0
- package/dist/view/Debugger.test.d.ts +1 -0
- package/dist/view/GameView.d.ts +101 -0
- package/dist/view/GameView.test.d.ts +1 -0
- package/dist/view/SessionModal.d.ts +12 -0
- package/dist/view/SessionModal.test.d.ts +4 -0
- package/dist/view/components/layout/ButtonLayout.d.ts +25 -0
- package/dist/view/components/layout/ButtonLayout.test.d.ts +1 -0
- package/dist/view/components/layout/ContainerLayout.d.ts +23 -0
- package/dist/view/components/layout/ContainerLayout.test.d.ts +1 -0
- package/dist/view/components/layout/FrameLayout.d.ts +11 -0
- package/dist/view/components/layout/FrameLayout.test.d.ts +1 -0
- package/dist/view/components/ui/BigButton.d.ts +13 -0
- package/dist/view/components/ui/BigButton.test.d.ts +1 -0
- package/dist/view/components/ui/Button.d.ts +12 -0
- package/dist/view/components/ui/Button.test.d.ts +1 -0
- package/dist/view/components/ui/Canvas.d.ts +22 -0
- package/dist/view/components/ui/Canvas.test.d.ts +1 -0
- package/dist/view/components/ui/SmallButton.d.ts +13 -0
- package/dist/view/components/ui/SmallButton.test.d.ts +1 -0
- package/dist/view/theme/applyColors.d.ts +10 -0
- package/dist/view/theme/applyColors.test.d.ts +1 -0
- package/dist/view/theme/dimensions.d.ts +13 -0
- package/dist/view/theme/dimensions.test.d.ts +1 -0
- package/docs/GAME_DEVELOPER_GUIDE.adoc +167 -0
- package/docs/brick-engine-guide.adoc +87 -0
- package/docs/diagrams/lifecycle.mmd +19 -0
- package/docs/documentation_style_guide.adoc +210 -0
- package/docs/getting-started.adoc +147 -0
- package/docs/images/lifecycle.svg +1 -0
- package/docs/jsdoc_standard.adoc +109 -0
- package/docs/publishing.adoc +58 -0
- package/docs/reference/enums/Color.adoc +35 -0
- package/docs/reference/enums/ControlEventType.adoc +28 -0
- package/docs/reference/enums/ControlKey.adoc +34 -0
- package/docs/reference/enums/FontAlignment.adoc +43 -0
- package/docs/reference/enums/FontSize.adoc +31 -0
- package/docs/reference/enums/Sound.adoc +42 -0
- package/docs/reference/enums/StateProperty.adoc +33 -0
- package/docs/reference/helpers/CellHelper.adoc +37 -0
- package/docs/reference/helpers/ControlInputHandlerHelper.adoc +57 -0
- package/docs/reference/helpers/CoordinateHelper.adoc +118 -0
- package/docs/reference/helpers/RelativeValuesHelper.adoc +53 -0
- package/docs/reference/interfaces/Debuggable.adoc +29 -0
- package/docs/reference/interfaces/GameModules.adoc +35 -0
- package/docs/reference/interfaces/Initializable.adoc +24 -0
- package/docs/reference/interfaces/RendererInitializable.adoc +33 -0
- package/docs/reference/interfaces/StateSyncable.adoc +41 -0
- package/docs/reference/interfaces/modules/Control.adoc +98 -0
- package/docs/reference/interfaces/modules/Grid.adoc +411 -0
- package/docs/reference/interfaces/modules/Renderer.adoc +34 -0
- package/docs/reference/interfaces/modules/RendererComposite.adoc +57 -0
- package/docs/reference/interfaces/modules/Score.adoc +107 -0
- package/docs/reference/interfaces/modules/Session.adoc +66 -0
- package/docs/reference/interfaces/modules/State.adoc +290 -0
- package/docs/reference/interfaces/modules/Text.adoc +110 -0
- package/docs/reference/interfaces/modules/Time.adoc +119 -0
- package/docs/reference/modules/Debugger.adoc +71 -0
- package/docs/reference/modules/DisplayRenderer.adoc +55 -0
- package/docs/reference/modules/Game.adoc +256 -0
- package/docs/reference/modules/GameControl.adoc +139 -0
- package/docs/reference/modules/GameGrid.adoc +794 -0
- package/docs/reference/modules/GameHudGrid.adoc +38 -0
- package/docs/reference/modules/GameMenu.adoc +39 -0
- package/docs/reference/modules/GameRenderer.adoc +79 -0
- package/docs/reference/modules/GameScore.adoc +138 -0
- package/docs/reference/modules/GameSession.adoc +43 -0
- package/docs/reference/modules/GameSound.adoc +111 -0
- package/docs/reference/modules/GameState.adoc +318 -0
- package/docs/reference/modules/GameText.adoc +139 -0
- package/docs/reference/modules/GameTime.adoc +141 -0
- package/docs/reference/modules/HudRenderer.adoc +56 -0
- package/docs/reference/modules/InitialStateSnapshot.adoc +47 -0
- package/docs/reference/modules/SessionModal.adoc +34 -0
- package/docs/reference/types/Axis.adoc +28 -0
- package/docs/reference/types/Cell.adoc +29 -0
- package/docs/reference/types/ControlCallback.adoc +23 -0
- package/docs/reference/types/Coordinate.adoc +29 -0
- package/docs/reference/types/GameEntry.adoc +29 -0
- package/docs/reference/types/GameEvent.adoc +29 -0
- package/docs/reference/types/Piece.adoc +32 -0
- package/docs/reference/types/RendererMetrics.adoc +29 -0
- package/docs/reference/types/Vector.adoc +28 -0
- package/docs/testing_best_practices.adoc +190 -0
- package/eslint.config.mjs +29 -0
- package/package.json +54 -0
- package/public/CNAME +1 -0
- package/public/docs/GAME_DEVELOPER_GUIDE.html +727 -0
- package/public/docs/brick-engine-guide.html +610 -0
- package/public/docs/diagrams/lifecycle.mmd +19 -0
- package/public/docs/documentation_style_guide.html +994 -0
- package/public/docs/getting-started.html +648 -0
- package/public/docs/images/lifecycle.svg +1 -0
- package/public/docs/index.html +593 -0
- package/public/docs/jsdoc_standard.html +656 -0
- package/public/docs/publishing.html +573 -0
- package/public/docs/reference/enums/Color.html +533 -0
- package/public/docs/reference/enums/ControlEventType.html +505 -0
- package/public/docs/reference/enums/ControlKey.html +529 -0
- package/public/docs/reference/enums/FontAlignment.html +545 -0
- package/public/docs/reference/enums/FontSize.html +517 -0
- package/public/docs/reference/enums/Sound.html +558 -0
- package/public/docs/reference/enums/StateProperty.html +525 -0
- package/public/docs/reference/helpers/CellHelper.html +520 -0
- package/public/docs/reference/helpers/ControlInputHandlerHelper.html +569 -0
- package/public/docs/reference/helpers/CoordinateHelper.html +703 -0
- package/public/docs/reference/helpers/RelativeValuesHelper.html +560 -0
- package/public/docs/reference/interfaces/Debuggable.html +501 -0
- package/public/docs/reference/interfaces/GameModules.html +544 -0
- package/public/docs/reference/interfaces/Initializable.html +495 -0
- package/public/docs/reference/interfaces/RendererInitializable.html +517 -0
- package/public/docs/reference/interfaces/StateSyncable.html +542 -0
- package/public/docs/reference/interfaces/modules/Control.html +648 -0
- package/public/docs/reference/interfaces/modules/Grid.html +1256 -0
- package/public/docs/reference/interfaces/modules/Renderer.html +522 -0
- package/public/docs/reference/interfaces/modules/RendererComposite.html +577 -0
- package/public/docs/reference/interfaces/modules/Score.html +669 -0
- package/public/docs/reference/interfaces/modules/Session.html +585 -0
- package/public/docs/reference/interfaces/modules/State.html +897 -0
- package/public/docs/reference/interfaces/modules/Text.html +668 -0
- package/public/docs/reference/interfaces/modules/Time.html +684 -0
- package/public/docs/reference/modules/Debugger.html +579 -0
- package/public/docs/reference/modules/DisplayRenderer.html +557 -0
- package/public/docs/reference/modules/Game.html +909 -0
- package/public/docs/reference/modules/GameControl.html +716 -0
- package/public/docs/reference/modules/GameGrid.html +1910 -0
- package/public/docs/reference/modules/GameHudGrid.html +508 -0
- package/public/docs/reference/modules/GameMenu.html +538 -0
- package/public/docs/reference/modules/GameRenderer.html +589 -0
- package/public/docs/reference/modules/GameScore.html +664 -0
- package/public/docs/reference/modules/GameSession.html +533 -0
- package/public/docs/reference/modules/GameSound.html +636 -0
- package/public/docs/reference/modules/GameState.html +922 -0
- package/public/docs/reference/modules/GameText.html +701 -0
- package/public/docs/reference/modules/GameTime.html +696 -0
- package/public/docs/reference/modules/HudRenderer.html +568 -0
- package/public/docs/reference/modules/InitialStateSnapshot.html +557 -0
- package/public/docs/reference/modules/SessionModal.html +520 -0
- package/public/docs/reference/types/Axis.html +505 -0
- package/public/docs/reference/types/Cell.html +514 -0
- package/public/docs/reference/types/ControlCallback.html +488 -0
- package/public/docs/reference/types/Coordinate.html +510 -0
- package/public/docs/reference/types/GameEntry.html +514 -0
- package/public/docs/reference/types/GameEvent.html +514 -0
- package/public/docs/reference/types/Piece.html +506 -0
- package/public/docs/reference/types/RendererMetrics.html +514 -0
- package/public/docs/reference/types/Vector.html +509 -0
- package/public/docs/testing_best_practices.html +770 -0
- package/public/favicon.ico +0 -0
- package/public/fonts/digital-7.monoitalic.ttf +0 -0
- package/public/images/cell.svg +32 -0
- package/public/images/close.png +0 -0
- package/public/images/games.png +0 -0
- package/public/images/github.png +0 -0
- package/public/images/letter-a.png +0 -0
- package/public/images/letter-d.png +0 -0
- package/public/images/letter-j.png +0 -0
- package/public/images/letter-s.png +0 -0
- package/public/images/letter-w.png +0 -0
- package/public/images/meta-image.png +0 -0
- package/public/images/number-1.png +0 -0
- package/public/images/number-2.png +0 -0
- package/public/images/number-3.png +0 -0
- package/public/images/number-4.png +0 -0
- package/public/images/number-5.png +0 -0
- package/public/images/number-6.png +0 -0
- package/public/images/splash.gif +0 -0
- package/public/index.html +15 -0
- package/public/sounds/sound_00.wav +0 -0
- package/public/sounds/sound_01.wav +0 -0
- package/public/sounds/sound_02.wav +0 -0
- package/public/sounds/sound_03.wav +0 -0
- package/public/sounds/sound_04.wav +0 -0
- package/public/sounds/sound_05.wav +0 -0
- package/public/sounds/sound_06.wav +0 -0
- package/public/sounds/sound_07.wav +0 -0
- package/public/sounds/sound_08.wav +0 -0
- package/public/sounds/sound_09.wav +0 -0
- package/public/sounds/sound_10.wav +0 -0
- package/public/sounds/sound_11.wav +0 -0
- package/public/sounds/sound_12.wav +0 -0
- package/public/sounds/sound_13.wav +0 -0
- package/public/sounds/sound_14.wav +0 -0
- package/public/sounds/sound_15.wav +0 -0
- package/public/style/body.css +86 -0
- package/public/style/buttons.css +233 -0
- package/public/style/debugger.css +117 -0
- package/public/style/sessionModal.css +155 -0
- package/public/style/sourceCodeAndCommands.css +74 -0
- package/public/style/splash.css +13 -0
- package/public/style/theme.css +137 -0
- package/scripts/generate-diagrams.sh +20 -0
- package/scripts/generate-docs.js +111 -0
- package/src/client-game.d.ts +1 -0
- package/src/config/configs.test.ts +20 -0
- package/src/config/configs.ts +197 -0
- package/src/config/env.test.ts +59 -0
- package/src/config/env.ts +7 -0
- package/src/config/styles.ts +5 -0
- package/src/core/Game.test.ts +167 -0
- package/src/core/Game.ts +307 -0
- package/src/core/InitialStateSnapshot.test.ts +51 -0
- package/src/core/InitialStateSnapshot.ts +46 -0
- package/src/core/helpers/CellHelper.test.ts +33 -0
- package/src/core/helpers/CellHelper.ts +21 -0
- package/src/core/helpers/ControlInputHandlerHelper.test.ts +116 -0
- package/src/core/helpers/ControlInputHandlerHelper.ts +68 -0
- package/src/core/helpers/CoordinateHelper.test.ts +113 -0
- package/src/core/helpers/CoordinateHelper.ts +82 -0
- package/src/core/helpers/InterfaceIdentifierHelper.test.ts +122 -0
- package/src/core/helpers/InterfaceIdentifierHelper.ts +43 -0
- package/src/core/helpers/RelativeValuesHelper.test.ts +47 -0
- package/src/core/helpers/RelativeValuesHelper.ts +29 -0
- package/src/core/module/control/GameControl.test.ts +82 -0
- package/src/core/module/control/GameControl.ts +142 -0
- package/src/core/module/control/GameControlKeyBinding.test.ts +59 -0
- package/src/core/module/control/GameControlKeyBinding.ts +92 -0
- package/src/core/module/grid/GameGrid.test.ts +83 -0
- package/src/core/module/grid/GameGrid.ts +610 -0
- package/src/core/module/grid/GameHudGrid.test.ts +22 -0
- package/src/core/module/grid/GameHudGrid.ts +40 -0
- package/src/core/module/grid/engines/GridAnalysisEngine.test.ts +157 -0
- package/src/core/module/grid/engines/GridAnalysisEngine.ts +124 -0
- package/src/core/module/grid/engines/GridLineEngine.test.ts +132 -0
- package/src/core/module/grid/engines/GridLineEngine.ts +165 -0
- package/src/core/module/grid/engines/GridMovementEngine.test.ts +125 -0
- package/src/core/module/grid/engines/GridMovementEngine.ts +113 -0
- package/src/core/module/grid/engines/GridRegionEngine.test.ts +136 -0
- package/src/core/module/grid/engines/GridRegionEngine.ts +52 -0
- package/src/core/module/grid/engines/GridTransformEngine.test.ts +98 -0
- package/src/core/module/grid/engines/GridTransformEngine.ts +70 -0
- package/src/core/module/renderer/DisplayRenderer.test.ts +86 -0
- package/src/core/module/renderer/DisplayRenderer.ts +152 -0
- package/src/core/module/renderer/GameRenderer.test.ts +103 -0
- package/src/core/module/renderer/GameRenderer.ts +144 -0
- package/src/core/module/renderer/HudRenderer.test.ts +108 -0
- package/src/core/module/renderer/HudRenderer.ts +203 -0
- package/src/core/module/score/GameScore.test.ts +71 -0
- package/src/core/module/score/GameScore.ts +188 -0
- package/src/core/module/session/GameSession.test.ts +176 -0
- package/src/core/module/session/GameSession.ts +103 -0
- package/src/core/module/sound/GameSound.test.ts +117 -0
- package/src/core/module/sound/GameSound.ts +229 -0
- package/src/core/module/state/GameState.test.ts +101 -0
- package/src/core/module/state/GameState.ts +339 -0
- package/src/core/module/text/GameText.test.ts +87 -0
- package/src/core/module/text/GameText.ts +150 -0
- package/src/core/module/time/GameTime.test.ts +86 -0
- package/src/core/module/time/GameTime.ts +144 -0
- package/src/core/types/Interfaces.ts +59 -0
- package/src/core/types/Types.ts +124 -0
- package/src/core/types/enums.ts +113 -0
- package/src/core/types/modules.ts +841 -0
- package/src/index.test.ts +15 -0
- package/src/index.ts +9 -0
- package/src/main.test.ts +137 -0
- package/src/main.ts +77 -0
- package/src/menu/GameMenu.test.ts +157 -0
- package/src/menu/GameMenu.ts +124 -0
- package/src/menu/GameMenuSingleton.test.ts +26 -0
- package/src/menu/GameMenuSingleton.ts +13 -0
- package/src/menu/GameRepository.test.ts +46 -0
- package/src/menu/GameRepository.ts +47 -0
- package/src/menu/manager/GameManager.test.ts +68 -0
- package/src/menu/manager/GameManager.ts +50 -0
- package/src/types/global.d.ts +8 -0
- package/src/types/interfaces.ts +5 -0
- package/src/view/Debugger.test.ts +152 -0
- package/src/view/Debugger.ts +124 -0
- package/src/view/GameView.test.ts +95 -0
- package/src/view/GameView.ts +244 -0
- package/src/view/SessionModal.test.ts +141 -0
- package/src/view/SessionModal.ts +73 -0
- package/src/view/components/layout/ButtonLayout.test.ts +28 -0
- package/src/view/components/layout/ButtonLayout.ts +63 -0
- package/src/view/components/layout/ContainerLayout.test.ts +48 -0
- package/src/view/components/layout/ContainerLayout.ts +50 -0
- package/src/view/components/layout/FrameLayout.test.ts +24 -0
- package/src/view/components/layout/FrameLayout.ts +25 -0
- package/src/view/components/ui/BigButton.test.ts +28 -0
- package/src/view/components/ui/BigButton.ts +31 -0
- package/src/view/components/ui/Button.test.ts +30 -0
- package/src/view/components/ui/Button.ts +30 -0
- package/src/view/components/ui/Canvas.test.ts +32 -0
- package/src/view/components/ui/Canvas.ts +34 -0
- package/src/view/components/ui/SmallButton.test.ts +48 -0
- package/src/view/components/ui/SmallButton.ts +32 -0
- package/src/view/theme/applyColors.test.ts +47 -0
- package/src/view/theme/applyColors.ts +38 -0
- package/src/view/theme/dimensions.test.ts +34 -0
- package/src/view/theme/dimensions.ts +53 -0
- package/tsconfig.json +16 -0
- package/vitest.config.ts +14 -0
- package/webpack.config.js +133 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import p5 from 'p5';
|
|
2
|
+
|
|
3
|
+
import configs from '../config/configs';
|
|
4
|
+
|
|
5
|
+
import applyColors from './theme/applyColors';
|
|
6
|
+
import dimensions from './theme/dimensions';
|
|
7
|
+
|
|
8
|
+
import ButtonLayout from './components/layout/ButtonLayout';
|
|
9
|
+
import ContainerLayout from './components/layout/ContainerLayout';
|
|
10
|
+
import FrameLayout from './components/layout/FrameLayout';
|
|
11
|
+
|
|
12
|
+
import BigButton from './components/ui/BigButton';
|
|
13
|
+
import Button from './components/ui/Button';
|
|
14
|
+
import Canvas from './components/ui/Canvas';
|
|
15
|
+
import SmallButton from './components/ui/SmallButton';
|
|
16
|
+
import { ControlKey } from '../core/types/enums';
|
|
17
|
+
import { Control } from '../core/types/modules';
|
|
18
|
+
import ControlInputHandler from '../core/helpers/ControlInputHandlerHelper';
|
|
19
|
+
import Debugger from './Debugger';
|
|
20
|
+
import { GameModules } from '../core/types/Types';
|
|
21
|
+
import SessionModal from './SessionModal';
|
|
22
|
+
|
|
23
|
+
// prettier-ignore
|
|
24
|
+
/**
|
|
25
|
+
* Responsible for rendering the game body and handling control events.
|
|
26
|
+
*
|
|
27
|
+
* This class acts as the main view controller, orchestrating the layout,
|
|
28
|
+
* styles, and user interaction (clicks and holds) for the game.
|
|
29
|
+
*
|
|
30
|
+
* @class
|
|
31
|
+
*/
|
|
32
|
+
export default class GameView {
|
|
33
|
+
private _onOffBtn : p5.Element;
|
|
34
|
+
private _startPauseBtn : p5.Element;
|
|
35
|
+
private _soundBtn : p5.Element;
|
|
36
|
+
private _resetBtn : p5.Element;
|
|
37
|
+
private _exitBtn : p5.Element;
|
|
38
|
+
private _enableColorBtn : p5.Element;
|
|
39
|
+
|
|
40
|
+
private _upBtn : p5.Element;
|
|
41
|
+
private _downBtn : p5.Element;
|
|
42
|
+
private _rightBtn : p5.Element;
|
|
43
|
+
private _leftBtn : p5.Element;
|
|
44
|
+
|
|
45
|
+
private _actionBtn : p5.Element;
|
|
46
|
+
|
|
47
|
+
private _parent : HTMLElement;
|
|
48
|
+
private _p : p5;
|
|
49
|
+
private _inputHandler : ControlInputHandler;
|
|
50
|
+
|
|
51
|
+
private _cachedCanvas : { canvas: p5.Element; canvasWidth: number; canvasHeight: number };
|
|
52
|
+
|
|
53
|
+
private _debugger : Debugger;
|
|
54
|
+
private _sessionModal : SessionModal;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Creates an instance of GameView.
|
|
58
|
+
*
|
|
59
|
+
* @param p - The p5 instance used for rendering and event handling.
|
|
60
|
+
* @param parent - The DOM element where the game view will be attached.
|
|
61
|
+
*/
|
|
62
|
+
constructor(p: p5, parent: HTMLElement) {
|
|
63
|
+
this._parent = parent;
|
|
64
|
+
this._p = p;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Checks if the game body has been built.
|
|
69
|
+
* @returns True if the game body has been built, false otherwise.
|
|
70
|
+
*/
|
|
71
|
+
isBodyBuilt() {
|
|
72
|
+
return this._cachedCanvas != null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Builds the visual structure of the game.
|
|
77
|
+
*
|
|
78
|
+
* It initializes themes, layouts (frames, containers, buttons), and calculates responsive dimensions.
|
|
79
|
+
*
|
|
80
|
+
* @returns An object containing the canvas element and its explicit dimensions.
|
|
81
|
+
* - canvas: The p5 element for the canvas.
|
|
82
|
+
* - canvasWidth: The calculated width of the canvas.
|
|
83
|
+
* - canvasHeight: The calculated height of the canvas.
|
|
84
|
+
*/
|
|
85
|
+
build() {
|
|
86
|
+
|
|
87
|
+
if(this._cachedCanvas) {
|
|
88
|
+
return this._cachedCanvas;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
applyColors();
|
|
92
|
+
|
|
93
|
+
//Container
|
|
94
|
+
const { container, height, width } = ContainerLayout(this._p, this._parent);
|
|
95
|
+
|
|
96
|
+
//Frame
|
|
97
|
+
const frame = FrameLayout(this._p, container);
|
|
98
|
+
|
|
99
|
+
//Canvas
|
|
100
|
+
const { canvas, canvasHeight, canvasWidth } = Canvas(this._p, frame, width);
|
|
101
|
+
|
|
102
|
+
//Buttons
|
|
103
|
+
const {
|
|
104
|
+
largeButtonContainer,
|
|
105
|
+
smallButtonContainer,
|
|
106
|
+
directionHorizontalContainer,
|
|
107
|
+
directionVerticalContainer,
|
|
108
|
+
} = ButtonLayout(this._p, container);
|
|
109
|
+
|
|
110
|
+
//System buttons
|
|
111
|
+
this._onOffBtn = SmallButton(this._p, smallButtonContainer , 'On<br/>Off' , true);
|
|
112
|
+
this._startPauseBtn = SmallButton(this._p, smallButtonContainer , 'Start<br/>Pause' , false);
|
|
113
|
+
this._soundBtn = SmallButton(this._p, smallButtonContainer , 'Sound' , true);
|
|
114
|
+
this._resetBtn = SmallButton(this._p, smallButtonContainer , 'Reset' , false);
|
|
115
|
+
this._exitBtn = SmallButton(this._p, smallButtonContainer , 'Exit' , true);
|
|
116
|
+
this._enableColorBtn = SmallButton(this._p, smallButtonContainer , 'Enable<br/>Colors' , false);
|
|
117
|
+
|
|
118
|
+
//Direction buttons
|
|
119
|
+
this._upBtn = Button(this._p, directionVerticalContainer , 'UP');
|
|
120
|
+
this._leftBtn = Button(this._p, directionHorizontalContainer , 'LEFT');
|
|
121
|
+
this._downBtn = Button(this._p, directionVerticalContainer , 'DOWN');
|
|
122
|
+
this._rightBtn = Button(this._p, directionHorizontalContainer , 'RIGHT');
|
|
123
|
+
|
|
124
|
+
//Action button
|
|
125
|
+
this._actionBtn = BigButton(this._p, largeButtonContainer , 'Action');
|
|
126
|
+
|
|
127
|
+
//Set dimensions
|
|
128
|
+
dimensions(width, height, canvasWidth, canvasHeight);
|
|
129
|
+
|
|
130
|
+
//Hide splash screen
|
|
131
|
+
this._hideSplash();
|
|
132
|
+
|
|
133
|
+
this._cachedCanvas = { canvas, canvasWidth, canvasHeight };
|
|
134
|
+
return this._cachedCanvas;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Sets up the session modal with the current game modules.
|
|
139
|
+
* @param gameModules - The game modules to be used in the session modal.
|
|
140
|
+
*/
|
|
141
|
+
setupSessionModal() {
|
|
142
|
+
this._sessionModal = new SessionModal(this._p);
|
|
143
|
+
this._sessionModal.setup();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
showSessionModal(onConfirm: () => void, onCancel: () => void) {
|
|
147
|
+
this._sessionModal.show(onConfirm, onCancel);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Sets up the debugger with the current game modules.
|
|
152
|
+
* @param gameModules - The game modules to be debugged.
|
|
153
|
+
*/
|
|
154
|
+
setupDebugger(gameModules: GameModules) {
|
|
155
|
+
this._debugger = new Debugger(gameModules, this._p);
|
|
156
|
+
this._debugger.setup();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
updateDebuggerGameModules(gameModules: GameModules) {
|
|
160
|
+
this._debugger.setGameModules(gameModules);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Updates the debugger with the current game state.
|
|
165
|
+
*/
|
|
166
|
+
updateDebugger() {
|
|
167
|
+
this._debugger.update();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Binds game control events to the view buttons.
|
|
172
|
+
*
|
|
173
|
+
* Connects click and hold events from the UI buttons to the game logic controllers.
|
|
174
|
+
*
|
|
175
|
+
* @param control - The control module instance.
|
|
176
|
+
*/
|
|
177
|
+
bindControls(control: Control) {
|
|
178
|
+
this._inputHandler = new ControlInputHandler(control);
|
|
179
|
+
|
|
180
|
+
//System buttons
|
|
181
|
+
this._bindButtonEvents(this._onOffBtn , ControlKey.POWER);
|
|
182
|
+
this._bindButtonEvents(this._startPauseBtn , ControlKey.START_PAUSE);
|
|
183
|
+
this._bindButtonEvents(this._soundBtn , ControlKey.SOUND);
|
|
184
|
+
this._bindButtonEvents(this._resetBtn , ControlKey.RESET);
|
|
185
|
+
this._bindButtonEvents(this._exitBtn , ControlKey.EXIT);
|
|
186
|
+
this._bindButtonEvents(this._enableColorBtn, ControlKey.COLOR);
|
|
187
|
+
|
|
188
|
+
//Direction buttons
|
|
189
|
+
this._bindButtonEvents(this._upBtn , ControlKey.UP);
|
|
190
|
+
this._bindButtonEvents(this._downBtn , ControlKey.DOWN);
|
|
191
|
+
this._bindButtonEvents(this._rightBtn , ControlKey.RIGHT);
|
|
192
|
+
this._bindButtonEvents(this._leftBtn , ControlKey.LEFT);
|
|
193
|
+
|
|
194
|
+
//Action button
|
|
195
|
+
this._bindButtonEvents(this._actionBtn , ControlKey.ACTION);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Unbinds all events from the view buttons.
|
|
200
|
+
*
|
|
201
|
+
* Replaces all event listeners with empty functions to prevent interaction
|
|
202
|
+
* (e.g., when the game is paused or stopped).
|
|
203
|
+
*/
|
|
204
|
+
unbindControls() {
|
|
205
|
+
this._onOffBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
206
|
+
this._startPauseBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
207
|
+
this._soundBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
208
|
+
this._resetBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
209
|
+
this._exitBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
210
|
+
this._enableColorBtn.mousePressed(() => {}).mouseReleased(() => {});
|
|
211
|
+
|
|
212
|
+
this._upBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
213
|
+
this._downBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
214
|
+
this._rightBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
215
|
+
this._leftBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
216
|
+
|
|
217
|
+
this._actionBtn .mousePressed(() => {}).mouseReleased(() => {});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Helper method to bind press and release events using ControlInputHandler.
|
|
222
|
+
*
|
|
223
|
+
* @param btn - The p5 button element to bind.
|
|
224
|
+
* @param key - The control key to notify.
|
|
225
|
+
*/
|
|
226
|
+
private _bindButtonEvents(btn: p5.Element, key: ControlKey) {
|
|
227
|
+
btn.mousePressed(() => this._inputHandler.handlePress(key));
|
|
228
|
+
btn.mouseReleased(() => this._inputHandler.handleRelease(key));
|
|
229
|
+
// Also handle mouseOut as release to prevent stuck keys if cursor leaves button
|
|
230
|
+
btn.mouseOut(() => this._inputHandler.handleRelease(key));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Helper method to hide the splash screen after a delay.
|
|
235
|
+
*
|
|
236
|
+
* @param delay - The delay in milliseconds (defaults to `configs.viewLayout.splashHideDelayMs`).
|
|
237
|
+
*/
|
|
238
|
+
private _hideSplash(delay = configs.viewLayout.splashHideDelayMs) {
|
|
239
|
+
const splash: HTMLDivElement = document.querySelector(configs.selectors.splash);
|
|
240
|
+
setTimeout(() => {
|
|
241
|
+
splash.style.display = 'none';
|
|
242
|
+
}, delay);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
6
|
+
import type p5 from 'p5';
|
|
7
|
+
import SessionModal from './SessionModal';
|
|
8
|
+
|
|
9
|
+
describe('SessionModal', () => {
|
|
10
|
+
let modal: SessionModal;
|
|
11
|
+
let mockP5: Record<string, unknown>;
|
|
12
|
+
let mockContainer: Record<string, unknown>;
|
|
13
|
+
let mockConfirmButton: Record<string, unknown>;
|
|
14
|
+
let mockCancelButton: Record<string, unknown>;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
// [ARRANGE]
|
|
18
|
+
mockContainer = {
|
|
19
|
+
parent: vi.fn(),
|
|
20
|
+
id: vi.fn(),
|
|
21
|
+
class: vi.fn(),
|
|
22
|
+
removeClass: vi.fn(),
|
|
23
|
+
addClass: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
mockConfirmButton = {
|
|
27
|
+
parent: vi.fn(),
|
|
28
|
+
class: vi.fn(),
|
|
29
|
+
mousePressed: vi.fn(),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
mockCancelButton = {
|
|
33
|
+
parent: vi.fn(),
|
|
34
|
+
class: vi.fn(),
|
|
35
|
+
mousePressed: vi.fn(),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const mockGenericElement = {
|
|
39
|
+
parent: vi.fn(),
|
|
40
|
+
id: vi.fn(),
|
|
41
|
+
html: vi.fn(),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
mockP5 = {
|
|
45
|
+
select: vi.fn().mockImplementation(() => {
|
|
46
|
+
return {};
|
|
47
|
+
}), // Mock body select
|
|
48
|
+
createDiv: vi.fn().mockImplementation(() => {
|
|
49
|
+
// If it's the first time, return the container mock
|
|
50
|
+
// Otherwise return a generic element mock
|
|
51
|
+
if ((mockP5.createDiv as import('vitest').Mock).mock.calls.length === 1) return mockContainer;
|
|
52
|
+
return mockGenericElement;
|
|
53
|
+
}),
|
|
54
|
+
createP: vi.fn().mockReturnValue(mockGenericElement),
|
|
55
|
+
createButton: vi.fn().mockImplementation((label: string) => {
|
|
56
|
+
if (label === 'Cancel') return mockCancelButton;
|
|
57
|
+
if (label === 'Confirm') return mockConfirmButton;
|
|
58
|
+
return mockGenericElement;
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
modal = new SessionModal(mockP5 as unknown as p5);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('setup', () => {
|
|
66
|
+
it('should create the modal DOM elements and apply classes', () => {
|
|
67
|
+
// [ACT]
|
|
68
|
+
modal.setup();
|
|
69
|
+
|
|
70
|
+
// [ASSERT]
|
|
71
|
+
expect(mockP5.createDiv).toHaveBeenCalled();
|
|
72
|
+
expect(mockP5.createButton).toHaveBeenCalledWith('Cancel');
|
|
73
|
+
expect(mockP5.createButton).toHaveBeenCalledWith('Confirm');
|
|
74
|
+
expect(mockContainer.addClass).not.toHaveBeenCalled(); // Hidden class added in mock directly via class()
|
|
75
|
+
expect(mockContainer.class).toHaveBeenCalledWith('hidden');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('show', () => {
|
|
80
|
+
it('should bind the click events to the buttons and remove the hidden class', () => {
|
|
81
|
+
// [ARRANGE]
|
|
82
|
+
modal.setup();
|
|
83
|
+
const onConfirm = vi.fn();
|
|
84
|
+
const onCancel = vi.fn();
|
|
85
|
+
|
|
86
|
+
// [ACT]
|
|
87
|
+
modal.show(onConfirm, onCancel);
|
|
88
|
+
|
|
89
|
+
// [ASSERT]
|
|
90
|
+
expect(mockConfirmButton.mousePressed).toHaveBeenCalled();
|
|
91
|
+
expect(mockCancelButton.mousePressed).toHaveBeenCalled();
|
|
92
|
+
expect(mockContainer.removeClass).toHaveBeenCalledWith('hidden');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should trigger onConfirm and hide the modal when confirm button is clicked', () => {
|
|
96
|
+
// [ARRANGE]
|
|
97
|
+
modal.setup();
|
|
98
|
+
const onConfirm = vi.fn();
|
|
99
|
+
const onCancel = vi.fn();
|
|
100
|
+
|
|
101
|
+
// Extract the callback passed to mousePressed
|
|
102
|
+
let confirmCallback: () => void;
|
|
103
|
+
// @ts-expect-error Checking mock calls safely
|
|
104
|
+
mockConfirmButton.mousePressed.mockImplementation((cb: () => void) => {
|
|
105
|
+
if (cb) confirmCallback = cb;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
modal.show(onConfirm, onCancel);
|
|
109
|
+
|
|
110
|
+
// [ACT]
|
|
111
|
+
confirmCallback!();
|
|
112
|
+
|
|
113
|
+
// [ASSERT]
|
|
114
|
+
expect(onConfirm).toHaveBeenCalled();
|
|
115
|
+
expect(mockContainer.addClass).toHaveBeenCalledWith('hidden');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should trigger onCancel and hide the modal when cancel button is clicked', () => {
|
|
119
|
+
// [ARRANGE]
|
|
120
|
+
modal.setup();
|
|
121
|
+
const onConfirm = vi.fn();
|
|
122
|
+
const onCancel = vi.fn();
|
|
123
|
+
|
|
124
|
+
// Extract the callback passed to mousePressed
|
|
125
|
+
let cancelCallback: () => void;
|
|
126
|
+
// @ts-expect-error Checking mock calls safely
|
|
127
|
+
mockCancelButton.mousePressed.mockImplementation((cb: () => void) => {
|
|
128
|
+
if (cb) cancelCallback = cb;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
modal.show(onConfirm, onCancel);
|
|
132
|
+
|
|
133
|
+
// [ACT]
|
|
134
|
+
cancelCallback!();
|
|
135
|
+
|
|
136
|
+
// [ASSERT]
|
|
137
|
+
expect(onCancel).toHaveBeenCalled();
|
|
138
|
+
expect(mockContainer.addClass).toHaveBeenCalledWith('hidden');
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Initializable } from '../core/types/Interfaces';
|
|
2
|
+
import p5 from 'p5';
|
|
3
|
+
|
|
4
|
+
export default class SessionModal implements Initializable {
|
|
5
|
+
private _p: p5;
|
|
6
|
+
|
|
7
|
+
private _container: p5.Element;
|
|
8
|
+
private _confirmButton: p5.Element;
|
|
9
|
+
private _cancelButton: p5.Element;
|
|
10
|
+
|
|
11
|
+
constructor(p: p5) {
|
|
12
|
+
this._p = p;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
setup() {
|
|
16
|
+
this._container = this._p.createDiv();
|
|
17
|
+
this._container.parent(this._p.select('body'));
|
|
18
|
+
this._container.id('modal-background');
|
|
19
|
+
this._container.class('hidden');
|
|
20
|
+
|
|
21
|
+
const modal = this._p.createDiv();
|
|
22
|
+
modal.parent(this._container);
|
|
23
|
+
modal.id('session-modal');
|
|
24
|
+
|
|
25
|
+
const frame = this._p.createDiv();
|
|
26
|
+
frame.parent(modal);
|
|
27
|
+
frame.id('session-modal-frame');
|
|
28
|
+
|
|
29
|
+
const title = this._p.createP();
|
|
30
|
+
title.parent(frame);
|
|
31
|
+
title.html('Brick Engine Session');
|
|
32
|
+
|
|
33
|
+
const screen = this._p.createDiv();
|
|
34
|
+
screen.parent(frame);
|
|
35
|
+
screen.id('session-modal-screen');
|
|
36
|
+
|
|
37
|
+
const screenText = this._p.createP();
|
|
38
|
+
screenText.parent(screen);
|
|
39
|
+
screenText.html('<span>Looks like you have an active session.</span><br><br>Do you want to continue?');
|
|
40
|
+
|
|
41
|
+
const buttonsContainer = this._p.createDiv();
|
|
42
|
+
buttonsContainer.parent(modal);
|
|
43
|
+
buttonsContainer.id('session-modal-buttons');
|
|
44
|
+
|
|
45
|
+
this._cancelButton = this._p.createButton('Cancel');
|
|
46
|
+
this._cancelButton.parent(buttonsContainer);
|
|
47
|
+
this._cancelButton.class('session-modal-button');
|
|
48
|
+
|
|
49
|
+
this._confirmButton = this._p.createButton('Confirm');
|
|
50
|
+
this._confirmButton.parent(buttonsContainer);
|
|
51
|
+
this._confirmButton.class('session-modal-button');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
show(onConfirm: () => void, onCancel: () => void) {
|
|
55
|
+
this._confirmButton.mousePressed(() => {
|
|
56
|
+
onConfirm();
|
|
57
|
+
this._hide();
|
|
58
|
+
});
|
|
59
|
+
this._cancelButton.mousePressed(() => {
|
|
60
|
+
onCancel();
|
|
61
|
+
this._hide();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
this._container.removeClass('hidden');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private _hide() {
|
|
68
|
+
this._confirmButton.mousePressed(null);
|
|
69
|
+
this._cancelButton.mousePressed(null);
|
|
70
|
+
|
|
71
|
+
this._container.addClass('hidden');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import type p5 from 'p5';
|
|
3
|
+
import ButtonLayout from './ButtonLayout';
|
|
4
|
+
|
|
5
|
+
describe('ButtonLayout', () => {
|
|
6
|
+
it('should create a hierarchy of containers with correct IDs', () => {
|
|
7
|
+
// [ARRANGE]
|
|
8
|
+
const mockElement = {
|
|
9
|
+
parent: vi.fn(),
|
|
10
|
+
id: vi.fn(),
|
|
11
|
+
};
|
|
12
|
+
const mockP5 = {
|
|
13
|
+
createDiv: vi.fn().mockReturnValue(mockElement),
|
|
14
|
+
} as unknown as p5;
|
|
15
|
+
const mockContainer = {} as p5.Element;
|
|
16
|
+
|
|
17
|
+
// [ACT]
|
|
18
|
+
const result = ButtonLayout(mockP5, mockContainer);
|
|
19
|
+
|
|
20
|
+
// [ASSERT]
|
|
21
|
+
expect(mockP5.createDiv).toHaveBeenCalledTimes(7); // buttonContainer, small, inner, medium, vertical, horizontal, large
|
|
22
|
+
expect(mockElement.id).toHaveBeenCalledWith('button-container');
|
|
23
|
+
expect(mockElement.id).toHaveBeenCalledWith('small-button-container');
|
|
24
|
+
expect(mockElement.id).toHaveBeenCalledWith('large-button-container');
|
|
25
|
+
expect(result.smallButtonContainer).toBe(mockElement);
|
|
26
|
+
expect(result.largeButtonContainer).toBe(mockElement);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import p5 from 'p5';
|
|
2
|
+
import configs from '../../../config/configs';
|
|
3
|
+
|
|
4
|
+
interface ButtonLayoutResponse {
|
|
5
|
+
smallButtonContainer: p5.Element;
|
|
6
|
+
mediumButtonContainer: p5.Element;
|
|
7
|
+
largeButtonContainer: p5.Element;
|
|
8
|
+
directionVerticalContainer: p5.Element;
|
|
9
|
+
directionHorizontalContainer: p5.Element;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates and organizes the layout containers for game control buttons.
|
|
14
|
+
*
|
|
15
|
+
* It constructs a hierarchy of div elements to separate small system buttons,
|
|
16
|
+
* inner group buttons, and directional pads.
|
|
17
|
+
*
|
|
18
|
+
* @param {p5} p - The p5 instance.
|
|
19
|
+
* @param {p5.Element} container - The parent container element.
|
|
20
|
+
* @returns {ButtonLayoutResponse} Object containing the button containers.
|
|
21
|
+
* - smallButtonContainer: For system buttons (Reset, Sound, etc.), uses `configs.selectors.viewElementIds.smallButtonContainer`.
|
|
22
|
+
* - mediumButtonContainer: For direction controls, uses `configs.selectors.viewElementIds.mediumButtonContainer`.
|
|
23
|
+
* - largeButtonContainer: For the main action button, uses `configs.selectors.viewElementIds.largeButtonContainer`.
|
|
24
|
+
* - directionVerticalContainer: For Up/Down buttons.
|
|
25
|
+
* - directionHorizontalContainer: For Left/Right buttons.
|
|
26
|
+
*/
|
|
27
|
+
export default function ButtonLayout(p: p5, container: p5.Element): ButtonLayoutResponse {
|
|
28
|
+
const buttonContainer = p.createDiv();
|
|
29
|
+
buttonContainer.parent(container);
|
|
30
|
+
buttonContainer.id(configs.selectors.viewElementIds.buttonContainer);
|
|
31
|
+
|
|
32
|
+
const smallButtonContainer = p.createDiv();
|
|
33
|
+
smallButtonContainer.parent(buttonContainer);
|
|
34
|
+
smallButtonContainer.id(configs.selectors.viewElementIds.smallButtonContainer);
|
|
35
|
+
|
|
36
|
+
const innerButtonContainer = p.createDiv();
|
|
37
|
+
innerButtonContainer.parent(buttonContainer);
|
|
38
|
+
innerButtonContainer.id(configs.selectors.viewElementIds.innerButtonContainer);
|
|
39
|
+
|
|
40
|
+
const mediumButtonContainer = p.createDiv();
|
|
41
|
+
mediumButtonContainer.parent(innerButtonContainer);
|
|
42
|
+
mediumButtonContainer.id(configs.selectors.viewElementIds.mediumButtonContainer);
|
|
43
|
+
|
|
44
|
+
const directionVerticalContainer = p.createDiv();
|
|
45
|
+
directionVerticalContainer.parent(mediumButtonContainer);
|
|
46
|
+
directionVerticalContainer.id(configs.selectors.viewElementIds.directionVerticalContainer);
|
|
47
|
+
|
|
48
|
+
const directionHorizontalContainer = p.createDiv();
|
|
49
|
+
directionHorizontalContainer.parent(mediumButtonContainer);
|
|
50
|
+
directionHorizontalContainer.id(configs.selectors.viewElementIds.directionHorizontalContainer);
|
|
51
|
+
|
|
52
|
+
const largeButtonContainer = p.createDiv();
|
|
53
|
+
largeButtonContainer.parent(innerButtonContainer);
|
|
54
|
+
largeButtonContainer.id(configs.selectors.viewElementIds.largeButtonContainer);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
smallButtonContainer,
|
|
58
|
+
mediumButtonContainer,
|
|
59
|
+
largeButtonContainer,
|
|
60
|
+
directionVerticalContainer,
|
|
61
|
+
directionHorizontalContainer,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** @vitest-environment jsdom */
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import type p5 from 'p5';
|
|
4
|
+
import ContainerLayout from './ContainerLayout';
|
|
5
|
+
|
|
6
|
+
describe('ContainerLayout', () => {
|
|
7
|
+
it('should calculate dimensions for mobile breakpoint', () => {
|
|
8
|
+
// [ARRANGE]
|
|
9
|
+
const mockElement = { parent: vi.fn(), id: vi.fn() };
|
|
10
|
+
const mockP5 = { createDiv: vi.fn().mockReturnValue(mockElement) } as unknown as p5;
|
|
11
|
+
const mockParent = {
|
|
12
|
+
clientWidth: 500, // Mobile < 600
|
|
13
|
+
clientHeight: 900,
|
|
14
|
+
} as unknown as HTMLElement;
|
|
15
|
+
|
|
16
|
+
// [ACT]
|
|
17
|
+
const result = ContainerLayout(mockP5, mockParent);
|
|
18
|
+
|
|
19
|
+
// [ASSERT]
|
|
20
|
+
expect(result.width).toBe(500);
|
|
21
|
+
expect(result.height).toBe(900);
|
|
22
|
+
expect(mockElement.id).toHaveBeenCalledWith('container');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should calculate dimensions for desktop with vertical limit', () => {
|
|
26
|
+
// [ARRANGE]
|
|
27
|
+
const mockElement = { parent: vi.fn(), id: vi.fn() };
|
|
28
|
+
const mockP5 = { createDiv: vi.fn().mockReturnValue(mockElement) } as unknown as p5;
|
|
29
|
+
|
|
30
|
+
// desktop
|
|
31
|
+
const mockParent = {
|
|
32
|
+
clientWidth: 1200,
|
|
33
|
+
clientHeight: 1000,
|
|
34
|
+
} as unknown as HTMLElement;
|
|
35
|
+
|
|
36
|
+
// Multiplier is 1.9 in configs
|
|
37
|
+
// maxHeightWidth = 1000 / (1.9 * 1.05) ≈ 501.25
|
|
38
|
+
// width = min(1200, 501.25) ≈ 501.25
|
|
39
|
+
// height = 501.25 * 1.9 ≈ 952.38
|
|
40
|
+
|
|
41
|
+
// [ACT]
|
|
42
|
+
const result = ContainerLayout(mockP5, mockParent);
|
|
43
|
+
|
|
44
|
+
// [ASSERT]
|
|
45
|
+
expect(result.width).toBeLessThan(600); // Because vertical limit is tight
|
|
46
|
+
expect(result.height).toBeCloseTo(result.width * 1.9);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import p5 from 'p5';
|
|
2
|
+
import configs from '../../../config/configs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Response object containing container dimensions and element reference.
|
|
6
|
+
*/
|
|
7
|
+
interface ContainerResponse {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
container: p5.Element;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates the main game container and calculates its optimal dimensions.
|
|
15
|
+
*
|
|
16
|
+
* It ensures the game container fits within the parent element (usually the window or a specific div)
|
|
17
|
+
* while maintaining a fixed aspect ratio defined by `configs.viewLayout.bodyHeightWidthMultiplier`.
|
|
18
|
+
* On smaller screens (<= configs.viewLayout.mobileBreakpoint width), it attempts to fill the parent width.
|
|
19
|
+
* On larger screens, it calculates the maximum dimensions that fit without overflowing vertically.
|
|
20
|
+
*
|
|
21
|
+
* @param {p5} p - The p5 instance.
|
|
22
|
+
* @param {HTMLElement} parent - The DOM element where the container will be appended.
|
|
23
|
+
* @returns {ContainerResponse} Object containing the container element and its calculated width/height.
|
|
24
|
+
*/
|
|
25
|
+
export default function ContainerLayout(p: p5, parent: HTMLElement): ContainerResponse {
|
|
26
|
+
const container = p.createDiv();
|
|
27
|
+
container.parent(configs.selectors.parent);
|
|
28
|
+
container.id(configs.selectors.viewElementIds.container);
|
|
29
|
+
|
|
30
|
+
let width: number;
|
|
31
|
+
let height: number;
|
|
32
|
+
|
|
33
|
+
if (parent.clientWidth <= configs.viewLayout.mobileBreakpoint) {
|
|
34
|
+
width = parent.clientWidth;
|
|
35
|
+
height = parent.clientHeight;
|
|
36
|
+
|
|
37
|
+
return { container, width, height };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Calcula a largura máxima baseada na altura disponível
|
|
41
|
+
const maxHeightWidth = parent.clientHeight / (configs.viewLayout.bodyHeightWidthMultiplier * 1.05);
|
|
42
|
+
|
|
43
|
+
// A largura final é o menor valor entre a largura disponível e a largura limitada pela altura
|
|
44
|
+
width = Math.min(parent.clientWidth, maxHeightWidth);
|
|
45
|
+
|
|
46
|
+
// A altura é calculada com base na proporção original
|
|
47
|
+
height = width * configs.viewLayout.bodyHeightWidthMultiplier;
|
|
48
|
+
|
|
49
|
+
return { container, width, height };
|
|
50
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import type p5 from 'p5';
|
|
3
|
+
import FrameLayout from './FrameLayout';
|
|
4
|
+
|
|
5
|
+
describe('FrameLayout', () => {
|
|
6
|
+
it('should create a frame with branding text', () => {
|
|
7
|
+
// [ARRANGE]
|
|
8
|
+
const mockElement = { parent: vi.fn(), id: vi.fn() };
|
|
9
|
+
const mockP5 = {
|
|
10
|
+
createDiv: vi.fn().mockReturnValue(mockElement),
|
|
11
|
+
createP: vi.fn().mockReturnValue(mockElement),
|
|
12
|
+
} as unknown as p5;
|
|
13
|
+
const mockContainer = {} as p5.Element;
|
|
14
|
+
|
|
15
|
+
// [ACT]
|
|
16
|
+
const result = FrameLayout(mockP5, mockContainer);
|
|
17
|
+
|
|
18
|
+
// [ASSERT]
|
|
19
|
+
expect(mockP5.createDiv).toHaveBeenCalledTimes(2);
|
|
20
|
+
expect(mockP5.createP).toHaveBeenCalledWith('Brick Game');
|
|
21
|
+
expect(mockElement.id).toHaveBeenCalledWith('frame');
|
|
22
|
+
expect(result).toBe(mockElement);
|
|
23
|
+
});
|
|
24
|
+
});
|