{"id":28146851,"url":"https://github.com/susam/invaders","last_synced_at":"2025-05-14T23:15:52.183Z","repository":{"id":43845645,"uuid":"458744275","full_name":"susam/invaders","owner":"susam","description":"A 1980s-arcade-style game written using HTML5, Canvas, and Web Audio","archived":false,"fork":false,"pushed_at":"2023-12-20T00:03:01.000Z","size":112,"stargazers_count":166,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-08-10T09:28:31.421Z","etag":null,"topics":["audiocontext","canvas-game","game","invaders","javascript"],"latest_commit_sha":null,"homepage":"https://susam.net/invaders.html","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/susam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-13T07:48:32.000Z","updated_at":"2024-05-29T22:22:39.000Z","dependencies_parsed_at":"2022-09-01T18:44:38.194Z","dependency_job_id":null,"html_url":"https://github.com/susam/invaders","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Finvaders","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Finvaders/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Finvaders/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Finvaders/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susam","download_url":"https://codeload.github.com/susam/invaders/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243312,"owners_count":22038048,"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":["audiocontext","canvas-game","game","invaders","javascript"],"created_at":"2025-05-14T23:14:45.070Z","updated_at":"2025-05-14T23:15:52.161Z","avatar_url":"https://github.com/susam.png","language":"HTML","readme":"Andromeda Invaders\n==================\n\n[Andromeda Invaders][PLAY1] is a 1980s-arcade-style game that runs in\na modern web browser. This game is inspired by Space Invaders, the\n1978 arcade game developed by Tomohiro Nishikado. However, the game\ncharacters, gameplay, and some technical aspects of this game are very\ndifferent from those of Space Invaders.\n\n[![A player emitting laser pulse and ten spaceships hovering][IMG]][PLAY1]\n\n**[PLAY NOW!][PLAY1]**\n\n[IMG]: https://susam.github.io/blob/img/invaders/invaders-v0.7.1.png\n\n\nContents\n--------\n\n* [Play](#play)\n* [Keys](#keys)\n* [Technical Details](#technical-details)\n* [Gameplay](#gameplay)\n* [Autoplay](#autoplay)\n* [Why?](#why)\n* [License](#license)\n* [Support](#support)\n* [More](#more)\n\n\nPlay\n----\n\nThe current stable version of the game is available at the following\nlinks:\n\n* [susam.net/invaders.html][PLAY1]\n* [susam.github.io/invaders.html][PLAY2]\n\nA testing version of the game with recent bug fixes is available here:\n\n* [susam.github.io/invaders/invaders.html][PLAY3]\n\n[PLAY1]: https://susam.net/invaders.html\n[PLAY2]: https://susam.github.io/invaders.html\n[PLAY3]: https://susam.github.io/invaders/invaders.html\n\nThere is rudimentary support for playing this game on small screens\nand touchscreens using the buttons provided below the game canvas.\nHowever, this game is best enjoyed on a laptop/desktop device with a\nphysical keyboard.\n\nSince it is a single-file game, you can also save this game to your\nsystem by right clicking one of the links mentioned above and\nselecting the option to save/download the HTML file.\n\n\nKeys\n----\n\nWhile playing on a keyboard-enabled device, the following keys are\nsupported:\n\n  - `\u003cleft arrow\u003e` or `a` to move player left\n  - `\u003cright arrow\u003e` or `d` to move player right\n  - `\u003cspace\u003e` or `p` to pause/unpause game\n  - `\u003center\u003e` or `e` to restart game\n  - `m` to mute/unmute audio\n  - `f` to enter/exit to fullscreen mode\n\nThe last key to enter/exit to fullscreen mode may not work on all web\nbrowsers.\n\n\nTechnical Details\n-----------------\n\nAll of the graphics is done by drawing rectangles on an HTML5\n`\u003ccanvas\u003e` element using the Canvas API. In fact, any text appearing\non the canvas is also displayed by drawing squares on the canvas. The\nbitmaps used to draw text are embedded as integer arrays in the code.\n\nAll of the audio is done by playing sine waves generated using\n`OscillatorNode` of the Web Audio API. The sine waves used for the\ngame audio correspond to actual musical notes from the C major scale.\nMultiple notes are played together to form chords. The background\nmusic is a chord progression consisting of four chords repeating over\nand over again as long as the game is being played. When the game\ncharacters get hit, the hit sounds are made of a single chord that\nplays for a very short duration.\n\n\nGameplay\n--------\n\n*You are encouraged to play the game without reading this section. I\nbelieve there is a certain joy in figuring out the game on your own\nwithout referring to any hints or existing documentation. For this\nreason, I suggest that you skip this section and [go play](#play) the\ngame first. If you really must understand the gameplay right now, the\nfollowing subsections contain notes about various details of this\ngame.*\n\n\n### Game Characters\n\n*Not so long time ago in a galaxy near, near away ...*\n\nBright orange ships visit the player's planet and begins dropping\nboulders from space to hit the player. The player defends itself by\nhitting the ships and the falling boulders with laser pulses. When a\nboulder is hit successfully, it vanishes instantly. When a ship is hit\nsuccessfully, it loses its health. The health is indicated by the\ncolour of the ship. Bright orange indicates perfect health. When a\nbright orange ship is hit, it turns dark orange. When a dark orange\nship is hit, it turns dark red. A dark red ship is in critical\ncondition. If a dark red ship is hit again, it vanishes.\n\nWhen a boulder hits the player it loses health. The player is initially\nbright green that indicates that it is in perfect health. When a\nperfectly healthy player is hit, it turns dark green. If the player is\nhit again while it is dark green, it turns dull yellow. If the player\nis hit when it is dull yellow, it vanishes and the game ends.\n\nFurther, as each game level progresses, the ships gradually descend.\nThe fewer the number of ships that are still visible, the faster they\ndescend. When the lowermost ship reaches the same level as that of the\nplayer, it moves rapidly in the direction of the player and collides\nwith the player. When a ship collides with the player, the ship\nvanishes but so does the player and the game ends.\n\n\n### Health Levels\n\nEach ship has three grades of health and the player too has three\ngrades of health. After being hit and losing health, the ships and the\nplayer can regain health as the game continues. A ship gains health by\none grade after it drops ten boulders since it was last hit. The\nplayer gains health by one grade after it gains 100 points since it\nwas last hit.\n\nWhen a ship collides with the player, the ship loses all its health\nand vanishes, so does the player, and the game ends immediately.\n\n\n### Game Levels\n\nThe game can be played indefinitely long. There are multiple levels in\nthe game that are numbered 1, 2, 3, and so on. After level 1000, the\nlevel is reset to 1, however, the score remains intact, so one can\nkeep playing levels 1 to 1000 repeatedly in a loop if one has the\npatience and skill to do so.\n\nAt level 1, only three ships visit the player's planet. At level 2,\nsix ships visit the planet. At level 3 and above, ten ships visit the\nplanet.\n\nThe boulders drop at various random speeds. The range of possible speeds\nfor the boulders is decided by the game level. The speed of the ships\ntoo depends on the level. Further, the tempo of the background music\ntoo depends on the level.\n\nThe following table shows the various game parameters for each level.\n\n| Level | Ships | Ship Speed | Boulder Speed | Music Tempo |\n|------:|------:|-----------:|--------------:|------------:|\n|     1 |     3 |          2 |        [1, 4] |           2 |\n|     2 |     6 |          2 |        [2, 4] |           2 |\n|     3 |    10 |          3 |        [2, 4] |           3 |\n|     4 |    10 |          3 |        [2, 5] |           4 |\n|     5 |    10 |          3 |        [3, 5] |           5 |\n|     6 |    10 |          4 |        [3, 5] |           6 |\n|     7 |    10 |          4 |        [3, 6] |           7 |\n|     8 |    10 |          4 |        [4, 6] |           8 |\n|     9 |    10 |          5 |        [4, 6] |           9 |\n|    10 |    10 |          5 |        [4, 7] |          10 |\n|    11 |    10 |          5 |        [5, 7] |          11 |\n|    12 |    10 |          6 |        [5, 7] |          12 |\n|    13 |    10 |          6 |        [5, 8] |          12 |\n|    14 |    10 |          6 |        [6, 8] |          12 |\n|    15 |    10 |          7 |        [6, 8] |          12 |\n|    16 |    10 |          7 |        [6, 9] |          12 |\n|    17 |    10 |          7 |        [7, 9] |          12 |\n|    18 |    10 |          8 |        [7, 9] |          12 |\n|    19 |    10 |          8 |       [7, 10] |          12 |\n|    20 |    10 |          8 |       [8, 10] |          12 |\n|   ... |     \" |          \" |             \" |           \" |\n|  1000 |     \" |          \" |             \" |           \" |\n\nIn the table above, the unit of speed is pixels per frame (PPF), i.e.,\nthe number of pixels an object appears to move from one game frame to\nanother. Here, the term *game frame* refers to a single instance of\nrendering the game state to the HTML5 `\u003ccanvas\u003e`. The game state is\nrendered to the canvas 50 times per second. The speed of the boulders\nis chosen randomly from the closed interval shown in the *Boulder\nSpeed* column. The unit of music tempo is beats per second. Each chord\nis played in a beat.\n\nTo summarize the table above, the game becomes progressively more\ndifficult to play in each level until level 20. The game parameters do\nnot change between levels 20 to 1000. After level 1000, the game\nresets to level 1 but the player's score remains intact. Thus the game\ncan be played indefinitely long in theory. However, in practice you\nmight find that it is quite difficult to reach even level 10 or so.\n\n\n### Points\n\nThe player gets 1 point for hitting a boulder, 10 points for hitting a\nbright orange ship, 20 points for hitting a dark orange ship, and 30\npoints for hitting a dark red ship.\n\n\nAutoplay\n--------\n\nThis game comes with an autoplay feature. After the game loads on the\nweb browser or after the game is restarted, when there is no activity\nfor 5 seconds, the autoplay algorithm starts and begins playing the\ngame on its own.\n\nTo see the autoplay algorithm in action, load or restart the game,\npress \u003ckbd\u003eenter\u003c/kbd\u003e twice, and wait for 5 seconds.\n\nPressing \u003ckbd\u003eenter\u003c/kbd\u003e twice is not strictly necessary for the\nautoplay algorithm to begin. The autoplay algorithm starts\nautomatically 5 seconds after a game is loaded or restarted regardless\nof whether you press \u003ckbd\u003eenter\u003c/kbd\u003e or not. However, if you don't\nperform some kind of user interaction with the web page, such as by\npressing a key or clicking with a mouse or with touch, before the\nautoplay begins, then the web browser may refuse to play the game\naudio. That is why typing some key that does not start a normal game\nor clicking with the mouse or some other user activity is necessary to\nensure that when the autoplay algorithm starts, the game audio plays\nas well. Pressing \u003ckbd\u003eenter\u003c/kbd\u003e twice happens to restart the game\nhappens to be one such convenient user interaction.\n\n\nWhy?\n----\n\nI first came across Space Invaders in the 1990s in the computer\nlaboratory of my lower secondary school. Soon after playing the game a\nfew times, I wanted to develop a similar game of my own. However, the\nlittle GW-BASIC programming I knew and the very limited access to\ncomputers I had then was insufficient to write anything more\nsophisticated than simple text-based input/output programs. I did\nwrite several simple text-based quiz and adventure games back then but\na more sophisticated game with graphics and audio remained elusive. As\nyears went by, I gradually forgot about it, learnt more mainstream\nlanguages like C, Python, Lisp, etc. and got into programming as a\ncareer.\n\nAlthough it is 25 years too late, I decided to spend a weekend to\nfulfill my childhood desire to write my own Invaders-like game. This\nproject fulfills a childhood dream of mine!\n\n\nLicense\n-------\n\nThis is free and open source software. You can use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of it,\nunder the terms of the MIT License. See [LICENSE.md][L] for details.\n\nThis software is provided \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nexpress or implied. See [LICENSE.md][L] for details.\n\n[L]: LICENSE.md\n\n\nSupport\n-------\n\nTo report bugs or ask questions, [create issues][ISSUES].\n\n[ISSUES]: https://github.com/susam/invaders/issues\n\n\nMore\n----\n\nThis project uses bitmap arrays to render text by drawing squares on\ncanvas. The bitmaps of only those characters that are needed in this\ngame are included in the source code. This includes the bitmap of ten\ndigits, a few punctuation characters, and a very limited subset of\nuppercase and lowercase letters.\n\nThe glyphs for these characters are taken from a raster font named\n[Modern DOS 8x16][MDOS] version 20190101.02. This font was developed\nby Jayvee Enaguas and it is available under the terms of [CC0 1.0\nUniversal Public Domain Dedication][CC0]. This font is based on the\n[IBM VGA 8x16][VGA] and [Verite 8x16][VERITE] OEM fonts.\n\nIf you are doing something similar and want the bitmap arrays for a\nlarger set of characters, see another project of mine named [PC\nFace](https://github.com/susam/pcface) which offers bitmap arrays for\nall 256 characters of the CP437 character set.\n\n[MDOS]: https://www.dafont.com/modern-dos.font\n[CC0]: https://creativecommons.org/publicdomain/zero/1.0/\n[VGA]: https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_vga_8x16\n[VERITE]: https://int10h.org/oldschool-pc-fonts/fontlist/font?verite_8x16\n\n\n\u003c!--\nRelease Checklist\n-----------------\n\n- Update version in package.json.\n- Update version in invaders.html (2 places).\n- Update copyright in invaders.html (2 places).\n- Update copyright in LICENSE.md.\n- Disable logging and scaffolding.\n- Update CHANGES.md.\n- Run: npm run lint\n- Run: git status; git add -p\n- Run: VERSION=\u003cVERSION\u003e\n- Run: git commit -em \"Set version to $VERSION\"\n- Run: git tag $VERSION -m \"Andromeda Invaders $VERSION\"\n- Run: git push origin main $VERSION\n- Run: npm login\n- Run: npm publish\n- Create a new release on GitHub.\n--\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Finvaders","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusam%2Finvaders","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Finvaders/lists"}