From 37cafca435d1c41c2ef4cde0d6ee9f745747bef5 Mon Sep 17 00:00:00 2001 From: Saurabh Singh Date: Thu, 27 May 2021 07:46:23 +0530 Subject: [PATCH] added main code --- .gitignore | 2 + Makefile | 24 +++++ README.md | 45 ++++++++++ src/TermPong.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++++ termpong.png | Bin 0 -> 4341 bytes 5 files changed, 297 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/TermPong.cpp create mode 100644 termpong.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d86ba9f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +obj/ +bin/ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6be6c17 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +CC = g++ + +src_dir = src +obj_dir = obj +bin_dir = bin + +$(bin_dir)/TermPong: directories $(obj_dir)/coordinate.o $(obj_dir)/TermPong.o + $(CC) -Wall $(obj_dir)/coordinate.o $(obj_dir)/TermPong.o -o $(bin_dir)/TermPong -lncurses + +directories: + mkdir obj + mkdir bin + +$(obj_dir)/coordinate.o : $(src_dir)/coordinate.cpp $(src_dir)/coordinate.h + $(CC) -Wall -c $(src_dir)/coordinate.cpp -o $(obj_dir)/coordinate.o + +$(obj_dir)/TermPong.o : $(src_dir)/TermPong.cpp + $(CC) -Wall -c $(src_dir)/TermPong.cpp -o $(obj_dir)/TermPong.o + + +.PHONY: clean +clean: + rm -rf $(bin_dir)/* + rm -rf $(obj_dir)/* \ No newline at end of file diff --git a/README.md b/README.md index 8852a09..799d19c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,47 @@ # TermPong Pong game on terminal! + +![TermPong](termpong.png) + + + +## Instuctions + +- use `a`, `d` keys to move bat left and right respectively. +- use `p` key to pause the game. +- use `q` or `ctrl+c` to exit the game. + + + +## Getting Started + +**Install the prerequisites** + +```bash +$ sudo apt install libncurses5-dev libncusesw5-dev build-essential +``` + +**Clone the repo** + +```bash +$ git clone https://github.com/saurabhsingh99100/TermPong.git +``` + +**Run make** + +```bash +$ cd TermPong && make +``` + +**Run the executable** + +```bash +$ ./bin/TermPong +``` + + + +***That' s it, Have fun!*** + + + diff --git a/src/TermPong.cpp b/src/TermPong.cpp new file mode 100644 index 0000000..aab2cb7 --- /dev/null +++ b/src/TermPong.cpp @@ -0,0 +1,226 @@ +/** + * TermPong v1 + * + * File: coordinate.cpp + * + * Description: + * A clone of the pong game using ncuses libay in C++ + * + * Author: + * Saurabh Singh (saurabh.s99100@gmail.com) + * + * MIT License + * + * Copyright (c) 2021 Saurabh Singh + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include +#include +#include +#include +#include + +#include "coordinate.h" + +// Constant definitions +const unsigned int mSec = 1000; // 1 msec = 1000us +const unsigned int Sec = 1000000; // 1 sec = 1000000us + +const char ballChar = '@'; // character used for displaying ball +const char batChar = '='; // character used for displaying bat +const int batLen = 8; // length of bat (ensure even number) +const int scoreIncrementAmount = 5; // value to increment score with + +int main() +{ + coordinate winLim(80, 26); + coordinate scoreLoc(30, 0); + + const int frameLim = 10; // move ball after every "frameLim" frames + + // Runtime variables + unsigned int score = 0; + int xVelocity = 1; + int yVelocity = 1; + + int frameCount = 0; + + bool gameOver = false; + bool paused = false; + + coordinate ballLoc(winLim.getX()/2, winLim.getY()/2); + int batLoc = winLim.getX()/2; + + // Game Setup + initscr(); // initialize ncurses mode + cbreak(); // disable getch() buffering + noecho(); // disable getch() echo + nodelay(stdscr, TRUE); // disable getch() waiting for keypress + curs_set(0); // Hide cursor + + // Print splashSceen + wmove(stdscr, 10-2, 37-36); wprintw(stdscr, " ////// ////// ////// // // ///// /// // // ///// "); + wmove(stdscr, 10-1, 37-36); wprintw(stdscr, " // // // // /// /// // // // // /// // // "); + wmove(stdscr, 10+0, 37-36); wprintw(stdscr, " // //// ///// // // // ///// // // // // // // //// "); + wmove(stdscr, 10+1, 37-36); wprintw(stdscr, " // // // // // // // // // // /// // // "); + wmove(stdscr, 10+2, 37-36); wprintw(stdscr, " // ////// // // // // // /// // // ///// "); + + wmove(stdscr, 10+5, 37-36); wprintw(stdscr, " By : Saurabh Singh (saurabh.s99100@gmail.com) "); + wmove(stdscr, 10+6, 37-36); wprintw(stdscr, " Instructions: Move the bat left and right with keys 'a' and 'd'"); + wmove(stdscr, 10+7, 37-36); wprintw(stdscr, " Press 'p' to pause & 'q' to quit"); + + wrefresh(stdscr); + usleep(1 * Sec); + + wmove(stdscr, 10+9, 37-36); wprintw(stdscr, " === READY ==="); + wrefresh(stdscr); + usleep(1 * Sec); + wmove(stdscr, 10+9, 37-36); wprintw(stdscr, " === SET ==="); + wrefresh(stdscr); + usleep(1 * Sec); + wmove(stdscr, 10+9, 37-36); wprintw(stdscr, " === GO! ==="); + wrefresh(stdscr); + usleep(1 * Sec); + wclear(stdscr); + + // Print header + wmove(stdscr, 0, 1); wprintw(stdscr, "TermPong v1"); + wmove(stdscr, 0, 22); wprintw(stdscr, "Score : "); + + WINDOW * gameWin = newwin(winLim.getY(), winLim.getX(), 1, 1); + wrefresh(stdscr); + wrefresh(gameWin); + + while(!gameOver) + { + // read input + char inchar = getch(); + if(inchar == 'q') + break; + if(inchar == 'p') + paused = !paused; + + if(!paused) + { + if(frameCount == frameLim) + { + // calculate new ball location + ballLoc.setX(ballLoc.getX()+xVelocity); + ballLoc.setY(ballLoc.getY()+yVelocity); + + // Bounce ball + if(ballLoc.getX() == 1) // left boundry + { + xVelocity = -xVelocity; + } + else if(ballLoc.getX() == winLim.getX()-2) // right boundry + { + xVelocity = -xVelocity; + } + else if(ballLoc.getY() == 1) // top boundry + { + yVelocity = -yVelocity; + } + else if(ballLoc.getY() == winLim.getY()-3) + { + if(ballLoc.getX() >= batLoc && ballLoc.getX() <= batLoc + batLen) + { + yVelocity = -yVelocity; // Bounce + score += scoreIncrementAmount; + } + } + else if(ballLoc.getY() == winLim.getY()-2) // bottom boundry + { + gameOver = true; + } + frameCount = 0; + } + else + { + frameCount++; + } + + // calculate new bat location + if(inchar == 'a') + { + if(batLoc != 1) + batLoc--; + } + else if(inchar == 'd') + { + if(batLoc + batLen - 1 != winLim.getX()-2) + batLoc++; + } + + // clear gameWin + wclear(gameWin); + box(gameWin, 0, 0); + + // print ball + wmove(gameWin, ballLoc.getY(), ballLoc.getX()); + wprintw(gameWin, "%c", ballChar); + + wmove(gameWin, winLim.getY()-2, batLoc); + + // print Bat + for(int i = 0; i < batLen; i++) + { + wprintw(gameWin, "%c", batChar); + } + + // print score + wmove(stdscr, scoreLoc.getY(), scoreLoc.getX()); wprintw(stdscr, "%d", score); + + + // refresh screen + wrefresh(stdscr); + wrefresh(gameWin); + } + + if(paused) + { + wmove(stdscr, scoreLoc.getY(), scoreLoc.getX()+10); wprintw(stdscr, "PAUSED"); + } + else + { + wmove(stdscr, scoreLoc.getY(), scoreLoc.getX()+10); wprintw(stdscr, " "); + } + + // loop delay + //usleep(400 * mSec); + + usleep(10 * mSec); + } + + if(gameOver) + { + WINDOW * gameOverScreen = newwin(4, 30, winLim.getY()/2 - 2, winLim.getX()/2 - 15); + box(gameOverScreen, 0, 0); + + wmove(gameOverScreen, 1, 10); wprintw(gameOverScreen, "GAME OVER"); + wmove(gameOverScreen, 2, 10); wprintw(gameOverScreen, "Score: "); + wmove(gameOverScreen, 2, 17); wprintw(gameOverScreen, "%d", score); + wrefresh(gameOverScreen); + usleep(3*Sec); + } + endwin(); +} diff --git a/termpong.png b/termpong.png new file mode 100644 index 0000000000000000000000000000000000000000..17f237696ac603b5096e263f852787a990b4afbe GIT binary patch literal 4341 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 L@pQ?_OSk?7ldN~5 literal 0 HcmV?d00001