{"id":16568548,"url":"https://github.com/franciscoengenheiro/space-invaders-app","last_synced_at":"2025-09-17T23:08:03.328Z","repository":{"id":220570652,"uuid":"751992301","full_name":"franciscoengenheiro/space-invaders-app","owner":"franciscoengenheiro","description":"A desktop application to play the classic space invaders arcade game with gameplay modifiers and difficulties","archived":false,"fork":false,"pushed_at":"2024-02-04T21:04:00.000Z","size":39918,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-05T11:49:17.007Z","etag":null,"topics":["canvas-game","college-project","desktop-app","functional-programming","kotlin","space-invaders"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/franciscoengenheiro.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":"2024-02-02T19:21:25.000Z","updated_at":"2024-07-02T00:18:47.000Z","dependencies_parsed_at":"2024-02-04T22:34:21.431Z","dependency_job_id":null,"html_url":"https://github.com/franciscoengenheiro/space-invaders-app","commit_stats":null,"previous_names":["franciscoengenheiro/space-invaders-app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/franciscoengenheiro/space-invaders-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoengenheiro%2Fspace-invaders-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoengenheiro%2Fspace-invaders-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoengenheiro%2Fspace-invaders-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoengenheiro%2Fspace-invaders-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/franciscoengenheiro","download_url":"https://codeload.github.com/franciscoengenheiro/space-invaders-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoengenheiro%2Fspace-invaders-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275680444,"owners_count":25508570,"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","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["canvas-game","college-project","desktop-app","functional-programming","kotlin","space-invaders"],"created_at":"2024-10-11T21:10:53.861Z","updated_at":"2025-09-17T23:08:03.309Z","avatar_url":"https://github.com/franciscoengenheiro.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Space Invaders\n\n| ![Space Invaders](/src/main/resources/invaders.png) |\n|:---------------------------------------------------:|\n|                  *Space Invaders*                   |\n\n\u003e The purpose of this project was to develop a game in Kotlin using\n\u003e the [CanvasLib](https://github.com/palex65/CanvasLib) library, which supports canvas-based graphics programming.\n\n\u003e The project was developed in the context of the *Programming* course of\n\u003e the [CSE](https://www.isel.pt/en/curso/bsc-degree/computer-science-and-computer-engineering) undergraduate degree\n\u003e of [ISEL](https://www.isel.pt/en), which took place in the first semester of the 2021/2022 academic year.\n\n\u003e [!NOTE]\n\u003e The code contains several non-game related issues mentioned in the [critical analysis](#critical-analysis) and should\n\u003e not be used as a reference. \n\u003e It was\n\u003e solely published with the intent of documenting my progress as a software developer student, highlighting my mistakes\n\u003e during its development.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Download](#download)\n- [Requirements](#requirements)\n- [Features](#features)\n- [How to Play](#how-to-play)\n- [Application Design](#application-design)\n    - [Points](#points)\n    - [Difficulties](#difficulties)\n    - [Animations](#animations)\n    - [Hitboxes](#hitboxes)\n    - [Spaceship](#spaceship)\n    - [Aliens](#aliens)\n    - [Bunkers](#bunkers)\n    - [Sounds](#sounds)\n- [Critical Analysis](#critical-analysis)\n\n## Download\n\nDownload the JAR file [here](https://mega.nz/file/ETY00Rjb#xKRBa4X7eSalATP-KGgzViVEgEKPMHrmXPU12Yt2MzU)\n\n## Requirements\n\n- JRE 1.4.0 or above (for running the application);\n- JDK 17 or above (for development purposes).\n\n## Features\n\nBesides what is present in the original game, this version includes the following features:\n\n- [x] Four difficulty levels: `Rogue`, `Classic`, `Master`, and `InHuman`. Each difficulty has its own\n  unique [settings](#difficulties) such as spaceship lives, projectiles, alien speed, and more;\n- [x] Custom points awarded for destroying different alien types, points are deducted when a life is lost;\n- [x] Unique sprite animations;\n- [x] Various sounds for spaceship projectiles, alien deaths, movement, and more.\n\n## Introduction\n\n[Space Invaders](https://en.wikipedia.org/wiki/Space_Invaders)\nis a legendary arcade game created by Tomohiro Nishikado in 1978. Regarded as one of the most influential and iconic\nvideo games of all time, it revolutionized the gaming industry and paved the way for the future of\ninteractive entertainment.\n\nIn this game, players control a spaceship, at the bottom of the screen, tasked with defending Earth from waves of\ndescending alien invaders. Armed with a laser cannon, players must skillfully shoot down the relentless extraterrestrial\nenemies while dodging their retaliatory fire.\nPlayers could also take cover behind destructible bunkers for protection from enemy fire.\n\nThe objective is to score as many points as possible by shooting down waves of invading aliens while avoiding\ntheir\nprojectiles.\nThe game is progressively increased in difficulty as the alien formations descended closer to the player's\nspaceship.\nThe goal is to survive for as long as possible and achieve the highest score.\n\n## How to Play\n\nIn the main menu, the player can choose between four different game difficulties, which are\ndifferentiated by the speed of the aliens, number of lives and the speed of their projectiles,\nas explained in later detail over in [this](#difficulties) section.\n\n| ![Space Invaders](/src/main/resources/menu.png) |\n|:-----------------------------------------------:|\n|             *Difficulty Selection*              |\n\nTo move the spaceship, the player must move the mouse cursor horizontally within the game window. The spaceship can only\nmove horizontally and is always at the bottom of the screen.\n\nFiring the cannon from this spaceship can be done with the **mouse right-click** or the **spacebar**.\nThe player is only allowed to fire if the previous projectile has already disappeared from the screen.\nAlthough, it can depend on the difficulty chosen, as some enable the player to fire multiple projectiles at once.\n\nThe alien and the spaceship projectiles have a **destructive effect** on the **bunkers**,\nwhich are placed at the bottom of the screen.\nSo, the player must be careful not to destroy the bunkers, as they provide protection from enemy fire.\n\nA spaceship projectile can destroy an enemy projectile, which can be useful in some situations.\n\nThe player is **awarded points** for each alien destroyed, depending on its type.\n\nThe **current score**, **difficulty** and **current number of lives** are displayed at the bottom of the screen.\n\nThe game gets **progressively harder** depending on the number of aliens still alive,\nsince the fewer aliens there are, the faster they move towards the player's spaceship.\n\nWhenever a life is lost and the player still has lives left:\n\n- all projectiles disappear from the screen in order to give the player a chance to recover and reposition properly;\n- if a UFO (**red** bonus alien) is present on the screen, it will also disappear.\n- the points lost on a life loss are incremented in order to further penalize the player for allowing\n  the spaceship to take damage.\n\nIn the course of the game, if the player does not eliminate the aliens from the screen,\nor if it loses the lives it has, depending on the difficulty chosen,\nthe game ends.\nIn such an event, the player is presented with the results' screen, which includes:\n\n- the **final score**;\n- the **lives lost**;\n- the **time elapsed**;\n- the **difficulty chosen**.\n\nThe mentioned screen can be seen in the following image:\n\n| ![Game Over Screen](/src/main/resources/game-over-screen.png) |\n|:-------------------------------------------------------------:|\n|                      *Game Over Screen*                       |\n\n## Application Design\n\n### Points\n\nThere are **55** aliens initially in the central block:\n\n- 2 lines at the top with 11 aliens each of the type **SQUID**\n  (in *yellow*);\n- 2 lines in the middle with 11 aliens each of the type **CRAB**\n  (in *light blue*);\n- 1 line at the bottom with 11 aliens of the type **OCTOPUS** (in *light green*).\n\nThere is also a **UFO** (in *red*) type, which appears randomly at the top of the screen throughout the game.\n\nEach type of alien has a different score value, as shown in the following table:\n\n| Alien Type | Points |\n|:----------:|:------:|\n|    UFO     |  100   |\n|    CRAB    |   20   |\n|  OCTOPUS   |   10   |\n|   SQUID    |   30   |\n\nWhen the player loses a life, it also loses some of the accumulated points.\nThe number of the points lost is dependent on the number of lives the player has left.\nIf the player has 3 lives:\n\n- **1st life lost** - loses 100 points;\n- **2nd life lost** - loses 150 points;\n- **3rd life lost** - loses 0 points, since it is the last life.\n\nEach time the spaceship projectile passes the top of the screen, the player is awarded **1 point**. If the player loses\nthe game with negative points, the score is set to 0.\n\n### Difficulties\n\nThere are four **different game difficulties** available, which are:\n\n- **Rogue**;\n- **Classic**;\n- **Master**;\n- **InHuman**.\n\nThe differences between them are the following:\n\n|          Characteristic           | Rogue  | Classic | Master | InHuman  |\n|:---------------------------------:|:------:|:-------:|:------:|:--------:|\n|        **Spaceship Lives**        |   3    |    3    |   2    |    1     |\n|     **Spaceship Projectiles**     | Single | Single  | Single | Multiple |\n| **Alien's Shooting Speed Range**  |  1-4   |   3-6   |  5-8   |   7-10   |\n|   **Alien's Horizontal Speed**    |   4    |    4    |   7    |    7     |\n| **Probability of Alien fire (%)** |   50   |   60    |   75   |    90    |\n|       **Bunkers Presence**        |  Yes   |   Yes   |   No   |    No    |\n|      **Infinite Game Cycle**      |   No   |   Yes   |  Yes   |   Yes    |\n\n### Animations\n\nTo enhance the game's visual appeal and create a more dynamic experience, animations were implemented. These animations\nutilize a [sprite sheet](https://gamedevelopment.tutsplus.com/an-introduction-to-spritesheet-animation--gamedev-13099t),\nwhich is a composite image containing multiple frames. By displaying the frames sequentially\nwith a specific delay, the illusion of movement is created.\n\nEach frame in the sprite sheet represents an animation step, and it advances as the animation updates. Multiple\nanimation steps can be defined for a single image, allowing for different animations to be displayed using the same\nimage, as is the case for the aliens.\n\nWhen the desired animations for an image are completed, the animation step is **resetted to 0**. For instance, if the\nsprite sheet has two columns representing different animations for a **SQUID type**, with the first animation step being\n0 and the second being 1, the third animation step will go back to 0. This cycling behavior is achieved by using the\n**modulus operator**, which wraps the animation step based on the number of columns in the sprite sheet.\n\nThe following image shows the sprite\nsheet used for the aliens' animation with the respective dimensions of each frame.\n\n|      ![Aliens Sprite Sheet](/src/main/resources/invaders-sprite.png)      |\n|:-------------------------------------------------------------------------:|\n|                           *Aliens Sprite Sheet*                           |\n\n### Hitboxes\n\nIn order to **detect collisions** between the different entities of the game, hitboxes were created.\nA **hitbox** is a defined **area that surrounds an entity**, which is used to determine if it has collided with another\nentity.\n\n| ![Game Hitboxes](/src/main/resources/hitboxes.png) |\n|:--------------------------------------------------:|\n|                  *Game Hitboxes*                   |\n\nNote that the bunker hitboxes are not visile in the previous image because of their rectangular shape\nthat perfectly matches the several components that make up the bunker, as described in [this](#bunkers) section.\n\n### Spaceship\n\nThe spaceship's hitbox **is composed of 4 rectangles**, which are used to detect collisions with the aliens'\nprojectiles.\n\nBelow, on the left, is the image of the spaceship used in the game, and on the right, the hitbox created for it.\n\n| ![Spaceship Hitbox](/src/main/resources/spaceship-hitbox.png) | \n|:-------------------------------------------------------------:|\n|                      *Spaceship Hitbox*                       |\n\nTo create the rectangles, it was necessary to know the x and y coordinates of the upper left corner of each one,\nas well as the width and length.\nThe coordinates of the ship are represented in the previous image by the intersection of two straight lines that were\nused\nto find them.\n\n| ![Spaceship Offsets](/src/main/resources/spaceship-offsets.png) |\n|:---------------------------------------------------------------:|\n|                       *Spaceship Offsets*                       |\n\n### Aliens\n\nWhen drawing the aliens in the game via the sprite sheet,\nit was necessary to shorten the image by half (length and width),\nso the offsets of the alien's hitboxes would directly depend on the type and size of the cropped image.\n\nSince each alien represents an object of type Alien,\nit is possible to access the coordinates of the upper left corner of each one, in order to add the necessary offset.\nThis way,\neach alien type will have an hitbox that is circumscribed to its image.\nAs such, during the course of the game, it is easier to hit the aliens that are closer to the player because they have a\nlarger hitbox than the ones that are further away.\n\nThe UFO represents a specific case,\nsince it does not move at the same pace as the central alien block,\nand therefore has a larger hitbox to compensate for the speed at which it moves.\n\n```kotlin\ndata class Alien(val position: Position, val type: AlienType, val isHit: Boolean = false) \n```\n\n### Bunkers\n\nEach bunker is a set of rectangles with 4 rows and 11 columns.\nEach rectangle was drawn with the same width as the shots (11 pixels) and twice as long as the shots (8 pixels).\nWith this information,\nthe ideal distances from the first bunker (leftmost) to the left edge of the game were calculated and found to be 45 pixels,\nso the last bunker (rightmost) would be the same length from the right edge of the game.\nIn order for there to be 4 properly spaced bunkers, the size of each and the distance between them were calculated using the following equation:\n\n```math\n(700 - (88 x 4) - (45 x 2)) / 3 = x \u003c=\u003e x = 86\n```\n\nWhere:\n- 700 corresponds to the length of the game window; \n- 88 corresponds to 11 rectangles with a length of 8;\n- 4 is the total number of bunkers;\n- 3 corresponds to the spaces to be calculated.\n\nThe following imagem shows the bunker's constitution, which was then used to create the hitboxes.\n\n| ![Bunkers Hitboxes](/src/main/resources/bunker-constitution.png) |\n|:----------------------------------------------------------------:|\n|                        *Bunkers Hitboxes*                        |\n    \n### Sounds\n\nThe [CanvasLib](https://github.com/palex65/CanvasLib) library provides functions for playing and loading sounds. These\nsounds are used to enhance the\nplayer's perception of the game state, making it more immersive and enjoyable.\n\nThe sounds used in this game include:\n\n- **Difficulty selection** - played when the player selects a difficulty;\n- **Spaceship projectile** - played when the spaceship fires a projectile;\n- **Alien death** - played when an alien is destroyed;\n- **Alien block movement** - played when the alien block moves across the screen;\n- **UFO movement** - played when the UFO moves across the screen;\n- **Spaceship damage** - played when the spaceship is hit by an alien projectile;\n- **Game Win** - played when the player wins the game;\n- **Game Over** - played when the player loses the game.\n\n## Critical Analysis\n\nUpon a light review of the project, I have identified several noteworthy flaws that severely impact its maintainability\nand scalability. The most relevant ones are:\n\n- The game is **not optimized** as it **prioritizes immutability over performance**, resulting in the creation and\n  destruction\n  of multiple copies of the same object every frame.\n- The game **lacks scalability** in terms of window size as it is hardcoded to a specific resolution.\n- There are **numerous occurrences of magic numbers** and **hardcoded values** throughout the code, making it\n  challenging to\n  modify the game's behavior and appearance.\n- The project **lacks organization and a clear structure**. Most files, if not all, are **unnecessarily large and\n  complex**, and\n  they assume responsibilities that should be clearly defined and separated.\n- The code contains **excessive comments**, which hinders readability.\n  The comments are also **inconsistent** and written in a language that is not universally understood.\n\n\u003e [!Important]\n\u003e It's worth mentioning that the project was developed in a short period of time. It was not intended to be\nmaintained or scaled, as the main goal was to learn and practice the Kotlin programming language as a way to introduce\nprogramming basic concepts to students.\n\u003e \n\u003e Nevertheless, such flaws should be addressed in a future version of the game if one is ever developed.\n\n--- \n\nInstituto Superior de Engenharia de Lisboa\u003cbr\u003e\nBSc in Computer Science and Engineering\u003cbr\u003e\nProgramming\u003cbr\u003e\nWinter Semester of 2021/2022","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranciscoengenheiro%2Fspace-invaders-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffranciscoengenheiro%2Fspace-invaders-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranciscoengenheiro%2Fspace-invaders-app/lists"}