A fun 2D terminal game built with C++.
The game is basically all about ducking the incoming blocks or obstacles. The player (indicated by '*') is spawned at the bottom of the playground or board. Obstacles would generate on top of the board and would start to come down to hit the player. Each obstacle would have some gaps. Player would have to take advantage of the gaps by pressing the Arrow Keys
and duck the obstacles.
Each obstacle player ducks score increases by 1. With increasing score game would grow more difficult with faster obstacle and smaller gaps. I dare anyone making a score 40. My personal best is 32! :)
This project has dependency on ncurses library for visual representation and cmake for compiling and running the project.
Game board or boundary is modifiable from the config.txt
file. Below are the things to remember while updating the config file.
- width/length ratio = 2 : 1. If width = 70, length = 35.
- 100 ≥ width ≥ 30
- Navigate to project directory and run
mkdir build && cd build
on terminal. - Run
cmake .. && make
. This will generate an executable insidebuild
folder namedPassTheBlocks
- Run
./PassTheBlocks
- A display will appear as below
- Press 'S' (not case-sensitive) to get in action or any key to terminate the program.
Once there's a collision everything halts. Please press any of the Arrow Keys
to get to the next screen.
- Below is the upper level breakdown of classes.
-
class Reader
parse_file()
- A virtual method for file reading
class File_Reader
parse_file()
- Implementation of the virtual method. Reads a file at a given url and stores the dimensions in a
std::vector
- Implementation of the virtual method. Reads a file at a given url and stores the dimensions in a
get_file_data()
- Returns the
std::vector
holding the dimension
- Returns the
class Config_Parser
parse_and_store_data()
- Uses
File_Reader
to provide file url and get the dimensions and save them in a publicunordered map
- Uses
class Board_Generator
draw_board()
- Draws the board initially in terminal
update_cell(int, int, int, int, int)
- Updates an individual cell in the terminal, specially changes player position
update_cell(int, vector<int>&, int)
- Updates range of cells in the terminal, specially changes obstacle position
class Game
load_game()
: Initializes inner matrix of the board without placing player or obstaclelaunch_game()
:- Draws the board in the terminal initially.
- Initiates a thread for obstacle generation and moving them
- Initiates a player/vehicle thread for user interaction
- This is the main cockpit for the overall game
move_my_vehicle()
- Responsible for launching a player thread
- Spawns the player and updates board
- Detects user key press and take action accordingly
- Takes a
std::unique_lock
and provides obstacle thread a go-ahead by notifying
generate_obstacle()
- Responsible for launching an obstacle thread
- Once player/vehicle is created this thread starts its job
- Randomly generates gap start index and modify matrix and board in terminal
- Moves the obstacle downward and checks for collision
- Keeps track of player score
check_collision_from_obstacle()
- Checks if collision occured once an obstacle has moved
check_collision_from_vehicle()
- Checks if collision occured once player has moved
get_obstacle_delay()
- Sets obstacle moving delay based on user score. The less the delay, game gets more difficult
get_obstacle_gap()
- Sets obstacle gap based on user score. The less the gap, game gets more difficult
stop_game()
- Uses a locking mechanism as either player or obstacle thread might want to reach it. Whoever reaches first stops the game.
change_inner_board_value()
- Both the player and obstacle thread use this method to modify inner matrix data. So it was made thread-safe by locking.
get_inner_board_cell()
- For reading inner matrix data
post_game_over()
- Display screen after game is over