{"id":18248833,"url":"https://github.com/igorski/weltkriegsimulator","last_synced_at":"2025-04-04T15:32:34.038Z","repository":{"id":39880150,"uuid":"89678047","full_name":"igorski/weltkriegsimulator","owner":"igorski","description":"Vertical scrolling shoot 'em up in the browser, using the zCanvas rendering lib. This is intended as a \"bullet hell\" game and is aimed more to showcase how to use zCanvas for game development.","archived":false,"fork":false,"pushed_at":"2025-03-25T20:20:47.000Z","size":3096,"stargazers_count":5,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-25T21:27:19.096Z","etag":null,"topics":["bullethell","game","schmup","shoot-em-up","shooter","shooting-game","webgame"],"latest_commit_sha":null,"homepage":"https://www.igorski.nl/weltkriegsimulator","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/igorski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-28T07:05:52.000Z","updated_at":"2025-03-25T20:20:47.000Z","dependencies_parsed_at":"2025-03-19T02:15:39.761Z","dependency_job_id":null,"html_url":"https://github.com/igorski/weltkriegsimulator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorski%2Fweltkriegsimulator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorski%2Fweltkriegsimulator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorski%2Fweltkriegsimulator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igorski%2Fweltkriegsimulator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igorski","download_url":"https://codeload.github.com/igorski/weltkriegsimulator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247203115,"owners_count":20900918,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bullethell","game","schmup","shoot-em-up","shooter","shooting-game","webgame"],"created_at":"2024-11-05T09:38:26.209Z","updated_at":"2025-04-04T15:32:29.028Z","avatar_url":"https://github.com/igorski.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WELTKRIEGSIMULATOR\n\n_Weltkriegsimulator_ (WKS) is a vertical scrolling shoot 'em up that was created to showcase the\npossibilities of creating a game using the open source [zCanvas library](https://github.com/igorski/zCanvas).\n\nYou can play the game directly in your browser by [navigating here](https://www.igorski.nl/weltkriegsimulator).\n\n## Project outline\n\nWKS is a Javascript project and uses the ES6 module-pattern in vanilla JS. It's deliberately designed to work\nwithout a framework or library just to focus on the game code. React and Vue are great, but reactivity\nis not required when blitting bitmaps from a game loop.\n\nThe only used libraries besides the aforementioned _zCanvas_ are _TweenMax_ (easing functions),\n_Handlebars_ (for HTML templating) and _pubsub-js_ (for messaging).\n\nAll source code resides in the _./src/js_-directory. The main application logic is split\nup into:\n\n * controllers\n * factory\n * model\n * view\n\nThe _controllers_ are responsible for managing changes in the model and updating the appropriate views. These\ncontrollers are:\n\n * _GameController_ sets up the game, changes game world properties, delegates changes in game state (through _ActionFactory.js_)\n * _InputController_ listens to keyboard/touch input and delegates these actions onto the Player\n * _RenderController_ maintains the zCanvas that will render all of the game's Actors on the screen as well as manage audio events\n * _ScreenController_ overlays different screens (e.g. title screen, game UI, high scores list)\n\nThe _views_ represent each of the screens used in the game. They are managed by their appropriate controllers.\nNote: for the game elements (the Actors) these are represented by _renderers_ (see _zCanvas in WKS_ below).\n\nThe _models_ contain all data and properties. For the game's model (_Game.js_) this is where the\nstate and contents of the game's \"world\" are held. Apart from generic world properties determining the\ngame's behaviour and progress, this model also references the _Actors_. The Actors are instances of all\nObjects in the game (for instance: the player, bullets, powerups, enemy ships). These share common properties\nsuch as coordinates, speed, but have their own custom properties (e.g. energy, weapon damage, etc.). These\nActors are defined as ES6 classes as the Object Oriented Pattern works well for inheritance purposes. The\nremainder of the applications business logic follows the Functional Programming pattern.\n\nFinally, the _factories_ are used to generate data to populate the models. _ActionFactory_ is of interest as\nit generates the enemy waves and the powerups.\n\nCommunication between these models, views and controllers is done using the publish-subscribe pattern where\nmessages are broadcast to subscribed listeners to act upon. As such, different players might be interested in\nthe same message for the same purpose (for instance: a message of GAME_OVER might trigger the _GameController_ to\nstop the action queue and freeze the game loop, while at the same time the _InputController_ decides to stop\nlistening to input events and the _ScreenController_ to open the high score input screen. \"Separate the concerns\"!\n\n## zCanvas in WKS\n\nThe zCanvas is used to render the game \"world\". All other visual components (energy bar, score, menus, etc.) are\noverlaid in HTML.\n\nThe zCanvas is maintained by _RenderController_. It is this controller that creates the zCanvas, sizes it\naccordingly and manages its display list. In WKS, there are multiple layers in the world to give the illusion\nof depth. Each of the games actors are appended to the appropriate according layer.\n\nThe visual representation of an Actor is done using a zCanvas _zSprite_. We refer to these instances as\n_renderers_. All zCanvas renderers reside in the _./src/js/view/renderers_-directory. A renderers only job is\nto _visually represent the state of the Actor_. Game.js knows nothing about renderers, and it doesn't have to, it\nmerely updates the actors in the game world.\n\nOn each render cycle (60 times per second) of the zCanvas, zCanvas requests an _update()_ from the Game, subsequently\nit will draw all renderers onto the screen. Consult the [zCanvas wiki](https://github.com/igorski/zCanvas/wiki) to\nlearn about the API.\n\nNote zCanvas is _always_ on-screen, the different screens (e.g. Title, High Scores, etc.) are overlaid on top (see\n_ScreenController.js_).\n\n## TweenMax in WKS\n\nTweenMax is a powerful animation engine by Greensock. Within WKS it is used to perform easing functions on\nActors which in turn are visualised as animations. Additionally, TweenMax is also a convenient timing engine, instead\nof relying on _setTimeout()_ (which fires when the browser tab is suspended and can drift), we use _TweenMax.delayedCall()_\nwhich is rock solid and can pause when the applications tab suspends.\n\n## Performance\n\n### Object pooling\n\nA vertical scrolling shoot 'em up is pure mayhem with a lot of Objects being in use simultaneously, as well\na lot of generation / removal of Actors.\n\nFor this purpose, this application uses pooling. When a resource is no longer needed (for instance: bullet\nis out of screen bounds), it is not disposed, but returned to the pool. The next time a new instance of\nthat type (for instance: newly fired bullet) is needed, it is retrieved from the pool and updated to have\nthe appropriate properties (e.g. new position, direction, etc.). This pool is maintained by _Game.js_.\n\nApart from game Actors pools, there is also a pool for decorative effects (e.g. explosions which are\ntriggered by Actors, but not actually an Actor by themselves). These are managed by _RenderController.js_.\n\n### Minimizing allocations\n\nIn a game a lot of functions are executed upon each iteration of both the A.I. and render loop. Its good\nto know how the V8 engine deals with garbage collection on used resources. Any allocated variable other\nthan a primitive becomes eligible for garbage collection, meaning it can impact performance when at a sudden\ntime outside of your control, all unused memory is freed while potentially stalling your application.\n\nCreate reusable variables outside of your function scopes to prevent these from being deallocated. Instead\nof creating a lot of lamba (arrow) functions, create a non instance function that receives a reference to\nthe instance object it needs to operate on. Use the language loops (_for_, _while_, _for of_) instead of\nmore expensive Array methods.\n\n_Don't go optimizing for the sake of optimizing_ though. Identify the critical areas in your application\nbut also be reasonable with regards to optimizing at the expense of code clarity and maintainability.\n\n## Project requirements\n\nThe only requirement on your system is to have Node.js installed. With Node installed, you can resolve all\ndependencies via command line using:\n\n`npm install`\n\nYou can start the dev mode through the following NPM task:\n\n`npm run dev`\n\nThis mode will launch a local server allowing you to debug the application from your browser through the\nlocal URL _http://localhost:5173_. When you make changes / additions to the source files, a watcher will\nregister the changes, rebuild the application and refresh the browser so you can see the effect of your\nchanges directly.\n\nYou can create a production ready package by running:\n\n`npm run build`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorski%2Fweltkriegsimulator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figorski%2Fweltkriegsimulator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figorski%2Fweltkriegsimulator/lists"}