A terminal mini-game in which you have to shoot down a horde of invaders with your starship.
In this game, you must control a starship to shoot down a horde of invaders that keep advancing.
- The starship can only move left and right on the bottom of the screen
- The starship can fire three shots at the same time, it cannot fire while it is moving
- The invaders will descend by a row every time they have moved horizontally across the screen and touched one of the edges
- Every time the invaders descend by a row, they will move faster
- If the invaders reach the bottom of the screen, you lose
- If you can kill all invaders before they reach your starship, you win
- There are four levels of difficulty to choose from. The author does not guarantee that the 'extreme' level can be won
- Greeting page with ASCII art and rules
- 4 levels of difficulty, with corresponding numbers of invaders and their initial speed
-
Keyboard controls
3.1 Left/ right to control the starship
3.2 Space to shoot
3.3 P to pause, any key to resume, Q to quit
-
Leaderboard to record who can eliminate the invaders quickest. To use the leaderboard, leaderboard.txt must be placed in the working directory. The program will create a new one if leaderboard.txt is not present
- Generation of random game sets or events: the initial positions of each invader are randomly generated within an area
- Data structures for storing game status: the program makes use of various enums, structs and classes to store the states of objects like invaders and player as well as global game statuses like level of difficulty, pause, continue, win and lose. The code then dynamically responds to changes in these statuses
- Dynamic memory management: the program makes heavy use of STL containers like vectors to store lists of items, including a list of shots for the player and a list of invaders for the army
- File input/output: used to write to the leaderboard
- Program codes in multiple files: classes and related enums are separated from main.cpp in their respective source and header files. The additional lib.h and lib.cpp declares and defines values, enums and functions used throughout the game
- A Frame class is used for all drawable classes to perform client-side drawing on. The player, shot and invader objects get passed a reference to a frame, which they then draw themselves on. The frame is then rendered on screen as a whole, instead of each object manipulating the screen directly
- The ncurses library is used for rendering, screen manipulation and input. This presents multiple advantages: there is no flicker thanks to the buffer-flushing mechanism (the screen is not updated until refresh() is called), the screen can be manipulated with a coordinate system, and non-blocking input can be achieved by setting a timeout on get-character operations. Besides, the cursor can be hidden and shown wherever appropriate
- Timers are achieved by comparing UNIX timestamps. This bypasses the trouble of compensating for putting the thread to sleep
- A secret test mode for developmental purposes
This program uses <bits/stdc++.h> for convenience. Users must use g++ for compilation.
This program uses <ncurses.h>. The program is linked to ncurses at compilation. The package libncurses6 (Debian and derivatives) or ncurses-lib must be installed. It is recommended to run the latest release of Ubuntu or Fedora in Windows Subsystem for Linux or a Podman/ Docker container. The package is installed by default on both operating systems.
You can use the pre-built binaries in GitHub Actions -> most recent workflow run -> 'invaders' artifact. You can also compile with the following instructions:
git clone https://github.com/kdwk/Invaders_CPP.git
cd Invaders_CPP
make clean
make invaders
./invaders
to execute the binary