feat: Added ball and collision to paddles. Added a score system and timer for game. May be done in one day.

This commit is contained in:
DarthMooMancer
2025-08-30 22:41:39 -04:00
parent fe8e4346a2
commit fbdf7af31e
9 changed files with 138 additions and 44 deletions
+1
View File
@@ -9,6 +9,7 @@ set(SOURCES
src/input.cpp
src/window.cpp
src/elements.cpp
src/timer.cpp
)
add_executable(pong ${SOURCES})
+15 -6
View File
@@ -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<std::array<char, COL>, 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
+1 -1
View File
@@ -2,6 +2,6 @@
#define GLOBALS_HPP
constexpr unsigned int ROW = 10;
constexpr unsigned int COL = 20;
constexpr unsigned int COL = 21;
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef TIMER_HPP
#define TIMER_HPP
struct Timer {
void decrement_time(int &time, bool &running, bool &timer_active);
};
#endif
+2 -4
View File
@@ -6,9 +6,7 @@
#include "elements.hpp"
struct Window {
// Window();
std::array<std::array<char, COL>, ROW> m_board;
// void update_display();
void update_display(Paddle &a, Paddle &b);
std::array<std::array<char, COL>, ROW> m_board = {};
void update_display(Paddle &left, Paddle &right, Ball &ball, int &time);
};
#endif
+56 -10
View File
@@ -10,24 +10,70 @@ void Point::clear(std::array<std::array<char, COL>, 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--;
}
}
+34 -3
View File
@@ -1,22 +1,53 @@
#include <iostream>
#include <thread>
#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;
}
+14
View File
@@ -0,0 +1,14 @@
#include <thread>
#include <chrono>
#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;
}
}
}
+7 -20
View File
@@ -3,33 +3,20 @@
#include <chrono>
#include <thread>
// Window::Window() {
// for(std::array<char, COL> &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<char, COL> &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<char, COL> &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<char, COL> &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
}