diff --git a/CMakeLists.txt b/CMakeLists.txt index 351889e..7d0afea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(SOURCES src/input.cpp src/window.cpp src/elements.cpp + src/timer.cpp ) add_executable(pong ${SOURCES}) diff --git a/include/elements.hpp b/include/elements.hpp index bb3d39c..d862e54 100644 --- a/include/elements.hpp +++ b/include/elements.hpp @@ -9,19 +9,28 @@ struct Point { Point(); Point(int row, int col) : m_row(row), m_col(col) {}; void to_string(); - void to_string(int index); void clear(std::array, ROW> &m_board); - // void set_new_point(int row, int col); + void assign(int row, int col); +}; + +struct Ball { + Ball(); + Point m_origin; + int m_vx = 1; + int m_vy = -1; + bool m_goal; + void get_new_pos(); + void check_collision(); + void change_direction(char d); }; struct Paddle { Paddle(int col); + int _size; + int m_score; Point m_nodes[4]; void get_new_pos(int col); -}; - -struct Ball { - + void check_collision(Ball &ball); }; #endif diff --git a/include/globals.hpp b/include/globals.hpp index f606eb7..0e62674 100644 --- a/include/globals.hpp +++ b/include/globals.hpp @@ -2,6 +2,6 @@ #define GLOBALS_HPP constexpr unsigned int ROW = 10; -constexpr unsigned int COL = 20; +constexpr unsigned int COL = 21; #endif diff --git a/include/timer.hpp b/include/timer.hpp new file mode 100644 index 0000000..9bc2b6b --- /dev/null +++ b/include/timer.hpp @@ -0,0 +1,8 @@ +#ifndef TIMER_HPP +#define TIMER_HPP + +struct Timer { + void decrement_time(int &time, bool &running, bool &timer_active); +}; + +#endif diff --git a/include/window.hpp b/include/window.hpp index c871afa..149c6f3 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -6,9 +6,7 @@ #include "elements.hpp" struct Window { - // Window(); - std::array, ROW> m_board; - // void update_display(); - void update_display(Paddle &a, Paddle &b); + std::array, ROW> m_board = {}; + void update_display(Paddle &left, Paddle &right, Ball &ball, int &time); }; #endif diff --git a/src/elements.cpp b/src/elements.cpp index 5daf342..61ba99f 100644 --- a/src/elements.cpp +++ b/src/elements.cpp @@ -10,24 +10,70 @@ void Point::clear(std::array, ROW> &m_board) { m_board[m_row][m_col] = '.'; } +void Point::assign(int row, int col) { + m_row = row; + m_col = col; +} + void Point::to_string() { std::cout << "(" << m_row << ", " << m_col << ")"; } -void Point::to_string(int index) { - std::cout << "Index " << index << ": (" << m_row << ", " << m_col << ")"; -} - Paddle::Paddle(int col) { - for(int i = 0; i < 4; i++) { - m_nodes[i].m_col = col; - m_nodes[i].m_row = i + 3; + _size = 4; + m_score = 0; + for(int i = 0; i < _size; i++) { + m_nodes[i].assign(i + 3, col); } } void Paddle::get_new_pos(int col) { - for(int i = 1; i < 4; i++) { - m_nodes[i].m_row = m_nodes[0].m_row + i; - m_nodes[i].m_col = col; // Should fix the weird bug that happens when spamming keys + for(int i = 1; i < _size; i++) { + m_nodes[i].assign(m_nodes[0].m_row + i, col); + } +} + +void Paddle::check_collision(Ball &ball) { + for(int i = 0; i < _size; i++) { + if(ball.m_origin.m_row == m_nodes[i].m_row && ball.m_origin.m_col == m_nodes[i].m_col) { + ball.change_direction('x'); + } + } +} + +Ball::Ball() { + m_origin.assign(5, 10); + m_vx = 1; + m_vy = -1; + m_goal = false; +} + +void Ball::change_direction(char d) { + if(d == 'y') { + if (m_vy == 1) m_vy = -1; + else m_vy = 1; + } if(d == 'x') { + if (m_vx == 1) m_vx = -1; + else m_vx = 1; + } +} + +void Ball::check_collision() { + if(m_origin.m_row <= 0 || m_origin.m_row >= ROW - 1) { + change_direction('y'); + } if(m_origin.m_col <= 0 || m_origin.m_col >= COL - 1) { + m_goal = true; + } +} + +void Ball::get_new_pos() { + if(m_vx == 1) { + m_origin.m_col++; + } else if(m_vx == -1) { + m_origin.m_col--; + } if(m_vy == 1) { + m_origin.m_row++; + } else if(m_vy == -1) { + m_origin.m_row--; } } diff --git a/src/main.cpp b/src/main.cpp index 1abe108..4b30021 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,22 +1,53 @@ #include #include #include "input.hpp" +#include "timer.hpp" #include "window.hpp" #include "elements.hpp" int main() { bool running = true; Input input; + Timer timer; Window window; Paddle left(1); - Paddle right(18); + Paddle right(19); + Ball ball; + int time = 90; + bool timer_active = true; + std::thread timer_thread(&Timer::decrement_time, &timer, std::ref(time), std::ref(running), std::ref(timer_active)); std::thread input_thread(&Input::get_input, &input, std::ref(running), std::ref(left), std::ref(right)); while (running) { - window.update_display(left, right); + window.update_display(left, right, ball, time); left.get_new_pos(1); - right.get_new_pos(18); + right.get_new_pos(19); + ball.get_new_pos(); + ball.check_collision(); + left.check_collision(ball); + right.check_collision(ball); + if (ball.m_goal && ball.m_origin.m_col < (ROW / 2)) { + ball.m_goal = false; + right.m_score++; + ball.m_origin.assign(5, 10); + } else if(ball.m_goal && ball.m_origin.m_col > (ROW / 2)) { + ball.m_goal = false; + left.m_score++; + ball.m_origin.assign(5, 10); + } + if(!timer_active) { + std::cout << "\033[H" << std::flush; // Clear screen + if(left.m_score > right.m_score) { + std::cout << "Player 1 wins!" << std::endl; + } if(left.m_score < right.m_score) { + std::cout << "Player 2 wins!" << std::endl; + } if(left.m_score == right.m_score) { + std::cout << "It's a tie!" << std::endl; + } + running = false; + } } + timer_thread.join(); input_thread.join(); return 0; } diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 0000000..7c93961 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,14 @@ +#include +#include +#include "timer.hpp" + +void Timer::decrement_time(int &time, bool &running, bool &timer_active) { + while (running) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + time--; + if(time <= 0) { + timer_active = false; + } + } + +} diff --git a/src/window.cpp b/src/window.cpp index 6cd3a2c..e8964f5 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3,33 +3,20 @@ #include #include -// Window::Window() { -// for(std::array &row : m_board) { row.fill('.'); } -// } - -void Window::update_display(Paddle &a, Paddle &b) { -// // Update symbols of positions +void Window::update_display(Paddle &left, Paddle &right, Ball &ball, int &time) { + for(std::array &row : m_board) { row.fill('.'); } for(int i = 0; i < 4; i++) { - m_board[a.m_nodes[i].m_row][a.m_nodes[i].m_col] = '*'; - m_board[b.m_nodes[i].m_row][b.m_nodes[i].m_col] = '*'; + m_board[left.m_nodes[i].m_row][left.m_nodes[i].m_col] = '|'; + m_board[right.m_nodes[i].m_row][right.m_nodes[i].m_col] = '|'; } -// m_board[fruit.m_point.m_row][fruit.m_point.m_col] = 'X'; -// for(int i = 0; i < body.m_body.size(); i++) { -// m_board[body.m_body.at(i).m_tail_pos.m_row][body.m_body.at(i).m_tail_pos.m_col] = '0'; -// } -// + m_board[ball.m_origin.m_row][ball.m_origin.m_col] = '*'; std::cout << "\033[H" << std::flush; // Clear screen - // Draw Screen for(std::array &row : m_board) { for(char &col : row) { std::cout << col << " "; } std::cout << "\r\n"; } - std::this_thread::sleep_for(std::chrono::milliseconds((int) (200))); // 1000 / fps; 200ms = 5fps -// // Clear old spaces - // for(int i = 0; i < body.m_body.size(); i++) { - // body.m_body.at(i).m_tail_pos.clear(m_board); - // } - for(std::array &row : m_board) { row.fill('.'); } + std::cout << "Time left: " << time << ", Score ( " << left.m_score << " : " << right.m_score << " )" << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 1000 / fps; 200ms = 5fps }