From 7d91eff5fc4245429e60c55b016fe1abeb21c6ac Mon Sep 17 00:00:00 2001 From: elioat Date: Mon, 17 Feb 2025 09:20:00 -0500 Subject: * --- html/tower/docs/fonts/OpenSans-Bold-webfont.eot | Bin 0 -> 19544 bytes html/tower/docs/fonts/OpenSans-Bold-webfont.svg | 1830 +++++++++++ html/tower/docs/fonts/OpenSans-Bold-webfont.woff | Bin 0 -> 22432 bytes .../docs/fonts/OpenSans-BoldItalic-webfont.eot | Bin 0 -> 20133 bytes .../docs/fonts/OpenSans-BoldItalic-webfont.svg | 1830 +++++++++++ .../docs/fonts/OpenSans-BoldItalic-webfont.woff | Bin 0 -> 23048 bytes html/tower/docs/fonts/OpenSans-Italic-webfont.eot | Bin 0 -> 20265 bytes html/tower/docs/fonts/OpenSans-Italic-webfont.svg | 1830 +++++++++++ html/tower/docs/fonts/OpenSans-Italic-webfont.woff | Bin 0 -> 23188 bytes html/tower/docs/fonts/OpenSans-Light-webfont.eot | Bin 0 -> 19514 bytes html/tower/docs/fonts/OpenSans-Light-webfont.svg | 1831 +++++++++++ html/tower/docs/fonts/OpenSans-Light-webfont.woff | Bin 0 -> 22248 bytes .../docs/fonts/OpenSans-LightItalic-webfont.eot | Bin 0 -> 20535 bytes .../docs/fonts/OpenSans-LightItalic-webfont.svg | 1835 +++++++++++ .../docs/fonts/OpenSans-LightItalic-webfont.woff | Bin 0 -> 23400 bytes html/tower/docs/fonts/OpenSans-Regular-webfont.eot | Bin 0 -> 19836 bytes html/tower/docs/fonts/OpenSans-Regular-webfont.svg | 1831 +++++++++++ .../tower/docs/fonts/OpenSans-Regular-webfont.woff | Bin 0 -> 22660 bytes html/tower/docs/game.js.html | 537 +++ html/tower/docs/gameState.js.html | 338 ++ html/tower/docs/global.html | 3447 ++++++++++++++++++++ html/tower/docs/index.html | 65 + html/tower/docs/mechanics.js.html | 480 +++ html/tower/docs/module-game.html | 1553 +++++++++ html/tower/docs/module-gameState.html | 1407 ++++++++ html/tower/docs/module-mechanics.html | 2286 +++++++++++++ html/tower/docs/module-path.html | 531 +++ html/tower/docs/module-renderer.html | 659 ++++ html/tower/docs/module-uiHandlers.html | 543 +++ html/tower/docs/path.js.html | 226 ++ html/tower/docs/renderer.js.html | 431 +++ html/tower/docs/scripts/linenumber.js | 25 + .../docs/scripts/prettify/Apache-License-2.0.txt | 202 ++ html/tower/docs/scripts/prettify/lang-css.js | 2 + html/tower/docs/scripts/prettify/prettify.js | 28 + html/tower/docs/styles/jsdoc-default.css | 358 ++ html/tower/docs/styles/prettify-jsdoc.css | 111 + html/tower/docs/styles/prettify-tomorrow.css | 132 + html/tower/docs/uiHandlers.js.html | 146 + html/tower/js/game.js | 10 + html/tower/js/gameState.js | 77 +- html/tower/js/mechanics.js | 4 +- html/tower/js/path.js | 2 + html/tower/js/renderer.js | 2 + html/tower/js/uiHandlers.js | 2 + 45 files changed, 24586 insertions(+), 5 deletions(-) create mode 100644 html/tower/docs/fonts/OpenSans-Bold-webfont.eot create mode 100644 html/tower/docs/fonts/OpenSans-Bold-webfont.svg create mode 100644 html/tower/docs/fonts/OpenSans-Bold-webfont.woff create mode 100644 html/tower/docs/fonts/OpenSans-BoldItalic-webfont.eot create mode 100644 html/tower/docs/fonts/OpenSans-BoldItalic-webfont.svg create mode 100644 html/tower/docs/fonts/OpenSans-BoldItalic-webfont.woff create mode 100644 html/tower/docs/fonts/OpenSans-Italic-webfont.eot create mode 100644 html/tower/docs/fonts/OpenSans-Italic-webfont.svg create mode 100644 html/tower/docs/fonts/OpenSans-Italic-webfont.woff create mode 100644 html/tower/docs/fonts/OpenSans-Light-webfont.eot create mode 100644 html/tower/docs/fonts/OpenSans-Light-webfont.svg create mode 100644 html/tower/docs/fonts/OpenSans-Light-webfont.woff create mode 100644 html/tower/docs/fonts/OpenSans-LightItalic-webfont.eot create mode 100644 html/tower/docs/fonts/OpenSans-LightItalic-webfont.svg create mode 100644 html/tower/docs/fonts/OpenSans-LightItalic-webfont.woff create mode 100644 html/tower/docs/fonts/OpenSans-Regular-webfont.eot create mode 100644 html/tower/docs/fonts/OpenSans-Regular-webfont.svg create mode 100644 html/tower/docs/fonts/OpenSans-Regular-webfont.woff create mode 100644 html/tower/docs/game.js.html create mode 100644 html/tower/docs/gameState.js.html create mode 100644 html/tower/docs/global.html create mode 100644 html/tower/docs/index.html create mode 100644 html/tower/docs/mechanics.js.html create mode 100644 html/tower/docs/module-game.html create mode 100644 html/tower/docs/module-gameState.html create mode 100644 html/tower/docs/module-mechanics.html create mode 100644 html/tower/docs/module-path.html create mode 100644 html/tower/docs/module-renderer.html create mode 100644 html/tower/docs/module-uiHandlers.html create mode 100644 html/tower/docs/path.js.html create mode 100644 html/tower/docs/renderer.js.html create mode 100644 html/tower/docs/scripts/linenumber.js create mode 100644 html/tower/docs/scripts/prettify/Apache-License-2.0.txt create mode 100644 html/tower/docs/scripts/prettify/lang-css.js create mode 100644 html/tower/docs/scripts/prettify/prettify.js create mode 100644 html/tower/docs/styles/jsdoc-default.css create mode 100644 html/tower/docs/styles/prettify-jsdoc.css create mode 100644 html/tower/docs/styles/prettify-tomorrow.css create mode 100644 html/tower/docs/uiHandlers.js.html (limited to 'html') diff --git a/html/tower/docs/fonts/OpenSans-Bold-webfont.eot b/html/tower/docs/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 0000000..5d20d91 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Bold-webfont.eot differ diff --git a/html/tower/docs/fonts/OpenSans-Bold-webfont.svg b/html/tower/docs/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 0000000..3ed7be4 --- /dev/null +++ b/html/tower/docs/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/html/tower/docs/fonts/OpenSans-Bold-webfont.woff b/html/tower/docs/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000..1205787 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Bold-webfont.woff differ diff --git a/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.eot b/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 0000000..1f639a1 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.svg b/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 0000000..6a2607b --- /dev/null +++ b/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.woff b/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000..ed760c0 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/html/tower/docs/fonts/OpenSans-Italic-webfont.eot b/html/tower/docs/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 0000000..0c8a0ae Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Italic-webfont.eot differ diff --git a/html/tower/docs/fonts/OpenSans-Italic-webfont.svg b/html/tower/docs/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 0000000..e1075dc --- /dev/null +++ b/html/tower/docs/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/html/tower/docs/fonts/OpenSans-Italic-webfont.woff b/html/tower/docs/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000..ff652e6 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Italic-webfont.woff differ diff --git a/html/tower/docs/fonts/OpenSans-Light-webfont.eot b/html/tower/docs/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 0000000..1486840 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Light-webfont.eot differ diff --git a/html/tower/docs/fonts/OpenSans-Light-webfont.svg b/html/tower/docs/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 0000000..11a472c --- /dev/null +++ b/html/tower/docs/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/html/tower/docs/fonts/OpenSans-Light-webfont.woff b/html/tower/docs/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 0000000..e786074 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Light-webfont.woff differ diff --git a/html/tower/docs/fonts/OpenSans-LightItalic-webfont.eot b/html/tower/docs/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 0000000..8f44592 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/html/tower/docs/fonts/OpenSans-LightItalic-webfont.svg b/html/tower/docs/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 0000000..431d7e3 --- /dev/null +++ b/html/tower/docs/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/html/tower/docs/fonts/OpenSans-LightItalic-webfont.woff b/html/tower/docs/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000..43e8b9e Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/html/tower/docs/fonts/OpenSans-Regular-webfont.eot b/html/tower/docs/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 0000000..6bbc3cf Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Regular-webfont.eot differ diff --git a/html/tower/docs/fonts/OpenSans-Regular-webfont.svg b/html/tower/docs/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 0000000..25a3952 --- /dev/null +++ b/html/tower/docs/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/html/tower/docs/fonts/OpenSans-Regular-webfont.woff b/html/tower/docs/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000..e231183 Binary files /dev/null and b/html/tower/docs/fonts/OpenSans-Regular-webfont.woff differ diff --git a/html/tower/docs/game.js.html b/html/tower/docs/game.js.html new file mode 100644 index 0000000..b34bcf8 --- /dev/null +++ b/html/tower/docs/game.js.html @@ -0,0 +1,537 @@ + + + + + JSDoc: Source: game.js + + + + + + + + + + +
+ +

Source: game.js

+ + + + + + +
+
+
// generate updated docs
+// jsdoc js -d docs
+
+/**
+ * Main game entry point
+ * Initializes the game state and starts the game loop
+ * 
+ * @module game
+ */
+
+/** Canvas elements for rendering the game */
+const canvas = document.getElementById('gameCanvas');
+const ctx = canvas.getContext('2d');
+
+/** Game timing variables */
+let lastTimestamp = 0;
+const ENEMY_SPAWN_INTERVAL = 1000; // 1 second between enemy spawns
+let lastEnemySpawn = 0;
+let enemiesRemaining = 0;
+
+/** Drag and drop state tracking */
+let draggedTowerType = null;
+let hoverCell = null;
+
+/**
+ * Main game loop using requestAnimationFrame
+ * This is the heart of the game, running approximately 60 times per second
+ * 
+ * @param {number} timestamp - Current time in milliseconds, provided by requestAnimationFrame
+ * 
+ * Key concepts:
+ * - RequestAnimationFrame for smooth animation
+ * - Delta time for consistent motion regardless of frame rate
+ * - Game state management
+ */
+function gameLoop(timestamp) {
+    const deltaTime = timestamp - lastTimestamp;
+    lastTimestamp = timestamp;
+    
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    
+    if (!gameState.isGameOver) {
+        if (gameState.phase === GamePhase.COMBAT) {
+            handleCombatPhase(timestamp, deltaTime);
+            
+            // Check for level completion
+            if (gameState.checkLevelComplete()) {
+                handleLevelComplete();
+            }
+        }
+    }
+    
+    renderGame();
+    requestAnimationFrame(gameLoop);
+}
+
+/**
+ * Handles all combat phase updates including enemy movement, attacks, and collisions
+ * 
+ * @param {number} timestamp - Current game time in milliseconds
+ * @param {number} deltaTime - Time elapsed since last frame
+ * 
+ * Key concepts:
+ * - Game state updates
+ * - Entity management (enemies, towers, projectiles)
+ * - Particle effects
+ * - Combat mechanics
+ */
+function handleCombatPhase(timestamp, deltaTime) {
+    spawnEnemies(timestamp);
+    updateEnemies();
+    // Update particle effects with time-based animation
+    gameState.particles = updateParticles(gameState.particles, timestamp, deltaTime);
+    // Remove expired projectiles
+    gameState.projectiles = gameState.projectiles.filter(p => timestamp - p.createdAt < p.lifetime);
+    
+    const cellSize = canvas.width / 20;
+    
+    // Process combat interactions
+    processTowerAttacks(
+        gameState.towers,
+        gameState.enemies,
+        gameState.projectiles,
+        gameState.particles,
+        timestamp,
+        cellSize
+    );
+    
+    processEnemyAttacks(
+        gameState.enemies,
+        gameState.towers,
+        gameState.particles,
+        timestamp,
+        cellSize
+    );
+    
+    // Remove defeated enemies and destroyed towers
+    // Uses array filter with a callback that has side effects (awarding currency)
+    gameState.enemies = gameState.enemies.filter(enemy => {
+        if (enemy.currentHealth <= 0) {
+            gameState.awardEnemyDestroyed();
+            return false;
+        }
+        return true;
+    });
+    gameState.towers = gameState.towers.filter(tower => tower.currentHealth > 0);
+}
+
+/**
+ * Spawns new enemies at regular intervals during combat
+ * 
+ * @param {number} timestamp - Current game time in milliseconds
+ * 
+ * Key concepts:
+ * - Time-based game events
+ * - Enemy creation and management
+ * - Game balance through spawn timing
+ */
+function spawnEnemies(timestamp) {
+    if (enemiesRemaining > 0 && timestamp - lastEnemySpawn > ENEMY_SPAWN_INTERVAL) {
+        gameState.enemies.push(createEnemy({ x: 0, y: gameState.path[0].y }));
+        lastEnemySpawn = timestamp;
+        enemiesRemaining--;
+    }
+}
+
+/**
+ * Renders all game elements to the canvas using a layered approach.
+ * This function demonstrates several key game development patterns:
+ * 
+ * 1. Canvas State Management:
+ *    - Uses save()/restore() to isolate rendering contexts
+ *    - Resets transform matrix to prevent state leaks
+ *    - Maintains clean state between rendering phases
+ * 
+ * 2. Layered Rendering Pattern:
+ *    - Renders in specific order (background → entities → UI)
+ *    - Each layer builds on top of previous layers
+ *    - Separates rendering concerns for easier maintenance
+ * 
+ * 3. Separation of Concerns:
+ *    - Each render function handles one specific type of game element
+ *    - UI rendering is isolated from game element rendering
+ *    - Clear boundaries between different rendering responsibilities
+ * 
+ * The rendering order is important:
+ * 1. Grid (background)
+ * 2. Particles (effects under entities)
+ * 3. Projectiles (dynamic game elements)
+ * 4. Towers (static game entities)
+ * 5. Enemies (moving game entities)
+ * 6. UI (top layer)
+ */
+function renderGame() {
+    // Reset the canvas transform matrix to identity
+    // This prevents any previous transformations from affecting new renders
+    ctx.setTransform(1, 0, 0, 1, 0, 0);
+    
+    // Clear the entire canvas to prevent ghosting
+    // This is crucial for animation smoothness
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    
+    // Save the initial clean state
+    // This is part of the state stack pattern used in canvas rendering
+    ctx.save();
+    
+    // Render game world elements in specific order
+    // This creates the layered effect common in 2D games
+    renderGrid(ctx, gameState.grid);          // Background layer
+    renderParticles(ctx, gameState.particles); // Effect layer
+    renderProjectiles(ctx, gameState.projectiles); // Dynamic elements
+    renderTowers(ctx, gameState.towers);       // Static entities
+    renderEnemies(ctx, gameState.enemies);     // Moving entities
+    
+    // Restore to clean state before UI rendering
+    // This ensures UI rendering isn't affected by game world rendering
+    ctx.restore();
+    ctx.save();
+    
+    // Render UI elements last so they appear on top
+    // UI is rendered with its own clean state to prevent interference
+    renderUI(ctx, gameState);
+    
+    // Final state restoration
+    // Ensures clean state for next frame
+    ctx.restore();
+}
+
+/**
+ * Initializes the game by:
+ * 1. Generating the path for enemies to follow
+ * 2. Setting up initial enemy count
+ * 3. Binding event listeners
+ * 4. Starting the game loop
+ * 
+ * Uses Promise-based path generation to handle async initialization
+ */
+generatePath(gameState.grid).then(path => {
+    gameState.path = path;
+    // Random enemy count between 5-30 for variety
+    enemiesRemaining = Math.floor(Math.random() * 26) + 5;
+    initializeEventListeners();
+    // Start the game loop using requestAnimationFrame for smooth animation
+    requestAnimationFrame(gameLoop);
+});
+
+/**
+ * Transitions the game from placement to combat phase.
+ * Demonstrates state machine pattern commonly used in games.
+ * 
+ * Side effects:
+ * - Updates game phase
+ * - Disables UI elements
+ * - Updates visual feedback
+ */
+function startCombat() {
+    if (gameState.phase === GamePhase.PLACEMENT && gameState.towers.length > 0) {
+        // State transition
+        gameState.phase = GamePhase.COMBAT;
+        
+        // UI updates
+        document.getElementById('startCombat').disabled = true;
+        
+        // Visual feedback for disabled state
+        document.querySelectorAll('.tower-option').forEach(option => {
+            option.draggable = false;
+            option.style.cursor = 'not-allowed';
+            option.style.opacity = '0.5';
+        });
+    }
+}
+
+/**
+ * Sets up all event listeners for user interaction
+ * 
+ * Key concepts:
+ * - Event-driven programming
+ * - HTML5 Drag and Drop API
+ * - DOM manipulation
+ * - Method decoration (towers.push)
+ */
+function initializeEventListeners() {
+    // Add this at the beginning of the function
+    populateTowerPalette();
+    
+    // Set up tower palette drag events
+    document.querySelectorAll('.tower-option').forEach(option => {
+        option.addEventListener('dragstart', (e) => {
+            draggedTowerType = e.target.dataset.towerType;
+            // Required for Firefox - must set data for drag operation
+            e.dataTransfer.setData('text/plain', '');
+        });
+        
+        option.addEventListener('dragend', () => {
+            draggedTowerType = null;
+            hoverCell = null;
+        });
+    });
+
+    // Set up canvas drag and drop handling
+    canvas.addEventListener('dragover', (e) => {
+        e.preventDefault(); // Required for drop to work
+        const rect = canvas.getBoundingClientRect();
+        // Convert mouse coordinates to grid coordinates
+        const x = Math.floor((e.clientX - rect.left) / (canvas.width / 20));
+        const y = Math.floor((e.clientY - rect.top) / (canvas.height / 20));
+        
+        // Validate grid boundaries
+        if (x >= 0 && x < 20 && y >= 0 && y < 20) {
+            hoverCell = { x, y };
+        } else {
+            hoverCell = null;
+        }
+    });
+
+    canvas.addEventListener('dragleave', () => {
+        hoverCell = null;
+    });
+
+    // Handle tower placement on drop
+    canvas.addEventListener('drop', (e) => {
+        e.preventDefault();
+        if (!draggedTowerType || !hoverCell) return;
+
+        const tower = TowerTypes[draggedTowerType];
+        // Validate placement and currency
+        if (
+            gameState.grid[hoverCell.y][hoverCell.x] === 'empty' &&
+            gameState.currency >= tower.cost
+        ) {
+            gameState.grid[hoverCell.y][hoverCell.x] = 'tower';
+            gameState.towers.push(createTower(draggedTowerType, { ...hoverCell }));
+            gameState.currency -= tower.cost;
+        }
+        
+        // Reset drag state
+        draggedTowerType = null;
+        hoverCell = null;
+    });
+
+    // Combat phase transition
+    document.getElementById('startCombat').addEventListener('click', startCombat);
+    
+    // Dynamic button state management
+    const updateStartButton = () => {
+        const button = document.getElementById('startCombat');
+        button.disabled = gameState.towers.length === 0;
+    };
+    
+    // Decorator pattern: Enhance towers.push to update UI
+    const originalPush = gameState.towers.push;
+    gameState.towers.push = function(...args) {
+        const result = originalPush.apply(this, args);
+        updateStartButton();
+        return result;
+    };
+    
+    updateStartButton();
+}
+
+/**
+ * Handles the transition between levels
+ * Shows completion message and sets up next level
+ */
+function handleLevelComplete() {
+    // Pause the game briefly
+    gameState.phase = GamePhase.TRANSITION;
+    
+    // Calculate ammo bonus
+    let ammoBonus = 0;
+    gameState.towers.forEach(tower => {
+        ammoBonus += tower.ammo * 0.25;
+    });
+    ammoBonus = Math.floor(ammoBonus);
+    
+    // Show level complete message with modal
+    const message = `
+        Level ${gameState.level} Complete!
+        
+        Stats:
+        - Enemies Destroyed: ${gameState.enemiesDestroyed}
+        - Enemies Escaped: ${gameState.enemiesEscaped}
+        
+        Bonuses:
+        - Current Money: $${gameState.currency}
+        - Remaining Ammo Bonus: +$${ammoBonus}
+        
+        Total After Bonuses: $${gameState.currency + ammoBonus + 10}
+        
+        Ready for Level ${gameState.level + 1}?
+    `;
+    
+    // Use setTimeout to allow the final frame to render
+    setTimeout(() => {
+        if (confirm(message)) {
+            startNextLevel();
+        }
+    }, 100);
+}
+
+/**
+ * Sets up the next level
+ * Increases difficulty and resets the game state while preserving currency
+ */
+function startNextLevel() {
+    gameState.advanceToNextLevel();
+    
+    // Generate new path
+    generatePath(gameState.grid).then(path => {
+        gameState.path = path;
+        
+        // Exponential enemy scaling
+        const baseEnemies = 5;
+        const scalingFactor = 1.5;  // Each level increases by 50%
+        enemiesRemaining = Math.floor(baseEnemies * Math.pow(scalingFactor, gameState.level - 1));
+        
+        // Re-enable tower palette
+        document.querySelectorAll('.tower-option').forEach(option => {
+            option.draggable = true;
+            option.style.cursor = 'grab';
+            option.style.opacity = '1';
+        });
+        
+        // Reset start button
+        const startButton = document.getElementById('startCombat');
+        startButton.disabled = false;
+        startButton.textContent = `Start Level ${gameState.level}`;
+    });
+}
+
+// Update the renderUI function to show current level
+function renderUI(ctx, gameState) {
+    ctx.fillStyle = 'black';
+    ctx.font = '20px Arial';
+    ctx.fillText(`Level: ${gameState.level}`, 10, 30);
+    ctx.fillText(`Currency: $${gameState.currency}`, 10, 60);
+    ctx.fillText(`Phase: ${gameState.phase}`, 10, 90);
+    ctx.fillText(`Destroyed: ${gameState.enemiesDestroyed}`, 10, 120);
+    ctx.fillText(`Escaped: ${gameState.enemiesEscaped}`, 10, 150);
+}
+
+/**
+ * Dynamically populates the tower palette based on TowerTypes
+ */
+function populateTowerPalette() {
+    const palette = document.querySelector('.tower-palette');
+    // Clear existing tower options
+    palette.innerHTML = '';
+    
+    // Create tower options dynamically
+    Object.entries(TowerTypes).forEach(([type, tower]) => {
+        const towerOption = document.createElement('div');
+        towerOption.className = 'tower-option';
+        towerOption.draggable = true;
+        towerOption.dataset.towerType = type;
+        
+        towerOption.innerHTML = `
+            <div class="tower-preview" style="background: ${tower.color};"></div>
+            <div class="tower-info">
+                <div class="tower-name">${tower.name}</div>
+                <div class="tower-cost">Cost: $${tower.cost}</div>
+                <div class="tower-ammo">Ammo: ${tower.maxAmmo}</div>
+            </div>
+        `;
+        
+        palette.appendChild(towerOption);
+    });
+    
+    // Add start combat button
+    const startButton = document.createElement('button');
+    startButton.id = 'startCombat';
+    startButton.className = 'start-button';
+    startButton.textContent = 'Start Run';
+    palette.appendChild(startButton);
+}
+
+/**
+ * Handles game over state and prompts for restart
+ */
+function handleGameOver() {
+    gameState.phase = GamePhase.TRANSITION;
+    gameState.isGameOver = true;
+    
+    const message = `
+        Game Over!
+        
+        Final Stats:
+        Level Reached: ${gameState.level}
+        Enemies Destroyed: ${gameState.enemiesDestroyed}
+        Enemies Escaped: ${gameState.enemiesEscaped}
+        
+        Would you like to restart from Level 1?
+    `;
+    
+    setTimeout(() => {
+        if (confirm(message)) {
+            restartGame();
+        }
+    }, 100);
+}
+
+/**
+ * Restarts the game from level 1 with fresh state
+ */
+function restartGame() {
+    gameState.resetGame();
+    
+    // Generate new path
+    generatePath(gameState.grid).then(path => {
+        gameState.path = path;
+        
+        // Reset enemy count to level 1
+        enemiesRemaining = 5;
+        
+        // Re-enable tower palette
+        document.querySelectorAll('.tower-option').forEach(option => {
+            option.draggable = true;
+            option.style.cursor = 'grab';
+            option.style.opacity = '1';
+        });
+        
+        // Reset start button
+        const startButton = document.getElementById('startCombat');
+        startButton.disabled = false;
+        startButton.textContent = 'Start Level 1';
+    });
+} 
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/html/tower/docs/gameState.js.html b/html/tower/docs/gameState.js.html new file mode 100644 index 0000000..1276143 --- /dev/null +++ b/html/tower/docs/gameState.js.html @@ -0,0 +1,338 @@ + + + + + JSDoc: Source: gameState.js + + + + + + + + + + +
+ +

Source: gameState.js

+ + + + + + +
+
+
/**
+ * Game State Module
+ * 
+ * This module defines the game state and game phases
+ * 
+ * @module gameState
+ */
+
+
+/**
+ * Game phases
+ * 
+ * @enum {string}
+ * @readonly
+ */
+const GamePhase = {
+    PLACEMENT: 'place',
+    COMBAT: 'run'
+};
+
+/**
+ * Tower types
+ * 
+ * @enum {string}
+ * @readonly
+ */
+const TowerTypes = {
+    BASIC: {
+        name: 'Basic',
+        cost: 5,
+        range: 3,
+        damage: 1,
+        attackSpeed: 1,
+        color: '#3498db',
+        maxAmmo: 75
+    },
+    RAPID: {
+        name: 'Fast',
+        cost: 10,
+        range: 2,
+        damage: 1,
+        attackSpeed: 3,
+        color: '#16a085',
+        maxAmmo: 50
+    },
+    SNIPER: {
+        name: 'Distance',
+        cost: 20,
+        range: 6,
+        damage: 2,
+        attackSpeed: 0.5,
+        color: '#8e44ad',
+        maxAmmo: 50
+    },
+    GOOP: {
+        name: 'Goop',
+        cost: 20,
+        range: 3,
+        damage: 0,
+        attackSpeed: 1,
+        color: '#27ae60',
+        special: 'slow',
+        slowAmount: 0.75,
+        maxAmmo: 25
+    },
+    AOE: {
+        name: 'AOE',
+        cost: 25,
+        range: 2,
+        damage: 3,
+        attackSpeed: 0.25,
+        color: '#d35400',
+        special: 'aoe',
+        aoeRadius: 2,
+        maxAmmo: 25
+    }
+};
+
+/**
+ * Particle types
+ * 
+ * @enum {string}
+ * @readonly
+ */
+const ParticleTypes = {
+    DEATH_PARTICLE: {
+        lifetime: 1000, // milliseconds
+        speed: 0.1,
+        colors: ['#e74c3c', '#c0392b', '#d35400', '#e67e22']
+    },
+    PROJECTILE: {
+        lifetime: 300,
+        speed: 0.3,
+        color: '#ecf0f1'
+    },
+    AOE_EXPLOSION: {
+        lifetime: 500,
+        initialRadius: 10,
+        finalRadius: 60,
+        color: '#d35400',
+        ringWidth: 3
+    },
+    SLIME_TRAIL: {
+        lifetime: 800,
+        color: '#27ae60',  // Same as Goop tower
+        size: 12,
+        fadeStart: 0.2     // When the fade should begin (percentage of lifetime)
+    }
+};
+
+/**
+ * Enemy types
+ * 
+ * @enum {string}
+ * @readonly
+ */
+const EnemyTypes = {
+    BASIC: {
+        color: '#c0392b',
+        baseHealth: { min: 2, max: 6 },
+        speed: { min: 1, max: 1.5 },
+        damage: 0,
+        isRanged: false
+    },
+    RANGED: {
+        color: '#2c3e50',
+        baseHealth: { min: 1, max: 4 },
+        speed: { min: 0.7, max: 1.2 },
+        damage: 0.3,
+        attackRange: 3,
+        attackSpeed: 1, // attacks per second
+        isRanged: true
+    }
+};
+
+/**
+ * Creates a tower
+ * 
+ * @param {string} type - Tower type
+ * @param {Object} position - Position of the tower
+ */
+function createTower(type, position) {
+    const towerType = TowerTypes[type];
+    return {
+        ...towerType,
+        type,
+        position,
+        lastAttackTime: 0,
+        currentHealth: 10,
+        maxHealth: 10,
+        ammo: towerType.maxAmmo  // Initialize ammo
+    };
+}
+
+/**
+ * Creates an enemy
+ * 
+ * @param {Object} startPosition - Starting position of the enemy
+ */
+function createEnemy(startPosition) {
+    // 20% chance for ranged enemy
+    const type = Math.random() < 0.2 ? 'RANGED' : 'BASIC';
+    const enemyType = EnemyTypes[type];
+    
+    // Scale health ranges with level
+    const levelScaling = 1 + (gameState.level - 1) * 0.25; // increase health by 25% per level
+    const minHealth = Math.floor(enemyType.baseHealth.min * levelScaling);
+    const maxHealth = Math.floor(enemyType.baseHealth.max * levelScaling);
+    
+    const health = Math.floor(Math.random() * 
+        (maxHealth - minHealth + 1)) + minHealth;
+    
+    return {
+        position: { ...startPosition },
+        currentHealth: health,
+        maxHealth: health,
+        speed: enemyType.speed.min + Math.random() * (enemyType.speed.max - enemyType.speed.min),
+        pathIndex: 0,
+        type,
+        lastAttackTime: 0,
+        damage: enemyType.damage
+    };
+}
+
+/**
+ * Creates a particle
+ * 
+ * @param {string} type - Particle type
+ * @param {Object} position - Position of the particle
+ */
+function createParticle(type, position, angle) {
+    return {
+        position: { ...position },
+        velocity: {
+            x: Math.cos(angle) * type.speed,
+            y: Math.sin(angle) * type.speed
+        },
+        color: Array.isArray(type.colors) 
+            ? type.colors[Math.floor(Math.random() * type.colors.length)]
+            : type.color,
+        createdAt: performance.now(),
+        lifetime: type.lifetime,
+        size: 3 + Math.random() * 2
+    };
+}
+
+
+/**
+ * Game state
+ * 
+ * @type {Object}
+ */
+const gameState = {
+    grid: Array(20).fill().map(() => Array(20).fill('empty')),
+    path: [],
+    towers: [],
+    enemies: [],
+    currency: 100,
+    phase: GamePhase.PLACEMENT,
+    isGameOver: false,
+    particles: [],
+    projectiles: [],
+    enemiesDestroyed: 0,
+    enemiesEscaped: 0,
+    level: 1,
+    
+    /**
+     * Resets the game state
+     */
+    resetGame() {
+        this.grid = Array(20).fill().map(() => Array(20).fill('empty'));
+        this.path = [];
+        this.towers = [];
+        this.enemies = [];
+        this.currency = 100;
+        this.phase = GamePhase.PLACEMENT;
+        this.isGameOver = false;
+        this.particles = [];
+        this.projectiles = [];
+        this.enemiesDestroyed = 0;
+        this.enemiesEscaped = 0;
+        this.level = 1;
+    },
+    
+
+    /**
+     * Awards the enemy destroyed
+     */
+    awardEnemyDestroyed() {
+        this.enemiesDestroyed++;
+        // Random reward between 1 and 3
+        const reward = Math.floor(Math.random() * 3) + 1;
+        this.currency += reward;
+    },
+    
+
+    /**
+     * Checks if the level is complete
+     * 
+     * @returns {boolean}
+     */
+    checkLevelComplete() {
+        return this.enemies.length === 0 && 
+               enemiesRemaining === 0 && 
+               this.phase === GamePhase.COMBAT;
+    },
+    
+
+    /**
+     * Advances to the next level
+     */
+    advanceToNextLevel() {
+
+        let ammoBonus = 0;
+        this.towers.forEach(tower => {
+            ammoBonus += tower.ammo * 0.25;
+        });
+        this.currency += Math.floor(ammoBonus);  // Round down to nearest whole number
+        
+        this.level++;
+        this.phase = GamePhase.PLACEMENT;
+        this.towers = [];
+        this.enemies = [];
+        this.projectiles = [];
+        this.particles = [];
+        this.grid = Array(20).fill().map(() => Array(20).fill('empty'));
+    }
+}; 
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/html/tower/docs/global.html b/html/tower/docs/global.html new file mode 100644 index 0000000..d21546f --- /dev/null +++ b/html/tower/docs/global.html @@ -0,0 +1,3447 @@ + + + + + JSDoc: Global + + + + + + + + + + +
+ +

Global

+ + + + + + +
+ +
+ +

+ + +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

createDeathParticles(target, cellSize) → {Array.<Object>}

+ + + + + + +
+ Creates death effect particles for defeated entities +Implements visual feedback system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
target + + +Object + + + + The defeated entity
cellSize + + +number + + + + Size of grid cell for scaling
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Array of particle objects +
+ + + +
+
+ Type +
+
+ +Array.<Object> + + +
+
+ + + + + + + + + + + + + +

findTowersInRange(enemy, towers) → {Array.<Object>}

+ + + + + + +
+ Finds towers within enemy attack range +Implements targeting system for enemies +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
enemy + + +Object + + + + Enemy doing the targeting
towers + + +Array.<Object> + + + + Array of potential tower targets
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Array of towers in range +
+ + + +
+
+ Type +
+
+ +Array.<Object> + + +
+
+ + + + + + + + + + + + + +

generatePath(grid) → {Promise.<Array.<{x: number, y: number}>>}

+ + + + + + +
+ Generates a valid path through the game grid using a modified depth-first search. +This algorithm ensures: +- Path always moves from left to right +- No diagonal movements +- No path segments touch each other (except at turns) +- Path is always completable +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
grid + + +Array.<Array.<string>> + + + + 2D array representing the game grid
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Promise resolving to array of path coordinates + +Implementation uses: +- Backtracking algorithm pattern +- Constraint satisfaction +- Random selection for variety +
+ + + +
+
+ Type +
+
+ +Promise.<Array.<{x: number, y: number}>> + + +
+
+ + + + + + + + + + + + + +

getPathPosition(progress, path) → {Object}

+ + + + + + +
+ Calculates a position along the path based on a progress value +Implements smooth entity movement along path segments +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
progress + + +number + + + + Progress along path (0-1)
path + + +Array.<{x: number, y: number}> + + + + Array of path coordinates
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Interpolated position along path + +Uses: +- Linear interpolation (lerp) +- Path segment traversal +- Normalized progress tracking +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

handleAOEEffect(target, tower, enemies, particles, cellSize)

+ + + + + + +
+ Handles AOE (Area of Effect) damage and visual effects +Implements area damage system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
target + + +Object + + + + Primary target
tower + + +Object + + + + Tower dealing AOE damage
enemies + + +Array.<Object> + + + + All enemies for AOE calculation
particles + + +Array.<Object> + + + + Particle array for effects
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

handleEnemyAttack(enemy, tower, particles, timestamp, cellSize)

+ + + + + + +
+ Handles enemy attack execution and effects +Implements enemy combat mechanics +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
enemy + + +Object + + + + Attacking enemy
tower + + +Object + + + + Target tower
particles + + +Array.<Object> + + + + Particle array for effects
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

handleSlowEffect(target, tower, timestamp, particles, cellSize)

+ + + + + + +
+ Handles slow effect application and stacking +Implements status effect system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
target + + +Object + + + + Enemy to apply slow to
tower + + +Object + + + + Tower applying the effect
timestamp + + +number + + + + Current game timestamp
particles + + +Array.<Object> + + + + Particle array for effects
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

handleTowerAttack(tower, target, projectiles, particles, timestamp, cellSize)

+ + + + + + +
+ Handles individual tower attack logic including special effects +Implements tower ability system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
tower + + +Object + + + + Attacking tower
target + + +Object + + + + Target enemy
projectiles + + +Array.<Object> + + + + Projectile array
particles + + +Array.<Object> + + + + Particle array
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

initializeDragAndDrop(canvas, gameState) → {Object}

+ + + + + + +
+ Initializes drag and drop functionality for tower placement +Implements HTML5 Drag and Drop API +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
canvas + + +HTMLCanvasElement + + + + Game canvas element
gameState + + +Object + + + + Current game state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Drag handlers and state information +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

placeTower(gameState, towerType, position)

+ + + + + + +
+ Places a tower in the game grid +Implements tower placement validation and state updates +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
gameState + + +Object + + + + Current game state
towerType + + +string + + + + Type of tower to place
position + + +Object + + + + Grid position for placement
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

processEnemyAttacks(enemies, towers, particles, timestamp, cellSize)

+ + + + + + +
+ Processes enemy attack behaviors and targeting +Implements enemy combat AI +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
enemies + + +Array.<Object> + + + + Array of enemy objects
towers + + +Array.<Object> + + + + Array of tower objects
particles + + +Array.<Object> + + + + Particle effect array
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

processTowerAttacks(towers, enemies, projectiles, particles, timestamp, cellSize)

+ + + + + + +
+ Processes tower attacks and targeting +Implements combat mechanics and special abilities +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
towers + + +Array.<Object> + + + + Array of tower objects
enemies + + +Array.<Object> + + + + Array of enemy objects
projectiles + + +Array.<Object> + + + + Array of projectile objects
particles + + +Array.<Object> + + + + Array of particle objects
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Size of grid cell for scaling
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renderEnemies(ctx, enemies)

+ + + + + + +
+ Renders all enemies with health indicators and effects +Implements visual state representation +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + + Canvas rendering context
enemies + + +Array.<Object> + + + + Array of enemy objects
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renderGrid(ctx, grid)

+ + + + + + +
+ Renders the game grid with path and hover previews +Implements visual feedback for player actions +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + + Canvas rendering context
grid + + +Array.<Array.<string>> + + + + Game grid state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renderUI(ctx, gameState)

+ + + + + + +
+ Renders game UI elements with clean state management +Implements heads-up display (HUD) pattern +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + + Canvas rendering context
gameState + + +Object + + + + Current game state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

updateEnemies() → {void}

+ + + + + + +
+ Updates all enemy states including movement, health, and status effects +Implements core game loop mechanics for enemy behavior + +Key features: +- Path following +- Health management +- Status effect processing +- Collision detection +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

updateParticles(particles, timestamp, deltaTime) → {Array.<Object>}

+ + + + + + +
+ Updates particle effects with time-based animation +Implements particle system lifecycle management +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
particles + + +Array.<Object> + + + + Array of particle objects
timestamp + + +number + + + + Current game timestamp
deltaTime + + +number + + + + Time elapsed since last frame
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Updated particles array +
+ + + +
+
+ Type +
+
+ +Array.<Object> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/index.html b/html/tower/docs/index.html new file mode 100644 index 0000000..9a1549d --- /dev/null +++ b/html/tower/docs/index.html @@ -0,0 +1,65 @@ + + + + + JSDoc: Home + + + + + + + + + + +
+ +

Home

+ + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/mechanics.js.html b/html/tower/docs/mechanics.js.html new file mode 100644 index 0000000..d629a87 --- /dev/null +++ b/html/tower/docs/mechanics.js.html @@ -0,0 +1,480 @@ + + + + + JSDoc: Source: mechanics.js + + + + + + + + + + +
+ +

Source: mechanics.js

+ + + + + + +
+
+
/**
+ * Combat Mechanics Module
+ *  
+ * This module handles all combat-related game mechanics including:
+ * 1. Enemy movement and behavior
+ * 2. Tower attacks and targeting
+ * 3. Projectile and particle systems
+ * 4. Status effects and special abilities
+ * 
+ * @module mechanics
+ */
+
+/**
+ * Updates all enemy states including movement, health, and status effects
+ * Implements core game loop mechanics for enemy behavior
+ * 
+ * Key features:
+ * - Path following
+ * - Health management
+ * - Status effect processing
+ * - Collision detection
+ * 
+ * @returns {void}
+ */
+function updateEnemies() {
+    const cellSize = canvas.width / 20;
+    
+    gameState.enemies = gameState.enemies.filter(enemy => {
+        // Initialize progress tracking for new enemies
+        if (typeof enemy.progress === 'undefined') {
+            enemy.progress = 0;
+        }
+        
+        // Update movement progress
+        enemy.progress += enemy.speed * 0.001;
+        
+        // Handle path completion
+        if (enemy.progress >= 1) {
+            gameState.enemiesEscaped++;
+            // Deduct currency when enemy escapes
+            gameState.currency = Math.max(0, gameState.currency - 10);
+            // Check for game over
+            if (gameState.currency <= 0) {
+                handleGameOver();
+            }
+            return false;
+        }
+        
+        // Projectile collision detection and damage application
+        const hitByProjectile = gameState.projectiles.some(projectile => {
+            // Calculate current projectile position based on lifetime
+            const age = performance.now() - projectile.createdAt;
+            const progress = Math.min(age / projectile.lifetime, 1);
+            
+            const currentX = projectile.startPos.x + (projectile.targetPos.x - projectile.startPos.x) * progress;
+            const currentY = projectile.startPos.y + (projectile.targetPos.y - projectile.startPos.y) * progress;
+            
+            const distance = Math.hypot(
+                enemy.position.x - currentX,
+                enemy.position.y - currentY
+            );
+            
+            if (distance < 0.5) {
+                // Apply damage when projectile hits
+                enemy.currentHealth -= projectile.damage;
+                return true;
+            }
+            return false;
+        });
+        
+        if (enemy.currentHealth <= 0) {
+            gameState.awardEnemyDestroyed();
+            // Create death particles
+            gameState.particles.push(...createDeathParticles(enemy, cellSize));
+            return false;
+        }
+        
+        // Update position based on path progress
+        const pathPosition = getPathPosition(enemy.progress, gameState.path);
+        enemy.position.x = pathPosition.x;
+        enemy.position.y = pathPosition.y;
+        
+        // Process slow effect expiration
+        if (enemy.slowed && performance.now() > enemy.slowExpiry) {
+            enemy.slowed = false;
+            enemy.slowStacks = 0;
+            enemy.currentSlowAmount = 0;
+            enemy.speed = enemy.originalSpeed;
+        }
+        
+        // Visual feedback for slowed status
+        if (enemy.slowed && Math.random() < 0.2 + (enemy.slowStacks * 0.05)) {
+            gameState.particles.push(createSlimeTrail(enemy, cellSize));
+        }
+        
+        return true;
+    });
+    
+    // Remove projectiles that hit enemies
+    gameState.projectiles = gameState.projectiles.filter(projectile => {
+        const age = performance.now() - projectile.createdAt;
+        if (age >= projectile.lifetime) return false;
+        
+        const progress = age / projectile.lifetime;
+        const currentX = projectile.startPos.x + (projectile.targetPos.x - projectile.startPos.x) * progress;
+        const currentY = projectile.startPos.y + (projectile.targetPos.y - projectile.startPos.y) * progress;
+        
+        const hitEnemy = gameState.enemies.some(enemy => {
+            const distance = Math.hypot(
+                enemy.position.x - currentX,
+                enemy.position.y - currentY
+            );
+            return distance < 0.5;
+        });
+        
+        return !hitEnemy;
+    });
+}
+
+/**
+ * Updates particle effects with time-based animation
+ * Implements particle system lifecycle management
+ * 
+ * @param {Array<Object>} particles - Array of particle objects
+ * @param {number} timestamp - Current game timestamp
+ * @param {number} deltaTime - Time elapsed since last frame
+ * @returns {Array<Object>} Updated particles array
+ */
+function updateParticles(particles, timestamp, deltaTime) {
+    return particles.filter(particle => {
+        const age = timestamp - particle.createdAt;
+        if (age > particle.lifetime) return false;
+        
+        if (particle.velocity) {
+            particle.position.x += particle.velocity.x * deltaTime;
+            particle.position.y += particle.velocity.y * deltaTime;
+        }
+        
+        return true;
+    });
+}
+
+/**
+ * Creates death effect particles for defeated entities
+ * Implements visual feedback system
+ * 
+ * @param {Object} target - The defeated entity
+ * @param {number} cellSize - Size of grid cell for scaling
+ * @returns {Array<Object>} Array of particle objects
+ */
+function createDeathParticles(target, cellSize) {
+    const particles = [];
+    const centerX = (target.position.x + 0.5) * cellSize;
+    const centerY = (target.position.y + 0.5) * cellSize;
+    
+    const particleCount = 8 + Math.floor(Math.random() * 8);
+    for (let i = 0; i < particleCount; i++) {
+        const baseAngle = (Math.PI * 2 * i) / particleCount;
+        const randomAngle = baseAngle + (Math.random() - 0.5) * 1.5;
+        const speedMultiplier = 0.7 + Math.random() * 0.6;
+        const startOffset = Math.random() * 5;
+        
+        particles.push(createParticle(
+            {
+                ...ParticleTypes.DEATH_PARTICLE,
+                speed: ParticleTypes.DEATH_PARTICLE.speed * speedMultiplier,
+                lifetime: ParticleTypes.DEATH_PARTICLE.lifetime * (0.8 + Math.random() * 0.4)
+            },
+            {
+                x: centerX + Math.cos(randomAngle) * startOffset,
+                y: centerY + Math.sin(randomAngle) * startOffset
+            },
+            randomAngle
+        ));
+    }
+    return particles;
+}
+
+/**
+ * Processes tower attacks and targeting
+ * Implements combat mechanics and special abilities
+ * 
+ * @param {Array<Object>} towers - Array of tower objects
+ * @param {Array<Object>} enemies - Array of enemy objects
+ * @param {Array<Object>} projectiles - Array of projectile objects
+ * @param {Array<Object>} particles - Array of particle objects
+ * @param {number} timestamp - Current game timestamp
+ * @param {number} cellSize - Size of grid cell for scaling
+ */
+function processTowerAttacks(towers, enemies, projectiles, particles, timestamp, cellSize) {
+    towers.forEach(tower => {
+        if (timestamp - tower.lastAttackTime > 1000 / tower.attackSpeed) {
+            const enemiesInRange = findEnemiesInRange(tower, enemies);
+            
+            if (enemiesInRange.length > 0 && tower.ammo > 0) {
+                const target = enemiesInRange[0];
+                handleTowerAttack(tower, target, projectiles, particles, timestamp, cellSize);
+            }
+        }
+    });
+}
+
+function findEnemiesInRange(tower, enemies) {
+    return enemies.filter(enemy => {
+        const dx = enemy.position.x - tower.position.x;
+        const dy = enemy.position.y - tower.position.y;
+        return Math.sqrt(dx * dx + dy * dy) <= tower.range;
+    });
+}
+
+function createAOEExplosion(position, cellSize) {
+    return {
+        position: {
+            x: (position.x + 0.5) * cellSize,
+            y: (position.y + 0.5) * cellSize
+        },
+        createdAt: performance.now(),
+        type: 'AOE_EXPLOSION',
+        ...ParticleTypes.AOE_EXPLOSION
+    };
+}
+
+function createSlimeTrail(enemy, cellSize) {
+    return {
+        position: {
+            x: (enemy.position.x + 0.5) * cellSize,
+            y: (enemy.position.y + 0.5) * cellSize
+        },
+        createdAt: performance.now(),
+        type: 'SLIME_TRAIL',
+        ...ParticleTypes.SLIME_TRAIL
+    };
+}
+
+/**
+ * Handles individual tower attack logic including special effects
+ * Implements tower ability system
+ * 
+ * @param {Object} tower - Attacking tower
+ * @param {Object} target - Target enemy
+ * @param {Array<Object>} projectiles - Projectile array
+ * @param {Array<Object>} particles - Particle array
+ * @param {number} timestamp - Current game timestamp
+ * @param {number} cellSize - Grid cell size
+ */
+function handleTowerAttack(tower, target, projectiles, particles, timestamp, cellSize) {
+    // Only attack if we have ammo
+    if (tower.ammo <= 0) return;
+    
+    // Decrease ammo (already checked it's > 0)
+    tower.ammo--;
+    
+    // Create projectile
+    projectiles.push({
+        startPos: { ...tower.position },
+        targetPos: { ...target.position },
+        createdAt: timestamp,
+        lifetime: 300,
+        towerType: tower.type,
+        damage: tower.damage
+    });
+    
+    // Process special abilities
+    if (tower.special === 'slow') {
+        handleSlowEffect(target, tower, timestamp, particles, cellSize);
+    } else if (tower.special === 'aoe') {
+        handleAOEEffect(target, tower, gameState.enemies, particles, cellSize);
+    }
+    
+    tower.lastAttackTime = timestamp;
+}
+
+/**
+ * Processes enemy attack behaviors and targeting
+ * Implements enemy combat AI
+ * 
+ * @param {Array<Object>} enemies - Array of enemy objects
+ * @param {Array<Object>} towers - Array of tower objects
+ * @param {Array<Object>} particles - Particle effect array
+ * @param {number} timestamp - Current game timestamp
+ * @param {number} cellSize - Grid cell size
+ */
+function processEnemyAttacks(enemies, towers, particles, timestamp, cellSize) {
+    enemies.forEach(enemy => {
+        if (!EnemyTypes[enemy.type].isRanged) return;
+        
+        if (timestamp - enemy.lastAttackTime > 1000 / EnemyTypes[enemy.type].attackSpeed) {
+            const towersInRange = findTowersInRange(enemy, towers);
+            
+            if (towersInRange.length > 0) {
+                const target = towersInRange[0];
+                handleEnemyAttack(enemy, target, particles, timestamp, cellSize);
+            }
+        }
+    });
+}
+
+/**
+ * Finds towers within enemy attack range
+ * Implements targeting system for enemies
+ * 
+ * @param {Object} enemy - Enemy doing the targeting
+ * @param {Array<Object>} towers - Array of potential tower targets
+ * @returns {Array<Object>} Array of towers in range
+ */
+function findTowersInRange(enemy, towers) {
+    return towers.filter(tower => {
+        const dx = tower.position.x - enemy.position.x;
+        const dy = tower.position.y - enemy.position.y;
+        return Math.sqrt(dx * dx + dy * dy) <= EnemyTypes[enemy.type].attackRange;
+    });
+}
+
+/**
+ * Handles enemy attack execution and effects
+ * Implements enemy combat mechanics
+ * 
+ * @param {Object} enemy - Attacking enemy
+ * @param {Object} tower - Target tower
+ * @param {Array<Object>} particles - Particle array for effects
+ * @param {number} timestamp - Current game timestamp
+ * @param {number} cellSize - Grid cell size
+ */
+function handleEnemyAttack(enemy, tower, particles, timestamp, cellSize) {
+    // Create projectile effect
+    particles.push(createParticle(
+        {
+            ...ParticleTypes.PROJECTILE,
+            color: '#8e44ad80', // Semi-transparent purple
+            lifetime: 500
+        },
+        {
+            x: (enemy.position.x + 0.5) * cellSize,
+            y: (enemy.position.y + 0.5) * cellSize
+        },
+        Math.atan2(
+            tower.position.y - enemy.position.y,
+            tower.position.x - enemy.position.x
+        )
+    ));
+    
+    // Apply damage and update tower state
+    tower.currentHealth -= enemy.damage;
+    enemy.lastAttackTime = timestamp;
+    
+    // Dynamic damage reduction based on tower health
+    tower.damage = TowerTypes[tower.type].damage * (tower.currentHealth / tower.maxHealth);
+}
+
+/**
+ * Handles slow effect application and stacking
+ * Implements status effect system
+ * 
+ * @param {Object} target - Enemy to apply slow to
+ * @param {Object} tower - Tower applying the effect
+ * @param {number} timestamp - Current game timestamp
+ * @param {Array<Object>} particles - Particle array for effects
+ * @param {number} cellSize - Grid cell size
+ */
+function handleSlowEffect(target, tower, timestamp, particles, cellSize) {
+    // Initialize slow effect tracking
+    if (!target.slowStacks) {
+        target.slowStacks = 0;
+    }
+    
+    const maxStacks = 5;  // Maximum 5 stacks
+    if (target.slowStacks < maxStacks) {
+        target.slowStacks++;
+        // Each stack slows by an additional 10% (multiplicative)
+        const newSlowAmount = 1 - Math.pow(0.9, target.slowStacks);
+        
+        // Only update if new slow is stronger
+        if (!target.slowed || newSlowAmount > target.currentSlowAmount) {
+            const originalSpeed = target.originalSpeed || target.speed;
+            target.originalSpeed = originalSpeed;
+            target.speed = originalSpeed * (1 - newSlowAmount);
+            target.currentSlowAmount = newSlowAmount;
+            target.slowed = true;
+        }
+        
+        // Visual feedback particles
+        for (let i = 0; i < 4 + target.slowStacks; i++) {
+            particles.push(createSlimeTrail(target, cellSize));
+        }
+    }
+    
+    // Refresh effect duration
+    target.slowExpiry = timestamp + 2000;  // 2 second duration
+}
+
+/**
+ * Handles AOE (Area of Effect) damage and visual effects
+ * Implements area damage system
+ * 
+ * @param {Object} target - Primary target
+ * @param {Object} tower - Tower dealing AOE damage
+ * @param {Array<Object>} enemies - All enemies for AOE calculation
+ * @param {Array<Object>} particles - Particle array for effects
+ * @param {number} cellSize - Grid cell size
+ */
+function handleAOEEffect(target, tower, enemies, particles, cellSize) {
+    // Find all enemies in AOE radius
+    const enemiesInAOE = enemies.filter(enemy => {
+        const dx = enemy.position.x - target.position.x;
+        const dy = enemy.position.y - target.position.y;
+        return Math.sqrt(dx * dx + dy * dy) <= tower.aoeRadius;
+    });
+    
+    // Create explosion effect
+    particles.push(createAOEExplosion(target.position, cellSize));
+    
+    // Apply AOE damage
+    enemiesInAOE.forEach(enemy => {
+        enemy.currentHealth -= tower.damage;
+        if (enemy.currentHealth <= 0) {
+            particles.push(...createDeathParticles(enemy, cellSize));
+        }
+    });
+}
+
+// Update createEnemy to track original speed
+function createEnemy(startPosition) {
+    const enemy = {
+        // ... existing enemy properties ...
+        slowStacks: 0,
+        currentSlowAmount: 0
+    };
+    enemy.originalSpeed = enemy.speed;  // Store original speed
+    return enemy;
+} 
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/html/tower/docs/module-game.html b/html/tower/docs/module-game.html new file mode 100644 index 0000000..a5bf480 --- /dev/null +++ b/html/tower/docs/module-game.html @@ -0,0 +1,1553 @@ + + + + + JSDoc: Module: game + + + + + + + + + + +
+ +

Module: game

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Main game entry point +Initializes the game state and starts the game loop
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(inner, constant) canvas

+ + + + +
+ Canvas elements for rendering the game +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

(inner) draggedTowerType

+ + + + +
+ Drag and drop state tracking +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

(inner) lastTimestamp

+ + + + +
+ Game timing variables +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(inner) gameLoop(timestamp)

+ + + + + + +
+ Main game loop using requestAnimationFrame +This is the heart of the game, running approximately 60 times per second +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
timestamp + + +number + + + + Current time in milliseconds, provided by requestAnimationFrame + +Key concepts: +- RequestAnimationFrame for smooth animation +- Delta time for consistent motion regardless of frame rate +- Game state management
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) handleCombatPhase(timestamp, deltaTime)

+ + + + + + +
+ Handles all combat phase updates including enemy movement, attacks, and collisions +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
timestamp + + +number + + + + Current game time in milliseconds
deltaTime + + +number + + + + Time elapsed since last frame + +Key concepts: +- Game state updates +- Entity management (enemies, towers, projectiles) +- Particle effects +- Combat mechanics
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) handleGameOver()

+ + + + + + +
+ Handles game over state and prompts for restart +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) handleLevelComplete()

+ + + + + + +
+ Handles the transition between levels +Shows completion message and sets up next level +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) initializeEventListeners()

+ + + + + + +
+ Sets up all event listeners for user interaction + +Key concepts: +- Event-driven programming +- HTML5 Drag and Drop API +- DOM manipulation +- Method decoration (towers.push) +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) populateTowerPalette()

+ + + + + + +
+ Dynamically populates the tower palette based on TowerTypes +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) renderGame()

+ + + + + + +
+ Renders all game elements to the canvas using a layered approach. +This function demonstrates several key game development patterns: + +1. Canvas State Management: + - Uses save()/restore() to isolate rendering contexts + - Resets transform matrix to prevent state leaks + - Maintains clean state between rendering phases + +2. Layered Rendering Pattern: + - Renders in specific order (background → entities → UI) + - Each layer builds on top of previous layers + - Separates rendering concerns for easier maintenance + +3. Separation of Concerns: + - Each render function handles one specific type of game element + - UI rendering is isolated from game element rendering + - Clear boundaries between different rendering responsibilities + +The rendering order is important: +1. Grid (background) +2. Particles (effects under entities) +3. Projectiles (dynamic game elements) +4. Towers (static game entities) +5. Enemies (moving game entities) +6. UI (top layer) +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) restartGame()

+ + + + + + +
+ Restarts the game from level 1 with fresh state +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) spawnEnemies(timestamp)

+ + + + + + +
+ Spawns new enemies at regular intervals during combat +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
timestamp + + +number + + + + Current game time in milliseconds + +Key concepts: +- Time-based game events +- Enemy creation and management +- Game balance through spawn timing
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) startCombat()

+ + + + + + +
+ Transitions the game from placement to combat phase. +Demonstrates state machine pattern commonly used in games. + +Side effects: +- Updates game phase +- Disables UI elements +- Updates visual feedback +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) startNextLevel()

+ + + + + + +
+ Sets up the next level +Increases difficulty and resets the game state while preserving currency +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/module-gameState.html b/html/tower/docs/module-gameState.html new file mode 100644 index 0000000..84feb7b --- /dev/null +++ b/html/tower/docs/module-gameState.html @@ -0,0 +1,1407 @@ + + + + + JSDoc: Module: gameState + + + + + + + + + + +
+ +

Module: gameState

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Game State Module + +This module defines the game state and game phases
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

(inner, constant) EnemyTypes :string

+ + + + +
+ Enemy types +
+ + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
BASIC + + +string + + + +
RANGED + + +string + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

(inner, constant) GamePhase :string

+ + + + +
+ Game phases +
+ + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
PLACEMENT + + +string + + + +
COMBAT + + +string + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

(inner, constant) ParticleTypes :string

+ + + + +
+ Particle types +
+ + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
DEATH_PARTICLE + + +string + + + +
PROJECTILE + + +string + + + +
AOE_EXPLOSION + + +string + + + +
SLIME_TRAIL + + +string + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

(inner, constant) TowerTypes :string

+ + + + +
+ Tower types +
+ + + +
Type:
+
    +
  • + +string + + +
  • +
+ + + + + +
Properties:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
BASIC + + +string + + + +
RAPID + + +string + + + +
SNIPER + + +string + + + +
GOOP + + +string + + + +
AOE + + +string + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

(inner, constant) gameState :Object

+ + + + +
+ Game state +
+ + + +
Type:
+
    +
  • + +Object + + +
  • +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

(inner) createEnemy(startPosition)

+ + + + + + +
+ Creates an enemy +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
startPosition + + +Object + + + + Starting position of the enemy
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) createParticle(type, position)

+ + + + + + +
+ Creates a particle +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
type + + +string + + + + Particle type
position + + +Object + + + + Position of the particle
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) createTower(type, position)

+ + + + + + +
+ Creates a tower +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
type + + +string + + + + Tower type
position + + +Object + + + + Position of the tower
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/module-mechanics.html b/html/tower/docs/module-mechanics.html new file mode 100644 index 0000000..acfb5c7 --- /dev/null +++ b/html/tower/docs/module-mechanics.html @@ -0,0 +1,2286 @@ + + + + + JSDoc: Module: mechanics + + + + + + + + + + +
+ +

Module: mechanics

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Combat Mechanics Module + +This module handles all combat-related game mechanics including: +1. Enemy movement and behavior +2. Tower attacks and targeting +3. Projectile and particle systems +4. Status effects and special abilities
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) createDeathParticles(target, cellSize) → {Array.<Object>}

+ + + + + + +
+ Creates death effect particles for defeated entities +Implements visual feedback system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
target + + +Object + + + + The defeated entity
cellSize + + +number + + + + Size of grid cell for scaling
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Array of particle objects +
+ + + +
+
+ Type +
+
+ +Array.<Object> + + +
+
+ + + + + + + + + + + + + +

(inner) findTowersInRange(enemy, towers) → {Array.<Object>}

+ + + + + + +
+ Finds towers within enemy attack range +Implements targeting system for enemies +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
enemy + + +Object + + + + Enemy doing the targeting
towers + + +Array.<Object> + + + + Array of potential tower targets
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Array of towers in range +
+ + + +
+
+ Type +
+
+ +Array.<Object> + + +
+
+ + + + + + + + + + + + + +

(inner) handleAOEEffect(target, tower, enemies, particles, cellSize)

+ + + + + + +
+ Handles AOE (Area of Effect) damage and visual effects +Implements area damage system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
target + + +Object + + + + Primary target
tower + + +Object + + + + Tower dealing AOE damage
enemies + + +Array.<Object> + + + + All enemies for AOE calculation
particles + + +Array.<Object> + + + + Particle array for effects
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) handleEnemyAttack(enemy, tower, particles, timestamp, cellSize)

+ + + + + + +
+ Handles enemy attack execution and effects +Implements enemy combat mechanics +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
enemy + + +Object + + + + Attacking enemy
tower + + +Object + + + + Target tower
particles + + +Array.<Object> + + + + Particle array for effects
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) handleSlowEffect(target, tower, timestamp, particles, cellSize)

+ + + + + + +
+ Handles slow effect application and stacking +Implements status effect system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
target + + +Object + + + + Enemy to apply slow to
tower + + +Object + + + + Tower applying the effect
timestamp + + +number + + + + Current game timestamp
particles + + +Array.<Object> + + + + Particle array for effects
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) handleTowerAttack(tower, target, projectiles, particles, timestamp, cellSize)

+ + + + + + +
+ Handles individual tower attack logic including special effects +Implements tower ability system +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
tower + + +Object + + + + Attacking tower
target + + +Object + + + + Target enemy
projectiles + + +Array.<Object> + + + + Projectile array
particles + + +Array.<Object> + + + + Particle array
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) processEnemyAttacks(enemies, towers, particles, timestamp, cellSize)

+ + + + + + +
+ Processes enemy attack behaviors and targeting +Implements enemy combat AI +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
enemies + + +Array.<Object> + + + + Array of enemy objects
towers + + +Array.<Object> + + + + Array of tower objects
particles + + +Array.<Object> + + + + Particle effect array
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Grid cell size
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) processTowerAttacks(towers, enemies, projectiles, particles, timestamp, cellSize)

+ + + + + + +
+ Processes tower attacks and targeting +Implements combat mechanics and special abilities +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
towers + + +Array.<Object> + + + + Array of tower objects
enemies + + +Array.<Object> + + + + Array of enemy objects
projectiles + + +Array.<Object> + + + + Array of projectile objects
particles + + +Array.<Object> + + + + Array of particle objects
timestamp + + +number + + + + Current game timestamp
cellSize + + +number + + + + Size of grid cell for scaling
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) updateEnemies() → {void}

+ + + + + + +
+ Updates all enemy states including movement, health, and status effects +Implements core game loop mechanics for enemy behavior + +Key features: +- Path following +- Health management +- Status effect processing +- Collision detection +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

(inner) updateParticles(particles, timestamp, deltaTime) → {Array.<Object>}

+ + + + + + +
+ Updates particle effects with time-based animation +Implements particle system lifecycle management +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
particles + + +Array.<Object> + + + + Array of particle objects
timestamp + + +number + + + + Current game timestamp
deltaTime + + +number + + + + Time elapsed since last frame
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Updated particles array +
+ + + +
+
+ Type +
+
+ +Array.<Object> + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/module-path.html b/html/tower/docs/module-path.html new file mode 100644 index 0000000..42b3180 --- /dev/null +++ b/html/tower/docs/module-path.html @@ -0,0 +1,531 @@ + + + + + JSDoc: Module: path + + + + + + + + + + +
+ +

Module: path

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Path Generation Module + +This module demonstrates several advanced game development concepts: +1. Procedural Content Generation (PCG) +2. Pathfinding algorithms +3. Constraint-based generation
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) generatePath(grid) → {Promise.<Array.<{x: number, y: number}>>}

+ + + + + + +
+ Generates a valid path through the game grid using a modified depth-first search. +This algorithm ensures: +- Path always moves from left to right +- No diagonal movements +- No path segments touch each other (except at turns) +- Path is always completable +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
grid + + +Array.<Array.<string>> + + + + 2D array representing the game grid
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Promise resolving to array of path coordinates + +Implementation uses: +- Backtracking algorithm pattern +- Constraint satisfaction +- Random selection for variety +
+ + + +
+
+ Type +
+
+ +Promise.<Array.<{x: number, y: number}>> + + +
+
+ + + + + + + + + + + + + +

(inner) getPathPosition(progress, path) → {Object}

+ + + + + + +
+ Calculates a position along the path based on a progress value +Implements smooth entity movement along path segments +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
progress + + +number + + + + Progress along path (0-1)
path + + +Array.<{x: number, y: number}> + + + + Array of path coordinates
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Interpolated position along path + +Uses: +- Linear interpolation (lerp) +- Path segment traversal +- Normalized progress tracking +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/module-renderer.html b/html/tower/docs/module-renderer.html new file mode 100644 index 0000000..bed9852 --- /dev/null +++ b/html/tower/docs/module-renderer.html @@ -0,0 +1,659 @@ + + + + + JSDoc: Module: renderer + + + + + + + + + + +
+ +

Module: renderer

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Rendering Module + +This module handles all game rendering operations using HTML5 Canvas. +Demonstrates key game development patterns: +1. Layer-based rendering +2. Particle systems +3. Visual state feedback +4. Canvas state management
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) renderEnemies(ctx, enemies)

+ + + + + + +
+ Renders all enemies with health indicators and effects +Implements visual state representation +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + + Canvas rendering context
enemies + + +Array.<Object> + + + + Array of enemy objects
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) renderGrid(ctx, grid)

+ + + + + + +
+ Renders the game grid with path and hover previews +Implements visual feedback for player actions +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + + Canvas rendering context
grid + + +Array.<Array.<string>> + + + + Game grid state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(inner) renderUI(ctx, gameState)

+ + + + + + +
+ Renders game UI elements with clean state management +Implements heads-up display (HUD) pattern +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +CanvasRenderingContext2D + + + + Canvas rendering context
gameState + + +Object + + + + Current game state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/module-uiHandlers.html b/html/tower/docs/module-uiHandlers.html new file mode 100644 index 0000000..fc3fdc4 --- /dev/null +++ b/html/tower/docs/module-uiHandlers.html @@ -0,0 +1,543 @@ + + + + + JSDoc: Module: uiHandlers + + + + + + + + + + +
+ +

Module: uiHandlers

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
UI Handlers Module + +This module manages user interactions and UI state. +Implements: +1. Drag and Drop system +2. Event handling +3. UI state management +4. Input validation
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) initializeDragAndDrop(canvas, gameState) → {Object}

+ + + + + + +
+ Initializes drag and drop functionality for tower placement +Implements HTML5 Drag and Drop API +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
canvas + + +HTMLCanvasElement + + + + Game canvas element
gameState + + +Object + + + + Current game state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Drag handlers and state information +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

(inner) placeTower(gameState, towerType, position)

+ + + + + + +
+ Places a tower in the game grid +Implements tower placement validation and state updates +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
gameState + + +Object + + + + Current game state
towerType + + +string + + + + Type of tower to place
position + + +Object + + + + Grid position for placement
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/html/tower/docs/path.js.html b/html/tower/docs/path.js.html new file mode 100644 index 0000000..ff45ba3 --- /dev/null +++ b/html/tower/docs/path.js.html @@ -0,0 +1,226 @@ + + + + + JSDoc: Source: path.js + + + + + + + + + + +
+ +

Source: path.js

+ + + + + + +
+
+
/**
+ * Path Generation Module
+ * 
+ * This module demonstrates several advanced game development concepts:
+ * 1. Procedural Content Generation (PCG)
+ * 2. Pathfinding algorithms
+ * 3. Constraint-based generation
+ * 
+ * @module path
+ */
+
+/**
+ * Generates a valid path through the game grid using a modified depth-first search.
+ * This algorithm ensures:
+ * - Path always moves from left to right
+ * - No diagonal movements
+ * - No path segments touch each other (except at turns)
+ * - Path is always completable
+ * 
+ * @param {Array<Array<string>>} grid - 2D array representing the game grid
+ * @returns {Promise<Array<{x: number, y: number}>>} Promise resolving to array of path coordinates
+ * 
+ * Implementation uses:
+ * - Backtracking algorithm pattern
+ * - Constraint satisfaction
+ * - Random selection for variety
+ */
+function generatePath(grid) {
+    const width = grid[0].length;
+    const height = grid.length;
+    
+    // Initialize with random start point on left edge
+    const startY = Math.floor(Math.random() * height);
+    let currentPos = { x: 0, y: startY };
+    
+    const path = [currentPos];
+    grid[startY][0] = 'path';
+    
+    /**
+     * Determines valid moves from current position based on game rules
+     * Uses constraint checking to ensure path validity
+     * 
+     * @param {Object} pos - Current position {x, y}
+     * @returns {Array<{x: number, y: number}>} Array of valid next positions
+     */
+    function getValidMoves(pos) {
+        const moves = [];
+        // Prioritize right movement for path progression
+        const directions = [
+            { x: 1, y: 0 },  // right
+            { x: 0, y: -1 }, // up
+            { x: 0, y: 1 }   // down
+        ];
+        
+        for (const dir of directions) {
+            const newX = pos.x + dir.x;
+            const newY = pos.y + dir.y;
+            
+            // Enforce boundary constraints
+            if (newX < 0 || newX >= width || newY < 0 || newY >= height) {
+                continue;
+            }
+            
+            // Check path isolation constraint
+            if (grid[newY][newX] === 'empty' && !hasAdjacentPath(newX, newY, grid)) {
+                moves.push({ x: newX, y: newY });
+            }
+        }
+        
+        return moves;
+    }
+    
+    /**
+     * Checks if a position has adjacent path tiles (excluding previous path tile)
+     * Implements path isolation constraint
+     * 
+     * @param {number} x - X coordinate to check
+     * @param {number} y - Y coordinate to check
+     * @param {Array<Array<string>>} grid - Current grid state
+     * @returns {boolean} True if position has adjacent path tiles
+     */
+    function hasAdjacentPath(x, y, grid) {
+        const adjacentCells = [
+            { x: x, y: y - 1 },     // up
+            { x: x, y: y + 1 },     // down
+            { x: x - 1, y: y },     // left
+            { x: x + 1, y: y },     // right
+        ];
+        
+        return adjacentCells.some(cell => {
+            if (cell.x < 0 || cell.x >= width || cell.y < 0 || cell.y >= height) {
+                return false;
+            }
+            return grid[cell.y][cell.x] === 'path' && 
+                   !path.some(p => p.x === cell.x && p.y === cell.y);
+        });
+    }
+    
+    // Main path generation loop with backtracking
+    while (currentPos.x < width - 1) {
+        const moves = getValidMoves(currentPos);
+        
+        if (moves.length === 0) {
+            // Backtrack when no valid moves exist
+            if (path.length <= 1) {
+                // Restart if backtracking fails
+                return generatePath(grid);
+            }
+            
+            path.pop();
+            const lastPos = path[path.length - 1];
+            grid[currentPos.y][currentPos.x] = 'empty';
+            currentPos = lastPos;
+            continue;
+        }
+        
+        // Random selection for path variety
+        const nextMove = moves[Math.floor(Math.random() * moves.length)];
+        currentPos = nextMove;
+        path.push(currentPos);
+        grid[currentPos.y][currentPos.x] = 'path';
+    }
+    
+    return Promise.resolve(path);
+}
+
+/**
+ * Calculates a position along the path based on a progress value
+ * Implements smooth entity movement along path segments
+ * 
+ * @param {number} progress - Progress along path (0-1)
+ * @param {Array<{x: number, y: number}>} path - Array of path coordinates
+ * @returns {{x: number, y: number}} Interpolated position along path
+ * 
+ * Uses:
+ * - Linear interpolation (lerp)
+ * - Path segment traversal
+ * - Normalized progress tracking
+ */
+function getPathPosition(progress, path) {
+    // Normalize progress to valid range
+    progress = Math.max(0, Math.min(1, progress));
+    
+    // Calculate total path length for normalization
+    let totalLength = 0;
+    for (let i = 1; i < path.length; i++) {
+        const dx = path[i].x - path[i-1].x;
+        const dy = path[i].y - path[i-1].y;
+        totalLength += Math.sqrt(dx * dx + dy * dy);
+    }
+    
+    // Convert progress to distance along path
+    const targetDistance = progress * totalLength;
+    
+    // Find appropriate path segment
+    let currentDistance = 0;
+    for (let i = 1; i < path.length; i++) {
+        const dx = path[i].x - path[i-1].x;
+        const dy = path[i].y - path[i-1].y;
+        const segmentLength = Math.sqrt(dx * dx + dy * dy);
+        
+        if (currentDistance + segmentLength >= targetDistance) {
+            // Linear interpolation within segment
+            const segmentProgress = (targetDistance - currentDistance) / segmentLength;
+            return {
+                x: path[i-1].x + dx * segmentProgress,
+                y: path[i-1].y + dy * segmentProgress
+            };
+        }
+        
+        currentDistance += segmentLength;
+    }
+    
+    // Fallback to end of path
+    return { ...path[path.length - 1] };
+} 
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/html/tower/docs/renderer.js.html b/html/tower/docs/renderer.js.html new file mode 100644 index 0000000..ed49c44 --- /dev/null +++ b/html/tower/docs/renderer.js.html @@ -0,0 +1,431 @@ + + + + + JSDoc: Source: renderer.js + + + + + + + + + + +
+ +

Source: renderer.js

+ + + + + + +
+
+
/**
+ * Rendering Module
+ * 
+ * This module handles all game rendering operations using HTML5 Canvas.
+ * Demonstrates key game development patterns:
+ * 1. Layer-based rendering
+ * 2. Particle systems
+ * 3. Visual state feedback
+ * 4. Canvas state management
+ * 
+ * @module renderer
+ */
+
+/**
+ * Renders the game grid with path and hover previews
+ * Implements visual feedback for player actions
+ * 
+ * @param {CanvasRenderingContext2D} ctx - Canvas rendering context
+ * @param {Array<Array<string>>} grid - Game grid state
+ */
+function renderGrid(ctx, grid) {
+    const cellSize = canvas.width / 20;
+    
+    // Draw grid lines for visual reference
+    ctx.strokeStyle = '#ccc';
+    ctx.lineWidth = 1;
+    
+    for (let i = 0; i <= 20; i++) {
+        // Vertical lines
+        ctx.beginPath();
+        ctx.moveTo(i * cellSize, 0);
+        ctx.lineTo(i * cellSize, canvas.height);
+        ctx.stroke();
+        
+        // Horizontal lines
+        ctx.beginPath();
+        ctx.moveTo(0, i * cellSize);
+        ctx.lineTo(canvas.width, i * cellSize);
+        ctx.stroke();
+    }
+    
+    // Render grid cells with path highlighting
+    grid.forEach((row, y) => {
+        row.forEach((cell, x) => {
+            if (cell === 'path') {
+                ctx.fillStyle = '#f4a460';
+                ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
+            }
+        });
+    });
+
+    // Render tower placement preview
+    if (gameState.phase === GamePhase.PLACEMENT && draggedTowerType && hoverCell) {
+        const tower = TowerTypes[draggedTowerType];
+        const canPlace = grid[hoverCell.y][hoverCell.x] === 'empty' &&
+                        gameState.playerCurrency >= tower.cost;
+        
+        // Visual feedback for placement validity
+        ctx.fillStyle = canPlace ? tower.color + '80' : 'rgba(255, 0, 0, 0.3)';
+        ctx.fillRect(
+            hoverCell.x * cellSize,
+            hoverCell.y * cellSize,
+            cellSize,
+            cellSize
+        );
+        
+        // Range indicator preview
+        ctx.beginPath();
+        ctx.arc(
+            (hoverCell.x + 0.5) * cellSize,
+            (hoverCell.y + 0.5) * cellSize,
+            tower.range * cellSize,
+            0,
+            Math.PI * 2
+        );
+        ctx.strokeStyle = canPlace ? tower.color + '40' : 'rgba(255, 0, 0, 0.2)';
+        ctx.stroke();
+    }
+}
+
+/**
+ * Renders all enemies with health indicators and effects
+ * Implements visual state representation
+ * 
+ * @param {CanvasRenderingContext2D} ctx - Canvas rendering context
+ * @param {Array<Object>} enemies - Array of enemy objects
+ */
+function renderEnemies(ctx, enemies) {
+    const cellSize = canvas.width / 20;
+    
+    enemies.forEach(enemy => {
+        // Health-based opacity for visual feedback
+        const healthPercent = enemy.currentHealth / enemy.maxHealth;
+        const opacity = 0.3 + (healthPercent * 0.7);
+        
+        // Dynamic color based on enemy state
+        const color = EnemyTypes[enemy.type].color;
+        const hexOpacity = Math.floor(opacity * 255).toString(16).padStart(2, '0');
+        
+        // Draw enemy body with solid black border
+        ctx.beginPath();
+        ctx.arc(
+            (enemy.position.x + 0.5) * cellSize,
+            (enemy.position.y + 0.5) * cellSize,
+            cellSize / 3,
+            0,
+            Math.PI * 2
+        );
+        
+        // Fill with dynamic opacity
+        ctx.fillStyle = `${color}${hexOpacity}`;
+        ctx.fill();
+        
+        // Add solid black border
+        ctx.strokeStyle = 'black';
+        ctx.lineWidth = 2;
+        ctx.stroke();
+        
+        // Range indicator for special enemy types
+        if (EnemyTypes[enemy.type].isRanged) {
+            ctx.beginPath();
+            ctx.arc(
+                (enemy.position.x + 0.5) * cellSize,
+                (enemy.position.y + 0.5) * cellSize,
+                EnemyTypes[enemy.type].attackRange * cellSize,
+                0,
+                Math.PI * 2
+            );
+            ctx.strokeStyle = `${EnemyTypes[enemy.type].color}40`;
+            ctx.stroke();
+        }
+    });
+}
+
+/**
+ * Renders game UI elements with clean state management
+ * Implements heads-up display (HUD) pattern
+ * 
+ * @param {CanvasRenderingContext2D} ctx - Canvas rendering context
+ * @param {Object} gameState - Current game state
+ */
+function renderUI(ctx, gameState) {
+    const padding = 20;
+    const lineHeight = 30;
+    const startY = padding;
+    const width = 200;
+    const height = lineHeight * 5;
+    
+    // Save the current canvas state
+    ctx.save();
+    
+    // Reset any transformations
+    ctx.setTransform(1, 0, 0, 1, 0, 0);
+    
+    // Semi-transparent background for readability
+    ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
+    ctx.fillRect(0, 0, width, height + padding);
+    
+    // Text rendering setup
+    ctx.fillStyle = 'black';
+    ctx.font = '20px Arial';
+    ctx.textAlign = 'left';
+    ctx.textBaseline = 'top';
+    
+    // Game state information
+    ctx.fillText(`Level: ${gameState.level}`, padding, startY);
+    ctx.fillText(`Currency: $${gameState.currency}`, padding, startY + lineHeight);
+    ctx.fillText(`Phase: ${gameState.phase}`, padding, startY + lineHeight * 2);
+    ctx.fillText(`Destroyed: ${gameState.enemiesDestroyed}`, padding, startY + lineHeight * 3);
+    ctx.fillText(`Escaped: ${gameState.enemiesEscaped}`, padding, startY + lineHeight * 4);
+    
+    // Restore the canvas state
+    ctx.restore();
+}
+
+function renderTowers(ctx, towers) {
+    const cellSize = canvas.width / 20;
+    
+    towers.forEach(tower => {
+        const healthPercent = tower.currentHealth / tower.maxHealth;
+        
+        // Draw tower body
+        ctx.fillStyle = tower.color + Math.floor(healthPercent * 255).toString(16).padStart(2, '0');
+        ctx.fillRect(
+            tower.position.x * cellSize + cellSize * 0.1,
+            tower.position.y * cellSize + cellSize * 0.1,
+            cellSize * 0.8,
+            cellSize * 0.8
+        );
+        
+        // Draw ammo count
+        ctx.fillStyle = 'white';
+        ctx.font = '12px Arial';
+        ctx.textAlign = 'center';
+        ctx.fillText(
+            tower.ammo,
+            (tower.position.x + 0.5) * cellSize,
+            (tower.position.y + 0.7) * cellSize
+        );
+        
+        // Draw range indicator
+        if (gameState.phase === GamePhase.PLACEMENT) {
+            ctx.beginPath();
+            ctx.arc(
+                (tower.position.x + 0.5) * cellSize,
+                (tower.position.y + 0.5) * cellSize,
+                tower.range * cellSize,
+                0,
+                Math.PI * 2
+            );
+            ctx.strokeStyle = tower.color + '40';
+            ctx.stroke();
+        }
+    });
+}
+
+// Add new render function for particles
+function renderParticles(ctx, particles) {
+    particles.forEach(particle => {
+        const age = performance.now() - particle.createdAt;
+        const lifePercent = age / particle.lifetime;
+        
+        if (lifePercent <= 1) {
+            if (particle.type === 'SLIME_TRAIL') {
+                // Calculate opacity based on lifetime and fade start
+                let opacity = 1;
+                if (lifePercent > particle.fadeStart) {
+                    opacity = 1 - ((lifePercent - particle.fadeStart) / (1 - particle.fadeStart));
+                }
+                opacity *= 0.3; // Make it translucent
+                
+                ctx.globalAlpha = opacity;
+                ctx.fillStyle = particle.color;
+                
+                // Draw a circular slime splat
+                ctx.beginPath();
+                ctx.arc(
+                    particle.position.x,
+                    particle.position.y,
+                    particle.size * (1 - lifePercent * 0.3), // Slightly shrink over time
+                    0,
+                    Math.PI * 2
+                );
+                ctx.fill();
+                
+                // Add some variation to the splat
+                for (let i = 0; i < 3; i++) {
+                    const angle = (Math.PI * 2 * i) / 3;
+                    const distance = particle.size * 0.4;
+                    ctx.beginPath();
+                    ctx.arc(
+                        particle.position.x + Math.cos(angle) * distance,
+                        particle.position.y + Math.sin(angle) * distance,
+                        particle.size * 0.4 * (1 - lifePercent * 0.3),
+                        0,
+                        Math.PI * 2
+                    );
+                    ctx.fill();
+                }
+            } else if (particle.type === 'AOE_EXPLOSION') {
+                // Draw expanding circle
+                const radius = particle.initialRadius + 
+                    (particle.finalRadius - particle.initialRadius) * lifePercent;
+                
+                // Draw multiple rings for better effect
+                const numRings = 3;
+                for (let i = 0; i < numRings; i++) {
+                    const ringRadius = radius * (1 - (i * 0.2));
+                    const ringAlpha = (1 - lifePercent) * (1 - (i * 0.3));
+                    
+                    ctx.beginPath();
+                    ctx.arc(
+                        particle.position.x,
+                        particle.position.y,
+                        ringRadius,
+                        0,
+                        Math.PI * 2
+                    );
+                    ctx.strokeStyle = particle.color;
+                    ctx.lineWidth = particle.ringWidth * (1 - (i * 0.2));
+                    ctx.globalAlpha = ringAlpha;
+                    ctx.stroke();
+                }
+                
+                // Draw affected area
+                ctx.beginPath();
+                ctx.arc(
+                    particle.position.x,
+                    particle.position.y,
+                    radius,
+                    0,
+                    Math.PI * 2
+                );
+                ctx.fillStyle = particle.color + '20'; // Very transparent fill
+                ctx.fill();
+            } else {
+                // Original particle rendering
+                ctx.fillStyle = particle.color;
+                ctx.beginPath();
+                ctx.arc(
+                    particle.position.x,
+                    particle.position.y,
+                    particle.size * (1 - lifePercent),
+                    0,
+                    Math.PI * 2
+                );
+                ctx.fill();
+            }
+        }
+    });
+    ctx.globalAlpha = 1;
+}
+
+// Add new render function for projectiles
+function renderProjectiles(ctx, projectiles) {
+    const cellSize = canvas.width / 20;
+    
+    projectiles.forEach(projectile => {
+        const age = performance.now() - projectile.createdAt;
+        const progress = age / projectile.lifetime;
+        
+        if (progress <= 1) {
+            // Draw projectile trail
+            ctx.beginPath();
+            ctx.moveTo(
+                projectile.startPos.x * cellSize + cellSize / 2,
+                projectile.startPos.y * cellSize + cellSize / 2
+            );
+            
+            const currentX = projectile.startPos.x + (projectile.targetPos.x - projectile.startPos.x) * progress;
+            const currentY = projectile.startPos.y + (projectile.targetPos.y - projectile.startPos.y) * progress;
+            
+            ctx.lineTo(
+                currentX * cellSize + cellSize / 2,
+                currentY * cellSize + cellSize / 2
+            );
+            
+            ctx.strokeStyle = '#fff';
+            ctx.lineWidth = 2;
+            ctx.stroke();
+            
+            // Draw projectile head
+            ctx.beginPath();
+            ctx.arc(
+                currentX * cellSize + cellSize / 2,
+                currentY * cellSize + cellSize / 2,
+                4,
+                0,
+                Math.PI * 2
+            );
+            ctx.fillStyle = '#fff';
+            ctx.fill();
+        }
+    });
+}
+
+// Update level complete message in game.js
+function handleLevelComplete() {
+    gameState.phase = GamePhase.TRANSITION;
+    
+    // Calculate ammo bonus
+    let ammoBonus = 0;
+    gameState.towers.forEach(tower => {
+        ammoBonus += tower.ammo * 2;
+    });
+    
+    const message = `
+        Level ${gameState.level} Complete!
+        Current Money: $${gameState.currency}
+        Ammo Bonus: +$${ammoBonus}
+        Level Bonus: +$10
+        
+        Ready for Level ${gameState.level + 1}?
+    `;
+    
+    setTimeout(() => {
+        if (confirm(message)) {
+            startNextLevel();
+        }
+    }, 100);
+} 
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/html/tower/docs/scripts/linenumber.js b/html/tower/docs/scripts/linenumber.js new file mode 100644 index 0000000..4354785 --- /dev/null +++ b/html/tower/docs/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(() => { + const source = document.getElementsByClassName('prettyprint source linenums'); + let i = 0; + let lineNumber = 0; + let lineId; + let lines; + let totalLines; + let anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = `line${lineNumber}`; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/html/tower/docs/scripts/prettify/Apache-License-2.0.txt b/html/tower/docs/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/html/tower/docs/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/html/tower/docs/scripts/prettify/lang-css.js b/html/tower/docs/scripts/prettify/lang-css.js new file mode 100644 index 0000000..041e1f5 --- /dev/null +++ b/html/tower/docs/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/html/tower/docs/scripts/prettify/prettify.js b/html/tower/docs/scripts/prettify/prettify.js new file mode 100644 index 0000000..eef5ad7 --- /dev/null +++ b/html/tower/docs/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } + +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a +{ + color: #999 !important; + text-decoration: none; +} + +.clear +{ + clear: both; +} + +.important +{ + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px; +} + +.type-signature { + color: #aaa; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.details { margin-top: 14px; border-left: 2px solid #DDD; } +.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } +.details dd { margin-left: 70px; } +.details ul { margin: 0; } +.details ul { list-style-type: none; } +.details li { margin-left: 30px; padding-top: 6px; } +.details pre.prettyprint { margin: 0 } +.details .object-value { padding-top: 0; } + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption +{ + font-style: italic; + font-size: 107%; + margin: 0; +} + +.source +{ + border: 1px solid #ddd; + width: 80%; + overflow: auto; +} + +.prettyprint.source { + width: inherit; +} + +.source code +{ + font-size: 100%; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint code span.line +{ + display: inline-block; +} + +.prettyprint.linenums +{ + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol +{ + padding-left: 0; +} + +.prettyprint.linenums li +{ + border-left: 3px #ddd solid; +} + +.prettyprint.linenums li.selected, +.prettyprint.linenums li.selected * +{ + background-color: lightyellow; +} + +.prettyprint.linenums li * +{ + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td.description > p:first-child, +.props td.description > p:first-child +{ + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child +{ + margin-bottom: 0; + padding-bottom: 0; +} + +.disabled { + color: #454545; +} diff --git a/html/tower/docs/styles/prettify-jsdoc.css b/html/tower/docs/styles/prettify-jsdoc.css new file mode 100644 index 0000000..5a2526e --- /dev/null +++ b/html/tower/docs/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/html/tower/docs/styles/prettify-tomorrow.css b/html/tower/docs/styles/prettify-tomorrow.css new file mode 100644 index 0000000..b6f92a7 --- /dev/null +++ b/html/tower/docs/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: #718c00; } + + /* a keyword */ + .kwd { + color: #8959a8; } + + /* a comment */ + .com { + color: #8e908c; } + + /* a type name */ + .typ { + color: #4271ae; } + + /* a literal value */ + .lit { + color: #f5871f; } + + /* punctuation */ + .pun { + color: #4d4d4c; } + + /* lisp open bracket */ + .opn { + color: #4d4d4c; } + + /* lisp close bracket */ + .clo { + color: #4d4d4c; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ } diff --git a/html/tower/docs/uiHandlers.js.html b/html/tower/docs/uiHandlers.js.html new file mode 100644 index 0000000..35f3867 --- /dev/null +++ b/html/tower/docs/uiHandlers.js.html @@ -0,0 +1,146 @@ + + + + + JSDoc: Source: uiHandlers.js + + + + + + + + + + +
+ +

Source: uiHandlers.js

+ + + + + + +
+
+
/**
+ * UI Handlers Module
+ * 
+ * This module manages user interactions and UI state.
+ * Implements:
+ * 1. Drag and Drop system
+ * 2. Event handling
+ * 3. UI state management
+ * 4. Input validation
+ * 
+ * @module uiHandlers
+ */
+
+/**
+ * Initializes drag and drop functionality for tower placement
+ * Implements HTML5 Drag and Drop API
+ * 
+ * @param {HTMLCanvasElement} canvas - Game canvas element
+ * @param {Object} gameState - Current game state
+ * @returns {Object} Drag handlers and state information
+ */
+function initializeDragAndDrop(canvas, gameState) {
+    let draggedTowerType = null;
+    let hoverCell = null;
+
+    const dragHandlers = {
+        /**
+         * Handles start of tower drag operation
+         * Sets up drag data and visual feedback
+         */
+        onDragStart: (e) => {
+            draggedTowerType = e.target.dataset.towerType;
+            e.dataTransfer.setData('text/plain', '');
+        },
+        
+        /**
+         * Handles end of drag operation
+         * Cleans up drag state
+         */
+        onDragEnd: () => {
+            draggedTowerType = null;
+            hoverCell = null;
+        },
+        
+        /**
+         * Handles drag over canvas
+         * Updates hover position and preview
+         */
+        onDragOver: (e) => {
+            e.preventDefault();
+            const rect = canvas.getBoundingClientRect();
+            const x = Math.floor((e.clientX - rect.left) / (canvas.width / 20));
+            const y = Math.floor((e.clientY - rect.top) / (canvas.height / 20));
+            
+            hoverCell = (x >= 0 && x < 20 && y >= 0 && y < 20) ? { x, y } : null;
+        },
+        
+        /**
+         * Handles tower placement on drop
+         * Validates placement and updates game state
+         */
+        onDrop: (e) => {
+            e.preventDefault();
+            if (!draggedTowerType || !hoverCell) return;
+            
+            placeTower(gameState, draggedTowerType, hoverCell);
+            draggedTowerType = null;
+            hoverCell = null;
+        }
+    };
+
+    return { 
+        dragHandlers, 
+        getHoverInfo: () => ({ draggedTowerType, hoverCell }) 
+    };
+}
+
+/**
+ * Places a tower in the game grid
+ * Implements tower placement validation and state updates
+ * 
+ * @param {Object} gameState - Current game state
+ * @param {string} towerType - Type of tower to place
+ * @param {Object} position - Grid position for placement
+ */
+function placeTower(gameState, towerType, position) {
+    const tower = TowerTypes[towerType];
+    if (
+        gameState.grid[position.y][position.x] === 'empty' &&
+        gameState.currency >= tower.cost
+    ) {
+        gameState.grid[position.y][position.x] = 'tower';
+        gameState.towers.push(createTower(towerType, { ...position }));
+        gameState.currency -= tower.cost;
+    }
+} 
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 4.0.3 on Mon Feb 17 2025 09:19:19 GMT-0500 (Eastern Standard Time) +
+ + + + + diff --git a/html/tower/js/game.js b/html/tower/js/game.js index 7495fbe..4d8ed39 100644 --- a/html/tower/js/game.js +++ b/html/tower/js/game.js @@ -1,3 +1,13 @@ +// generate updated docs +// jsdoc js -d docs + +/** + * Main game entry point + * Initializes the game state and starts the game loop + * + * @module game + */ + /** Canvas elements for rendering the game */ const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); diff --git a/html/tower/js/gameState.js b/html/tower/js/gameState.js index 3cee9ed..ac7a968 100644 --- a/html/tower/js/gameState.js +++ b/html/tower/js/gameState.js @@ -1,8 +1,29 @@ +/** + * Game State Module + * + * This module defines the game state and game phases + * + * @module gameState + */ + + +/** + * Game phases + * + * @enum {string} + * @readonly + */ const GamePhase = { PLACEMENT: 'place', COMBAT: 'run' }; +/** + * Tower types + * + * @enum {string} + * @readonly + */ const TowerTypes = { BASIC: { name: 'Basic', @@ -55,6 +76,12 @@ const TowerTypes = { } }; +/** + * Particle types + * + * @enum {string} + * @readonly + */ const ParticleTypes = { DEATH_PARTICLE: { lifetime: 1000, // milliseconds @@ -81,6 +108,12 @@ const ParticleTypes = { } }; +/** + * Enemy types + * + * @enum {string} + * @readonly + */ const EnemyTypes = { BASIC: { color: '#c0392b', @@ -100,6 +133,12 @@ const EnemyTypes = { } }; +/** + * Creates a tower + * + * @param {string} type - Tower type + * @param {Object} position - Position of the tower + */ function createTower(type, position) { const towerType = TowerTypes[type]; return { @@ -113,6 +152,11 @@ function createTower(type, position) { }; } +/** + * Creates an enemy + * + * @param {Object} startPosition - Starting position of the enemy + */ function createEnemy(startPosition) { // 20% chance for ranged enemy const type = Math.random() < 0.2 ? 'RANGED' : 'BASIC'; @@ -138,6 +182,12 @@ function createEnemy(startPosition) { }; } +/** + * Creates a particle + * + * @param {string} type - Particle type + * @param {Object} position - Position of the particle + */ function createParticle(type, position, angle) { return { position: { ...position }, @@ -154,7 +204,12 @@ function createParticle(type, position, angle) { }; } -// Initialize game state at the bottom of the file + +/** + * Game state + * + * @type {Object} + */ const gameState = { grid: Array(20).fill().map(() => Array(20).fill('empty')), path: [], @@ -169,6 +224,9 @@ const gameState = { enemiesEscaped: 0, level: 1, + /** + * Resets the game state + */ resetGame() { this.grid = Array(20).fill().map(() => Array(20).fill('empty')); this.path = []; @@ -184,7 +242,10 @@ const gameState = { this.level = 1; }, - // Define the function as part of the initial object + + /** + * Awards the enemy destroyed + */ awardEnemyDestroyed() { this.enemiesDestroyed++; // Random reward between 1 and 3 @@ -192,14 +253,22 @@ const gameState = { this.currency += reward; }, - // Add method to check for level completion + + /** + * Checks if the level is complete + * + * @returns {boolean} + */ checkLevelComplete() { return this.enemies.length === 0 && enemiesRemaining === 0 && this.phase === GamePhase.COMBAT; }, - // Add method to advance to next level + + /** + * Advances to the next level + */ advanceToNextLevel() { let ammoBonus = 0; diff --git a/html/tower/js/mechanics.js b/html/tower/js/mechanics.js index e9d751a..bc73fff 100644 --- a/html/tower/js/mechanics.js +++ b/html/tower/js/mechanics.js @@ -1,11 +1,13 @@ /** * Combat Mechanics Module - * + * * This module handles all combat-related game mechanics including: * 1. Enemy movement and behavior * 2. Tower attacks and targeting * 3. Projectile and particle systems * 4. Status effects and special abilities + * + * @module mechanics */ /** diff --git a/html/tower/js/path.js b/html/tower/js/path.js index 91193e2..8b840ce 100644 --- a/html/tower/js/path.js +++ b/html/tower/js/path.js @@ -5,6 +5,8 @@ * 1. Procedural Content Generation (PCG) * 2. Pathfinding algorithms * 3. Constraint-based generation + * + * @module path */ /** diff --git a/html/tower/js/renderer.js b/html/tower/js/renderer.js index 29dd35f..fce4b88 100644 --- a/html/tower/js/renderer.js +++ b/html/tower/js/renderer.js @@ -7,6 +7,8 @@ * 2. Particle systems * 3. Visual state feedback * 4. Canvas state management + * + * @module renderer */ /** diff --git a/html/tower/js/uiHandlers.js b/html/tower/js/uiHandlers.js index f171358..00651ca 100644 --- a/html/tower/js/uiHandlers.js +++ b/html/tower/js/uiHandlers.js @@ -7,6 +7,8 @@ * 2. Event handling * 3. UI state management * 4. Input validation + * + * @module uiHandlers */ /** -- cgit 1.4.1-2-gfad0