commit 51685622714c543adc0e28aab6050b7fefaa89d6 Author: emad Date: Mon Apr 20 23:09:26 2026 +0430 breakOut diff --git a/Breakout.exe b/Breakout.exe new file mode 100644 index 0000000..223ab64 Binary files /dev/null and b/Breakout.exe differ diff --git a/bandicam 2026-02-10 06-51-21-815.mp4 b/bandicam 2026-02-10 06-51-21-815.mp4 new file mode 100644 index 0000000..825b28d Binary files /dev/null and b/bandicam 2026-02-10 06-51-21-815.mp4 differ diff --git a/editedGame.cpp b/editedGame.cpp new file mode 100644 index 0000000..afbf4e0 --- /dev/null +++ b/editedGame.cpp @@ -0,0 +1,1563 @@ +#include "game.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +// Structures +struct paddle +{ + int x; + int width; + string paddleChar; +}; +struct ball +{ + int x; + int y; + int vx; + int vy; +}; +struct brick +{ + int x; + int y; + int width; + bool isBroken; + int color; + int CTB; // Collision TO Break +}; + +// Globals +const int width = 81; +const int height = 30; + +int FPS = 60; +int frameDelay = 1000 / FPS; + +int goldenCount = 0; +int TNTCount = 0; +int HardCount = 0; +int normalCount = 0; + +const int panelx = 130; +const int panely = 5; + +int score = 0; +int Broken = 0; +int life = 3; + +int brickCol = 10; +int brickRow = 5; +const int brickWidth = 4; +const int brickGap = 1; +int brickColors[] = {9, 10, 11, 12, 13, 14}; +brick bricks[14][8]; + +player Player = {}; +paddle Paddle; +ball Ball; + +// SetUp +void HideCursor(bool visible) +{ + HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_CURSOR_INFO info; + info.dwSize = 100; + info.bVisible = visible; + SetConsoleCursorInfo(consoleHandle, &info); +} +void initializeBricks(); +void initializePaddle(paddle &paddle, int width); +void initializeBall(ball &Ball); + +// Game +void input(); +void logic(ball &); +// void render(); +// void renderPanel(); + +bool game(); +int gameDelay = 150; +bool gameOver = false; +bool bricksCount(); + +// Pause +void render(string pause); +void pauseMenu(); +int pauseOption = 1; + +// Other Prototypes +void explodeBricks(int col, int row); +void nextStage(); + +// Game History +player history[100] = {}; +int historyCount = 0; + +// Load Game +player loadedPlayer[100] = {}; +int playerCount = 0; +int loadOption = 1; // for delete record index + +// int main() +// { +// fstream file("loadGame.dat", ios::binary | ios::in | ios::out); +// file.seekp(0); +// player temp; +// file.read(reinterpret_cast(&temp), sizeof(player)); +// file.read(reinterpret_cast(&Ball), sizeof(ball)); +// file.read(reinterpret_cast(&Paddle.width), sizeof(int)); +// file.read(reinterpret_cast(&Paddle.x), sizeof(int)); +// size_t len; +// file.read(reinterpret_cast(&len), sizeof(len)); +// cout << sizeof(len) << endl; +// cout << len; +// } +bool game(int) +{ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + system("cls"); + HideCursor(false); + life = Player.life; + score = Player.score; + pauseOption = 1; + renderPanel(); + auto lastTime2 = std::chrono::steady_clock::now(); + renderPanel(); + while (!gameOver) + { + auto currentTime = std::chrono::steady_clock::now(); + auto elapsedTime = std::chrono::duration_cast(currentTime - lastTime2).count(); + + // broken == 50? + if (bricksCount()) + { + nextStage(); + Sleep(1000); + if (FPS < 120) + { + FPS += 20; + } + if (brickRow < 8) + { + brickRow++; + } + if (brickRow % 2 == 0 && brickCol < 14) + { + brickCol += 2; + } + initializeBricks(); + initializePaddle(Paddle, width); + initializeBall(Ball); + } + auto frameStart = std::chrono::steady_clock::now(); + input(); + if (pauseOption == 2) + { + return false; + } + else if (pauseOption >= 2) + { + return true; + } + logic(Ball); + SetConsoleCursorPosition(h, {0, 5}); + render(); + auto frameTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - frameStart).count(); + if (frameDelay > frameTime) + { + Sleep(frameDelay - frameTime); // تنظیم فاصله زمانی برای رسیدن به FPS ثابت + } + } + if (gameOver == true) + { + life--; + } + while (life > 0) + { + + HideCursor(false); + initializePaddle(Paddle, width); + initializeBall(Ball); + COORD cursor = {0, 5}; + gameOver = false; + auto lastTime = std::chrono::steady_clock::now(); + SetConsoleCursorPosition(h, cursor); + render(); + renderPanel(); + char start = _getch(); + if (start == 27) + { + pauseMenu(); + } + while (!gameOver) + { + auto currentTime = std::chrono::steady_clock::now(); + auto elapsedTime = std::chrono::duration_cast(currentTime - lastTime).count(); + + // broken == 50? + if (bricksCount()) + { + nextStage(); + Sleep(1000); + if (FPS < 120) + { + FPS += 20; + } + if (brickRow < 8) + { + brickRow++; + } + if (brickRow % 2 == 0 && brickCol < 14) + { + brickCol += 2; + } + initializeBricks(); + initializePaddle(Paddle, width); + initializeBall(Ball); + } + input(); + if (pauseOption == 2) + { + return false; + } + else if (pauseOption >= 2) + { + return true; + } + if (elapsedTime > 75) + { + logic(Ball); + SetConsoleCursorPosition(h, cursor); + render(); + lastTime = currentTime; + } + } + if (gameOver == true) + { + life--; + } + } + return true; +} + +bool game() +{ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + system("cls"); + HideCursor(false); + initializeBricks(); + initializePaddle(Paddle, width); + initializeBall(Ball); + life = 3; + score = 0; + pauseOption = 1; + Broken = 0; + goldenCount = 0; + TNTCount = 0; + HardCount = 0; + normalCount = 0; + while (life > 0) + { + + HideCursor(false); + initializePaddle(Paddle, width); + initializeBall(Ball); + COORD cursor = {0, 5}; + gameOver = false; + auto lastTime = std::chrono::steady_clock::now(); + SetConsoleCursorPosition(h, cursor); + render(); + renderPanel(); + char start = _getch(); + if (start == 27) + { + pauseMenu(); + } + while (!gameOver) + { + + // broken == 50? + if (bricksCount()) + { + nextStage(); + Sleep(1000); + if (brickRow < 8) + { + brickRow++; + } + if (brickRow % 2 == 0 && brickCol < 14) + { + brickCol += 2; + } + initializeBricks(); + initializePaddle(Paddle, width); + initializeBall(Ball); + SetConsoleCursorPosition(h, cursor); + HideCursor(false); + Broken = 0; + render(); + renderPanel(); + _getch(); + } + auto frameStart = std::chrono::steady_clock::now(); + input(); + if (pauseOption == 2) + { + return false; + } + else if (pauseOption >= 2) + { + return true; + } + logic(Ball); + SetConsoleCursorPosition(h, cursor); + render(); + auto frameTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - frameStart).count(); + if (frameDelay > frameTime) + { + Sleep(frameDelay - frameTime); // تنظیم فاصله زمانی برای رسیدن به FPS ثابت + } + } + if (gameOver == true) + { + life--; + } + } + return true; +} + +void initializeBricks() +{ + int totalBrickWidth = brickCol * brickWidth + (brickCol - 1) * brickGap; + + int start = (width - totalBrickWidth) / 2; + + srand(time(0)); + for (int col = 0; col < brickCol; col++) + { + for (int row = 0; row < brickRow; row++) + { + bricks[col][row].x = start + col * (brickWidth + brickGap); + bricks[col][row].y = row * 2 + 3; + bricks[col][row].width = brickWidth; + bricks[col][row].isBroken = false; + int r = rand() % 100; + if (r < 20) + { + bricks[col][row].color = 9; + } + else if (r < 40) + { + bricks[col][row].color = 10; + } + // else if (r < 60) + // { + // bricks[col][row].color = 11; + // } + else if (r < 80) + { + bricks[col][row].color = 13; + } + else if (r < 90) + { + bricks[col][row].color = 12; + } + else + { + bricks[col][row].color = 14; + } + if (bricks[col][row].color == 9) + { + bricks[col][row].CTB = 2; + } + else + { + bricks[col][row].CTB = 1; + } + } + } +} +void initializePaddle(paddle &Paddle, int width) +{ + Paddle.width = 7; + Paddle.paddleChar = "━"; + Paddle.x = (width - Paddle.width) / 2; +} +void initializeBall(ball &Ball) +{ + srand(time(0)); + Ball.x = Paddle.x + 3; + Ball.y = height - 3; + + int sign = rand() % 2; + int value = rand() % 2 + 1; + Ball.vx = sign == 0 ? 1 : -1; + Ball.vy = value; +} +void render() +{ + for (int y = 0; y < 30; y++) + { + cout << setw(45) << ""; + for (int x = 0; x < 81; x++) + { + string c = " "; + if (y == 0 && x == 0) + { + c = "┌"; + } + else if (y == 29 && x == 0) + { + c = "└"; + } + else if (y == 29 && x == 80) + { + c = "┘"; + } + else if (y == 0 && x == 80) + { + c = "┐"; + } + else if (y == 0 && (x > 0 && x < 80)) + { + c = "─"; + } + else if (y == 29 && (x > 0 && x < 80)) + { + c = "─"; + } + else if (x == 0 && (y > 0 && y < 29)) + { + c = "│"; + } + else if (x == 80 && (y > 0 && y < 29)) + { + c = "│"; + } + for (int col = 0; col < brickCol; col++) + { + for (int row = 0; row < brickRow; row++) + { + if (y == bricks[col][row].y && + x >= bricks[col][row].x && + x < bricks[col][row].x + bricks[col][row].width && bricks[col][row].isBroken == false) + { + setColor(bricks[col][row].color); + c = "█"; + } + } + } + if (y == height - 2 && + x >= Paddle.x && + x < Paddle.x + Paddle.width) + { + c = Paddle.paddleChar; + } + + if (x > 0 && x < width - 1 && y > 0 && y < height - 1) + { + if (x == Ball.x && y == Ball.y) + c = "●"; + } + cout << c; + setColor(7); + } + cout << endl; + } +} +void render(string pause) +{ + for (int y = 0; y < 30; y++) + { + cout << setw(45) << ""; + for (int x = 0; x < 81; x++) + { + string c = " "; + if (y == 0 && x == 0) + { + c = "┌"; + } + else if (y == 29 && x == 0) + { + c = "└"; + } + else if (y == 29 && x == 80) + { + c = "┘"; + } + else if (y == 0 && x == 80) + { + c = "┐"; + } + else if (y == 0 && (x > 0 && x < 80)) + { + c = "─"; + } + else if (y == 29 && (x > 0 && x < 80)) + { + c = "─"; + } + else if (x == 0 && (y > 0 && y < 29)) + { + c = "│"; + } + else if (x == 80 && (y > 0 && y < 29)) + { + c = "│"; + } + for (int col = 0; col < 10; col++) + { + for (int row = 0; row < 5; row++) + { + if (y == bricks[col][row].y && + x >= bricks[col][row].x && + x < bricks[col][row].x + bricks[col][row].width && bricks[col][row].isBroken == false) + { + c = "█"; + } + } + } + if (y == height - 2 && + x >= Paddle.x && + x < Paddle.x + Paddle.width) + { + c = Paddle.paddleChar; + } + + if (x > 0 && x < width - 1 && y > 0 && y < height - 1) + { + if (x == Ball.x && y == Ball.y) + c = "●"; + } + cout << c; + } + cout << endl; + } +} +void input() +{ + if (_kbhit()) + { + char input = _getch(); + switch (input) + { + case 'D': + case 'd': + { + if (Paddle.x + Paddle.width < 78 && (Ball.vx > 1 || Ball.vx < -1)) + { + Paddle.x += 3; + } + else if (Paddle.x + Paddle.width < 79) + { + Paddle.x += 2; + } + break; + } + case 'A': + case 'a': + { + if (Paddle.x > 3 && (Ball.vx > 1 || Ball.vx < -1)) + { + Paddle.x -= 3; + } + else if (Paddle.x > 2) + { + Paddle.x -= 2; + } + break; + } + case 27: + { + pauseMenu(); + switch (pauseOption) + { + case 2: + { + } + } + break; + } + } + } +} +void playBeep(int F, int T) +{ + thread t(Beep, F, T); + t.detach(); +} +void bricksLogic(brick &B, int i, int j) +{ + B.CTB--; + if (B.color == 9 && B.CTB == 1) + { + playBeep(600 + 9 * 50, 60); + B.color = 11; + } + if (B.CTB <= 0) + { + B.isBroken = true; + + if (B.color == 12) + { + TNTCount++; + playBeep(600 + 12 * 50, 60); + explodeBricks(i, j); + } + + if (B.color == 14) + { + goldenCount++; + playBeep(600 + 14 * 50, 60); + score += 20; + } + else + { + if (B.color == 14) + { + HardCount++; + } + else + { + normalCount++; + } + playBeep(600, 60); + score += 10; + } + Broken++; + renderPanel(); + } +} +void logic(ball &) +{ + + // endGame -> you will lose a life + if (Ball.y >= height - 1) + { + // playBeep(200, 200); + // playBeep(300, 100); + // playBeep(400, 100); + // playBeep(500, 100); + playBeep(500, 300); + playBeep(350, 400); + playBeep(200, 600); + gameOver = true; + } + + // Wall Collision + if (Ball.x >= width - 1 || Ball.x <= 1) + { + playBeep(520, 80); + + Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; + Ball.vx *= -1; + } + if (Ball.y <= 1) + { + playBeep(520, 80); + Ball.vy *= -1; + } + + // Brick Collision + bool collision = false; + for (int i = 0; i < brickCol && !collision; i++) + { + for (int j = 0; j < brickRow; j++) + { + // from below + if (Ball.x >= bricks[i][j].x - 1 && + Ball.x < bricks[i][j].x + bricks[i][j].width + 1 && + (Ball.y == bricks[i][j].y + 1) && bricks[i][j].isBroken == false && Ball.vy < 0) + { + collision = true; + + Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; + Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; + Ball.vy *= -1; + if (j < brickRow - 1) + { + if (((Ball.y + Ball.vy) == bricks[i][j + 1].y) && + bricks[i][j + 1].isBroken == false && (Ball.x + Ball.vx >= bricks[i][j + 1].x) && + (Ball.x + Ball.vx < bricks[i][j + 1].x + bricks[i][j + 1].width)) + { + Ball.y = bricks[i][j + 1].y - 2; + } + } + + bricksLogic(bricks[i][j], i, j); + break; + } + + // from left + else if (Ball.x == bricks[i][j].x - 1 && + (Ball.y >= bricks[i][j].y - 1 && Ball.y <= bricks[i][j].y + 1) && + bricks[i][j].isBroken == false && Ball.vx > 0) + { + collision = true; + + Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; + Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; + Ball.vx *= -1; + if (i > 0) + { + // (Ball.x + Ball.vx) >= bricks[i - 1][j].x && + if ((Ball.x + Ball.vx) >= bricks[i - 1][j].x && + (Ball.x + Ball.vx) < bricks[i - 1][j].x + brickWidth && + bricks[i - 1][j].isBroken == false && (Ball.y + Ball.vy == bricks[i - 1][j].y)) + { + Ball.x += bricks[i - 1][j].x + brickWidth - 1 - (Ball.x + Ball.vx) + 1; + } + } + + bricksLogic(bricks[i][j], i, j); + break; + } + + // from right + else if (Ball.x == bricks[i][j].x + bricks[i][j].width + 1 && + (Ball.y >= bricks[i][j].y - 1 && Ball.y <= bricks[i][j].y + 1) && + bricks[i][j].isBroken == false && Ball.vx < 0) + { + collision = true; + + Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; + Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; + Ball.vx *= -1; + if (i < brickCol - 1) + { + // (Ball.x + Ball.vx) >= bricks[i - 1][j].x && + if ((Ball.x + Ball.vx) >= bricks[i + 1][j].x && + (Ball.x + Ball.vx) < bricks[i + 1][j].x + brickWidth && + bricks[i + 1][j].isBroken == false && (Ball.y + Ball.vy == bricks[i + 1][j].y)) + { + Ball.x -= Ball.x + Ball.vx - bricks[i + 1][j].x + 1; + } + } + + bricksLogic(bricks[i][j], i, j); + renderPanel(); + break; + } + // from above + else if (Ball.x >= bricks[i][j].x - 1 && + Ball.x < bricks[i][j].x + bricks[i][j].width + 1 && + (Ball.y == bricks[i][j].y - 1) && bricks[i][j].isBroken == false && Ball.vy > 0) + { + collision = true; + + Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; + Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; + Ball.vy *= -1; + if (j > 0) + { + if (((Ball.y + Ball.vy) == bricks[i][j - 1].y) && + bricks[i][j - 1].isBroken == false && (Ball.x + Ball.vx >= bricks[i][j - 1].x) && (Ball.x + Ball.vx < bricks[i][j - 1].x + bricks[i][j + 1].width)) + { + Ball.y += 2; + } + } + + bricksLogic(bricks[i][j], i, j); + break; + } + } + } + int nextY = Ball.y + Ball.vx; + + // Paddle Collision + int delta = 0; + if (Ball.x >= Paddle.x && + Ball.x < Paddle.x + Paddle.width && Ball.y == height - 3) + { + playBeep(520, 80); + Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; + Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; + int pos = Paddle.x + Paddle.width - Ball.x; + switch (pos) + { + // case 0: + case 2: + case 1: + { + + Ball.vy *= -1; + if (Ball.x < 20 && Ball.vx < 0 && Ball.vx < 0) + { + Ball.vx *= -1; + } + Ball.vx > 0 ? delta = 2 : delta = 0; + break; + } + // case 8:/ + case 6: + case 7: + { + Ball.vy *= -1; + if (Ball.x > width - 20 && Ball.vx > 0) + { + Ball.vx *= -1; + } + Ball.vx > 0 ? delta = 0 : delta = -2; + break; + } + + case 4: + { + // srand(time(0)); + // Ball.vx = (rand() % 2 == 0) ? 1 : -1; + } + case 5: + case 3: + { + // Ball.vx = 0; + Ball.vy *= -1; + break; + } + } + } + Ball.vx += delta; + + if (Ball.x + Ball.vx > width - 1) + { + Ball.x = width - 1; + } + else if (Ball.x + Ball.vx < 1) + { + Ball.x = 1; + } + else + { + Ball.x += Ball.vx; + } + Ball.y += Ball.vy; +} +bool bricksCount() +{ + for (int i = 0; i < brickCol; i++) + { + for (int j = 0; j < brickRow; j++) + { + if (bricks[i][j].isBroken == false) + { + return false; + } + } + } + return true; +} +void renderPanel() +{ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {panelx, panely}); + cout << "┌───────────────────┐"; + SetConsoleCursorPosition(h, {panelx, panely + 1}); + cout << "│ Game Info │"; + SetConsoleCursorPosition(h, {panelx, panely + 2}); + cout << "├───────────────────┤"; + SetConsoleCursorPosition(h, {panelx, panely + 3}); + cout << "│ Score: " << setw(5) << score << " │"; + SetConsoleCursorPosition(h, {panelx, panely + 4}); + cout << "│ Life: " << setw(5) << life << " │"; + SetConsoleCursorPosition(h, {panelx, panely + 5}); + cout << "│ Bricks: " << setw(5) << (brickCol * brickRow) - Broken << " │"; + SetConsoleCursorPosition(h, {panelx, panely + 6}); + cout << "└───────────────────┘"; +} +void selectPO(int option, int crrOption) // PO: pause option +{ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + + if (option == crrOption) + { + SetConsoleTextAttribute(h, 1); + } + else + { + SetConsoleTextAttribute(h, 15); + } +} +void pauseMenu() +{ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h, 8); + SetConsoleCursorPosition(h, {0, 5}); + render("pause"); + renderPanel(); + SetConsoleTextAttribute(h, 15); + SetConsoleCursorPosition(h, {65, 13}); + cout << "╔══════════════════PAUSE══════════════════╗"; + for (int i = 0; i < 13; i++) + { + SetConsoleCursorPosition(h, {65, SHORT(14 + i)}); + cout << "║ ║"; + } + SetConsoleCursorPosition(h, {65, 26}); + SetConsoleTextAttribute(h, 15); + cout << "╚═════════════════════════════════════════╝"; + while (true) + { + selectPO(1, pauseOption); + SetConsoleCursorPosition(h, {80, 14}); + cout << "╔═══════════╗"; + SetConsoleCursorPosition(h, {80, 15}); + cout << "║ Resume ║"; + SetConsoleCursorPosition(h, {80, 16}); + cout << "╚═══════════╝"; + selectPO(2, pauseOption); + SetConsoleCursorPosition(h, {80, 17}); + cout << "╔═══════════╗"; + SetConsoleCursorPosition(h, {80, 18}); + cout << "║ Restart ║"; + SetConsoleCursorPosition(h, {80, 19}); + cout << "╚═══════════╝"; + selectPO(3, pauseOption); + SetConsoleCursorPosition(h, {80, 20}); + cout << "╔═══════════╗"; + SetConsoleCursorPosition(h, {80, 21}); + cout << "║ Save Game ║"; + SetConsoleCursorPosition(h, {80, 22}); + cout << "╚═══════════╝"; + selectPO(4, pauseOption); + SetConsoleCursorPosition(h, {80, 23}); + cout << "╔═══════════╗"; + SetConsoleCursorPosition(h, {80, 24}); + cout << "║ Quit ║"; + SetConsoleCursorPosition(h, {80, 25}); + cout << "╚═══════════╝"; + while (true) + { + if (_kbhit()) + { + char userInput = _getch(); + if ((userInput == 'w' || userInput == 'W') && pauseOption > 1) + { + pauseOption -= 1; + break; + } + else if ((userInput == 's' || userInput == 'S') && pauseOption < 4) + { + pauseOption += 1; + break; + } + if (userInput == 13) + { + if (pauseOption <= 2) + { + SetConsoleTextAttribute(h, 7); + renderPanel(); + } + return; + } + } + } + Sleep(10); + } +} +void setColor(int color) +{ + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(h, color); +} +void explodeBricks(int col, int row) +{ + for (int dx = -1; dx <= 1; dx++) + { + for (int dy = -1; dy <= 1; dy++) + { + if (dx == 0 && dy == 0) + continue; + int c = col + dx; + int r = row + dy; + if (c >= 0 && c < brickCol && r >= 0 && r < brickRow) + { + if (!bricks[c][r].isBroken && !(c == col && r == row)) + { + bricks[c][r].isBroken = true; + if (bricks[c][r].color == 14) + { + goldenCount++; + score += 20; + } + else + { + if (bricks[c][r].color == 9 || bricks[c][r].color == 11) + { + HardCount++; + } + else + { + normalCount++; + } + score += 10; + } + Broken++; + } + } + } + } +} +void saveHistory() +{ + time_t now = time(nullptr); + tm *local = localtime(&now); + strftime(Player.date, 80, "%Y-%m(%b)-%d(%a)", local); + strftime(Player.time, 80, "%H:%M", local); + + char *pointer = strstr(Player.name, "(auto save)"); // پیدا کردن کلمه + if (pointer != NULL) + { + int length = strlen("(auto save)"); + // کپی کردن ادامه رشته روی بخش پیدا شده + strcpy(pointer, pointer + length); + } + ofstream file("history.txt", ios::app); + if (file.fail()) + return; + file << Player.name << " " + << Player.date << " " + << Player.time << " " + << score << endl; // PLayer.score = scores + file.close(); + + ofstream scores("scores.txt", ios::out | ios::app); + if (scores.fail()) + return; + scores << Player.name << " " + << goldenCount << " " + << TNTCount << " " + << HardCount << " " + << normalCount << endl; + scores.close(); +} +void loadScoresAndPrint(char name[]) +{ + // T: Tmep + string Tname; + int TgoldenCount = 0; + int TeTNTCount = 0; + int THardCount = 0; + int TnormalCount = 0; + ifstream scores("scores.txt", ios::in); + if (scores.fail()) + return; + while (scores >> Tname >> TgoldenCount >> TNTCount >> THardCount >> TnormalCount) + { + if (Tname == name) + { + break; + } + } + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + system("cls"); + setColor(7); + SetConsoleCursorPosition(h, {68, 15}); + cout << "╔══════════════════════════════╗"; + SetConsoleCursorPosition(h, {68, 16}); + cout << "║ ║"; + SetConsoleCursorPosition(h, {68, 17}); + cout << "║ "; setColor(5); cout << "YOU HEAT "; setColor(7); cout <<" ║"; + SetConsoleCursorPosition(h, {68, 18}); + cout << "║ " << "\033[38;5;196mTNT: " << TNTCount; + SetConsoleCursorPosition(h, {99, 18}); + cout << "\033[0m║"; + SetConsoleCursorPosition(h, {68, 19}); + cout << "║ ║"; + SetConsoleCursorPosition(h, {68, 20}); + cout << "║ " << "\033[38;5;226mGolden: " << TgoldenCount; + SetConsoleCursorPosition(h, {99, 20}); + cout << "\033[0m║"; + SetConsoleCursorPosition(h, {68, 21}); + cout << "║ ║"; + SetConsoleCursorPosition(h, {68, 22}); + cout << "║ " << "\033[38;5;33mHard: " << THardCount; + SetConsoleCursorPosition(h, {99, 22}); + cout << "\033[0m║"; + SetConsoleCursorPosition(h, {68, 23}); + cout << "║ ║"; + SetConsoleCursorPosition(h, {68, 24}); + cout << "║ " << "\033[38;5;181mNormal: " << TnormalCount; + SetConsoleCursorPosition(h, {99, 24}); + cout << "\033[0m║"; + SetConsoleCursorPosition(h, {68, 25}); + cout << "\033[0m╚══════════════════════════════╝"; +} +int sort() +{ + if (historyCount == 1) + { + return history[0].score; + } + int high; + for (int i = 0; i < historyCount - 1; i++) + { + for (int j = 0; j < historyCount - i - 1; j++) + { + if (history[j].score < history[j + 1].score) + { + swap(history[j], history[j + 1]); + } + } + } + return history[0].score; +} +void loadHistory() +{ + historyCount = 0; + ifstream file("history.txt"); + file.seekg(0); + if (file.is_open()) + { + while (file >> history[historyCount].name >> history[historyCount].date >> history[historyCount].time >> history[historyCount].score) + { + historyCount++; + } + } + file.close(); +} +int Hoption = 1; // History option +void setHoptioncolor(int crrOption, int option) +{ + if (crrOption == option) + { + setColor(13); + } + else + { + setColor(7); + } +} +bool printHistory(int historyCount) +{ + setColor(5); + system("cls"); + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {54, 3}); + cout << "==============================================================\n"; + cout << setw(54) << "" << " GAME HISTORY\n"; + cout << setw(54) << "" << "==============================================================\n\n"; + cout << setw(54) << ""; + cout << left + << setw(6) << "Rank" + << setw(15) << "Name" + << setw(25) << "Date" + << setw(10) << "Time" + << setw(10) << "Score" + // << setw(8) << "Lives" + // << setw(8) << "Result" + << endl; + + cout << setw(54) << "" << "--------------------------------------------------------------\n"; + + setColor(7); + while (true) + { + SetConsoleCursorPosition(h, {0, 9}); + for (int i = 0; i < historyCount; i++) + { + setHoptioncolor(Hoption, i + 1); + cout << setw(54) << ""; + cout << left + << setw(6) << i + 1 + << setw(15) << history[i].name + << setw(25) << history[i].date + << setw(10) << history[i].time + << setw(10) << history[i].score + // << setw(8) << history[i].life + // << setw(8) << (history[i].win ? "WIN" : "LOSE") + << endl; + } + setColor(5); + cout << setw(54) << "" << "==============================================================\n"; + while (true) + { + if (_kbhit()) + { + char userInput = _getch(); + if ((userInput == 'w' || userInput == 'W') && Hoption > 1) + { + Hoption -= 1; + break; + } + else if ((userInput == 's' || userInput == 'S') && Hoption < historyCount) + { + Hoption += 1; + break; + } + else if (userInput == 13) + { + return true; + } + else if (userInput == 8) + { + + return false; + } + } + } + } + setColor(7); + _getch(); +} +void saveGame(player &p) +{ + p.score = score; + p.life = life; + p.isActive = false; + time_t now = time(nullptr); + tm *local = localtime(&now); + strftime(Player.date, 80, "%Y-%m(%b)-%d(%a)", local); + strftime(Player.time, 80, "%H:%M", local); + // maybe ios::app + ofstream fOut("loadGame.dat", ios::app | ios::binary); + if (fOut.is_open()) + { + fOut.write(reinterpret_cast(&p), sizeof(player)); + fOut.write(reinterpret_cast(&Ball), sizeof(ball)); + + fOut.write(reinterpret_cast(&Paddle.width), sizeof(int)); + fOut.write(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len = Paddle.paddleChar.size(); + fOut.write(reinterpret_cast(&len), sizeof(len)); + fOut.write(Paddle.paddleChar.c_str(), len); + + fOut.write(reinterpret_cast(&brickCol), sizeof(int)); + fOut.write(reinterpret_cast(&brickRow), sizeof(int)); + fOut.write(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); + fOut.write(reinterpret_cast(&Broken), sizeof(int)); + fOut.write(reinterpret_cast(&goldenCount), sizeof(int)); + fOut.write(reinterpret_cast(&TNTCount), sizeof(int)); + fOut.write(reinterpret_cast(&HardCount), sizeof(int)); + fOut.write(reinterpret_cast(&normalCount), sizeof(int)); + } + fOut.seekp(0, ios::end); + fOut.close(); +} + +// Half AI +void setAndMarkAsActive(int index) +{ + // باز کردن فایل در حالت خواندن و نوشتن همزمان (ios::in | ios::out) + fstream file("loadGame.dat", ios::binary | ios::in | ios::out); + int count = 1; + player temp; + if (file.is_open()) + { + if (index == 1) + { + while (file.read(reinterpret_cast(&temp), sizeof(player))) + { + if (temp.isActive == false) + { + int pointer = file.tellp(); + int pos = pointer - sizeof(player); + + temp.isActive = true; + char *find = strstr(temp.name, "(auto save)"); // پیدا کردن کلمه + if (find != NULL) + { + int length = strlen("(auto save)"); + // کپی کردن ادامه رشته روی بخش پیدا شده + strcpy(find, find + length); + } + Player = temp; + file.read(reinterpret_cast(&Ball), sizeof(ball)); + + file.read(reinterpret_cast(&Paddle.width), sizeof(int)); + file.read(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len; + file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول + Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ + file.read(&Paddle.paddleChar[0], len); // خواندن متن + + file.read(reinterpret_cast(&brickCol), sizeof(int)); + file.read(reinterpret_cast(&brickRow), sizeof(int)); + file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); + file.read(reinterpret_cast(&Broken), sizeof(int)); + file.read(reinterpret_cast(&goldenCount), sizeof(int)); + file.read(reinterpret_cast(&TNTCount), sizeof(int)); + file.read(reinterpret_cast(&HardCount), sizeof(int)); + file.read(reinterpret_cast(&normalCount), sizeof(int)); + file.seekp(pos); + file.write(reinterpret_cast(&Player), sizeof(player)); + break; + } + file.read(reinterpret_cast(&Ball), sizeof(ball)); + file.read(reinterpret_cast(&Paddle.width), sizeof(int)); + file.read(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len; + file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول + Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ + file.read(&Paddle.paddleChar[0], len); // خواندن متن + + file.read(reinterpret_cast(&brickCol), sizeof(int)); + file.read(reinterpret_cast(&brickRow), sizeof(int)); + file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); + file.read(reinterpret_cast(&Broken), sizeof(int)); + file.read(reinterpret_cast(&goldenCount), sizeof(int)); + file.read(reinterpret_cast(&TNTCount), sizeof(int)); + file.read(reinterpret_cast(&HardCount), sizeof(int)); + file.read(reinterpret_cast(&normalCount), sizeof(int)); + } + } + else + { + while (count < index) + { + file.read(reinterpret_cast(&temp), sizeof(player)); + if (temp.isActive == false) + { + count++; + } + file.read(reinterpret_cast(&Ball), sizeof(ball)); + file.read(reinterpret_cast(&Paddle.width), sizeof(int)); + file.read(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len; + file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول + Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ + file.read(&Paddle.paddleChar[0], len); // خواندن متن + + file.read(reinterpret_cast(&brickCol), sizeof(int)); + file.read(reinterpret_cast(&brickRow), sizeof(int)); + file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); + file.read(reinterpret_cast(&Broken), sizeof(int)); + file.read(reinterpret_cast(&goldenCount), sizeof(int)); + file.read(reinterpret_cast(&TNTCount), sizeof(int)); + file.read(reinterpret_cast(&HardCount), sizeof(int)); + file.read(reinterpret_cast(&normalCount), sizeof(int)); + } + while (file.read(reinterpret_cast(&temp), sizeof(player))) + { + if (temp.isActive == false) + { + int pointer = file.tellp(); + int pos = pointer - sizeof(player); + + temp.isActive = true; + char *find = strstr(temp.name, "(auto save)"); // پیدا کردن کلمه + if (find != NULL) + { + int length = strlen("(auto save)"); + // کپی کردن ادامه رشته روی بخش پیدا شده + strcpy(find, find + length); + } + Player = temp; + file.read(reinterpret_cast(&Ball), sizeof(ball)); + + file.read(reinterpret_cast(&Paddle.width), sizeof(int)); + file.read(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len; + file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول + Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ + file.read(&Paddle.paddleChar[0], len); // خواندن متن + + file.read(reinterpret_cast(&brickCol), sizeof(int)); + file.read(reinterpret_cast(&brickRow), sizeof(int)); + file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); + file.read(reinterpret_cast(&Broken), sizeof(int)); + file.read(reinterpret_cast(&goldenCount), sizeof(int)); + file.read(reinterpret_cast(&TNTCount), sizeof(int)); + file.read(reinterpret_cast(&HardCount), sizeof(int)); + file.read(reinterpret_cast(&normalCount), sizeof(int)); + file.seekp(pos); + file.write(reinterpret_cast(&Player), sizeof(player)); + break; + } + file.read(reinterpret_cast(&Ball), sizeof(ball)); + file.read(reinterpret_cast(&Paddle.width), sizeof(int)); + file.read(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len; + file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول + Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ + file.read(&Paddle.paddleChar[0], len); // خواندن متن + + file.read(reinterpret_cast(&brickCol), sizeof(int)); + file.read(reinterpret_cast(&brickRow), sizeof(int)); + file.read(reinterpret_cast(&bricks), (sizeof(brick) * brickCol * brickRow)); + file.read(reinterpret_cast(&Broken), sizeof(int)); + file.read(reinterpret_cast(&goldenCount), sizeof(int)); + file.read(reinterpret_cast(&TNTCount), sizeof(int)); + file.read(reinterpret_cast(&HardCount), sizeof(int)); + file.read(reinterpret_cast(&normalCount), sizeof(int)); + } + } + file.close(); + } +} +void setLGOColor(int crrOption, int option) // LGO : Load Game Option +{ + if (crrOption == option) + { + setColor(14); + } + else + { + setColor(15); + } +} +void loadPlayer() +{ + playerCount = 0; + // int count = 0; + ifstream fIn("loadGame.dat", ios::in | ios::binary); + player temp; + // int index = sizeof(ball) + sizeof(paddle) + sizeof(bricks) + sizeof(int); + fIn.seekg(0); + if (fIn.is_open()) + { + while (fIn.read(reinterpret_cast(&temp), sizeof(player))) + { + if (temp.isActive == false) + { + loadedPlayer[playerCount] = temp; + playerCount++; + } + fIn.read(reinterpret_cast(&Ball), sizeof(ball)); + fIn.read(reinterpret_cast(&Paddle.width), sizeof(int)); + fIn.read(reinterpret_cast(&Paddle.x), sizeof(int)); + size_t len; + fIn.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول + Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ + fIn.read(&Paddle.paddleChar[0], len); // خواندن متن + + fIn.read(reinterpret_cast(&brickCol), sizeof(int)); + fIn.read(reinterpret_cast(&brickRow), sizeof(int)); + fIn.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); + fIn.read(reinterpret_cast(&Broken), sizeof(int)); + fIn.read(reinterpret_cast(&goldenCount), sizeof(int)); + fIn.read(reinterpret_cast(&TNTCount), sizeof(int)); + fIn.read(reinterpret_cast(&HardCount), sizeof(int)); + fIn.read(reinterpret_cast(&normalCount), sizeof(int)); + } + } + fIn.close(); +} +bool printLoadGame() +{ + setColor(6); + loadOption = 1; + system("cls"); + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {51, 3}); + cout << "=================================================================\n"; + cout << setw(51) << "" << " LOAD GAME\n"; + cout << setw(51) << "" << "=================================================================\n\n"; + cout << setw(51) << ""; + cout << left + << setw(4) << "#" + << setw(15) << "Name" + << setw(10) << "Score" + << setw(8) << "Lives" + << setw(22) << "Date" + << setw(10) << "Time" + << endl; + + cout << setw(51) << "" << "-----------------------------------------------------------------\n"; + while (true) + { + SetConsoleCursorPosition(h, {0, 9}); + for (int i = 0; i < playerCount; i++) + { + setLGOColor(loadOption, i + 1); + cout << setw(51) << ""; + cout << "|" << left + << setw(3) << i + 1 + << setw(15) << loadedPlayer[i].name + << setw(10) << loadedPlayer[i].score + << setw(8) << loadedPlayer[i].life + << setw(22) << loadedPlayer[i].date + << setw(10) << loadedPlayer[i].time + << endl; + if (i < playerCount - 1) + { + setColor(15); + cout << setw(51) << "" << "-----------------------------------------------------------------\n"; + } + } + setColor(6); + cout << setw(51) << "" << "=================================================================\n"; + while (true) + { + if (_kbhit()) + { + char userInput = _getch(); + if ((userInput == 'w' || userInput == 'W') && loadOption > 1) + { + loadOption -= 1; + break; + } + else if ((userInput == 's' || userInput == 'S') && loadOption < playerCount) + { + loadOption += 1; + break; + } + else if (userInput == 13) + { + if (playerCount > 0) + { + return true; + } + } + else if (userInput == 8) + { + + return false; + } + } + } + } + setColor(7); +} +void nextStage() +{ + HideCursor(true); + system("cls"); + string newGame[35][80]; + for (int H = 0; H < 35; H++) + { + for (int S = 0; S < 80; S++) + { + newGame[H][S] = " "; + } + } + newGame[0][0] = "╔"; + newGame[0][54] = "╗"; + newGame[34][0] = "╚"; + newGame[34][54] = "╝"; + for (int i = 1; i < 34; i++) + { + newGame[i][0] = "║"; + newGame[i][54] = "║"; + } + for (int i = 1; i < 54; i++) + { + newGame[0][i] = "═"; + newGame[34][i] = "═"; + } + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {0, 14}); + for (int i = 0; i < 10; i++) + { + cout << setw(60) << ""; + for (int j = 0; j < 79; j++) + { + cout << newGame[i][j]; + } + cout << endl; + } + SetConsoleCursorPosition(h, {60, 23}); + cout << "╚═════════════════════════════════════════════════════╝"; + SetConsoleTextAttribute(h, 12); + SetConsoleCursorPosition(h, {85, 18}); + cout << "Great"; + SetConsoleCursorPosition(h, {77, 19}); + cout << "Loading next stage..."; + SetConsoleTextAttribute(h, 7); +} \ No newline at end of file diff --git a/game.hpp b/game.hpp new file mode 100644 index 0000000..66e6f97 --- /dev/null +++ b/game.hpp @@ -0,0 +1,32 @@ +#ifndef GAME_HPP +#define GAME_HPP +#include "menu.hpp" +extern player Player; +extern int score; +extern int life; +extern int pauseOption; +extern player history[100]; +extern int historyCount; +void render(); +void renderPanel(); +bool game(); +bool game(int); +void HideCursor(bool visible); +void setColor(int color); +void playBeep(int F, int T); + +//History +void saveHistory(); +int sort(); +void loadHistory(); +extern int Hoption; +void loadScoresAndPrint(char name[]); +bool printHistory(int historyCount); + +//Load Game +void saveGame(player &p); +void setAndMarkAsActive(int index); +void loadPlayer(); +bool printLoadGame(); +extern int loadOption; +#endif \ No newline at end of file diff --git a/game.jpg b/game.jpg new file mode 100644 index 0000000..551929d Binary files /dev/null and b/game.jpg differ diff --git a/gameOver.jpg b/gameOver.jpg new file mode 100644 index 0000000..5ac94ff Binary files /dev/null and b/gameOver.jpg differ diff --git a/help.jpg b/help.jpg new file mode 100644 index 0000000..143530a Binary files /dev/null and b/help.jpg differ diff --git a/history.jpg b/history.jpg new file mode 100644 index 0000000..f23ba0c Binary files /dev/null and b/history.jpg differ diff --git a/loadGame.jpg b/loadGame.jpg new file mode 100644 index 0000000..7359da9 Binary files /dev/null and b/loadGame.jpg differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..104e82e --- /dev/null +++ b/main.cpp @@ -0,0 +1,270 @@ +#include "menu.hpp" +#include "game.hpp" +#include +#include +#include +#include +#include +#include +using namespace std; + +bool GameOver(); +bool run = false; +void signalHandler(int signum) +{ + if (run && Player.name != 0) + { + strcat(Player.name, "(auto save)"); + saveGame(Player); + } + exit(signum); +} +int main() +{ + signal(SIGINT, signalHandler); + signal(SIGTERM, signalHandler); +#ifdef _WIN32 + signal(SIGBREAK, signalHandler); +#endif + + system("cls"); + while (true) + { + menu(); + switch (option) + { + case 1: + { + newGame(); + run = true; + bool playAgain = false; + int playCount = 1; + do + { + if (playCount > 1) + { + char temp[10]; // یک آرایه موقت برای نگه داشتن عدد + // تبدیل عدد به رشته و ریختن در temp + sprintf(temp, "%d", playCount); + + // حالا چسباندن به آرایه اصلی + strcat(Player.name, temp); + } + while (!game()) + ; + if (pauseOption == 3) + { + saveGame(Player); + run = false; + playAgain = false; + } + else if (pauseOption <= 2) + { + saveHistory(); + playAgain = GameOver(); + if (playAgain) + { + run = true; + playCount++; + } + } + } while (playAgain); + break; + } + case 2: + { + // printLoadGame(); + while (true) + { + loadPlayer(); + if (printLoadGame()) + { + run = true; + setAndMarkAsActive(loadOption); + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + system("cls"); + SetConsoleCursorPosition(h, {0, 5}); + render(); + renderPanel(); + _getch(); + Beep(440, 200); + Sleep(50); + Beep(660, 200); + Sleep(50); + Beep(880, 400); + bool playAgain = false; + int playCount = 1; + do + { + if (playCount > 1) + { + char temp[10]; // یک آرایه موقت برای نگه داشتن عدد + // تبدیل عدد به رشته و ریختن در temp + sprintf(temp, "%d", playCount); + + // حالا چسباندن به آرایه اصلی + strcat(Player.name, temp); + } + while (!game(2)) + ; + if (pauseOption == 3) + { + saveGame(Player); + run = false; + playAgain = false; + } + else if (pauseOption <= 2) + { + saveHistory(); + playAgain = GameOver(); + if (playAgain) + { + run = true; + playCount++; + } + } + } while (playAgain); + } + else + { + break; + } + } + break; + } + case 3: + { + loadHistory(); + sort(); + while (true) + { + if (printHistory(historyCount)) + { + loadScoresAndPrint(history[Hoption - 1].name); + _getch(); + } + else + { + break; + } + } + break; + } + case 4: + { + help(); + break; + } + case 5: + { + return 0; + } + } + } +} +bool GameOver() +{ + HideCursor(false); + setColor(11); + system("cls"); + loadHistory(); + int High = sort(); + string newGame[35][80]; + for (int H = 0; H < 35; H++) + { + for (int S = 0; S < 80; S++) + { + newGame[H][S] = " "; + } + } + newGame[0][0] = "╔"; + newGame[0][78] = "╗"; + newGame[34][0] = "╚"; + newGame[34][78] = "╝"; + for (int i = 1; i < 34; i++) + { + newGame[i][0] = "║"; + newGame[i][78] = "║"; + } + for (int i = 1; i < 78; i++) + { + newGame[0][i] = "═"; + newGame[34][i] = "═"; + } + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {0, 3}); + for (int i = 0; i < 17; i++) + { + cout << setw(45) << ""; + for (int j = 0; j < 79; j++) + { + cout << newGame[i][j]; + } + cout << endl; + } + SetConsoleCursorPosition(h, {45, 20}); + cout << "╚═════════════════════════════════════════════════════════════════════════════╝"; + SetConsoleCursorPosition(h, {79, 4}); + cout << "Game Over"; + SetConsoleCursorPosition(h, {46, 5}); + cout << "═════════════════════════════════════════════════════════════════════════════"; + SetConsoleCursorPosition(h, {48, 8}); + cout << "╔═══════════════════╗"; + SetConsoleCursorPosition(h, {48, 9}); + cout << "║ Score: " << setw(5) << score; + SetConsoleCursorPosition(h, {68, 9}); + cout << "║"; + SetConsoleCursorPosition(h, {48, 10}); + cout << "╚═══════════════════╝"; + SetConsoleCursorPosition(h, {48, 12}); + cout << "╔═══════════════════╗"; + SetConsoleCursorPosition(h, {48, 13}); + cout << "║ High: " << setw(6) << High; + SetConsoleCursorPosition(h, {68, 13}); + cout << "║"; + SetConsoleCursorPosition(h, {48, 14}); + cout << "╚═══════════════════╝"; + SetConsoleCursorPosition(h, {90, 7}); + cout << "╔══════════════════════════════╗"; + SetConsoleCursorPosition(h, {90, 8}); + cout << "║ Top Players ║"; + SetConsoleCursorPosition(h, {90, 9}); + cout << "║══════════════════════════════║"; + SetConsoleCursorPosition(h, {90, 10}); + cout << "║ " << left << setw(18) << history[0].name << right << setw(10) << history[0].score; + SetConsoleCursorPosition(h, {121, 10}); + cout << "║"; + SetConsoleCursorPosition(h, {90, 11}); + cout << "║══════════════════════════════║"; + SetConsoleCursorPosition(h, {90, 12}); + cout << "║ " << left << setw(18) << history[1].name; + history[1].score > 0 ? cout << right << setw(10) << history[1].score : cout << ""; + SetConsoleCursorPosition(h, {121, 12}); + cout << "║"; + SetConsoleCursorPosition(h, {90, 13}); + cout << "║══════════════════════════════║"; + SetConsoleCursorPosition(h, {90, 14}); + cout << "║ " << left << setw(18) << history[2].name; + history[2].score > 0 ? cout << right << setw(10) << history[2].score : cout << ""; + SetConsoleCursorPosition(h, {121, 14}); + cout << "║"; + SetConsoleCursorPosition(h, {90, 15}); + cout << "╚══════════════════════════════╝"; + SetConsoleCursorPosition(h, {76, 17}); + cout << "╔═══════════════╗"; + SetConsoleCursorPosition(h, {76, 18}); + cout << "║ ║"; + SetConsoleCursorPosition(h, {78, 18}); + setColor(15); + cout << "X: Play Again"; + setColor(11); + SetConsoleCursorPosition(h, {76, 19}); + cout << "╚═══════════════╝"; + setColor(7); + char input = _getch(); + if (input == 'X' || input == 'x') + { + return true; + } + return false; +} \ No newline at end of file diff --git a/menu.cpp b/menu.cpp new file mode 100644 index 0000000..796205e --- /dev/null +++ b/menu.cpp @@ -0,0 +1,301 @@ +#include "menu.hpp" +#include "game.hpp" +#include +#include +#include +#include +#include +using namespace std; +void options(string menu[][80], string option, int optionLength, int i); +int option = 1; +void menu() +{ + setColor(7); + HideCursor(false); + string menu[30][80]; + for (int H = 0; H < 30; H++) + { + for (int S = 0; S < 80; S++) + { + menu[H][S] = " "; + } + } + menu[0][0] = "╔"; + menu[0][79] = "╗"; + menu[29][0] = "╚"; + menu[29][79] = "╝"; + for (int i = 1; i < 29; i++) + { + menu[i][0] = "║"; + menu[i][79] = "║"; + } + for (int i = 1; i < 79; i++) + { + menu[0][i] = "═"; + menu[29][i] = "═"; + } + options(menu, "New Game", 8, 3); + options(menu, "Load Game", 9, 8); + options(menu, "Game History", 12, 13); + options(menu, "Help", 4, 18); + // options(menu, "Settings", 8, 23); + options(menu, "Exit", 4, 23); + system("cls"); + while (true) + { + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + COORD cursorPosition = {0, 5}; + SetConsoleCursorPosition(h, cursorPosition); + for (int i = 0; i < 30; i++) + { + cout << setw(45) << ""; + for (int j = 0; j < 80; j++) + { + if (option == 1) + { + if (i > 2 && i < 6 && j > 31 && j < 48) + { + SetConsoleTextAttribute(h, 1); + cout << menu[i][j]; + SetConsoleTextAttribute(h, 7); + + continue; + } + } + else if (option == 2) + { + if (i > 7 && i < 11 && j > 31 && j < 48) + { + SetConsoleTextAttribute(h, 1); + cout << menu[i][j]; + SetConsoleTextAttribute(h, 7); + + continue; + } + } + else if (option == 3) + { + if (i > 12 && i < 16 && j > 31 && j < 48) + { + SetConsoleTextAttribute(h, 1); + cout << menu[i][j]; + SetConsoleTextAttribute(h, 7); + + continue; + } + } + else if (option == 4) + { + if (i > 17 && i < 21 && j > 31 && j < 48) + { + SetConsoleTextAttribute(h, 1); + cout << menu[i][j]; + SetConsoleTextAttribute(h, 7); + + continue; + } + } + else if (option == 5) + { + if (i > 22 && i < 26 && j > 31 && j < 48) + { + SetConsoleTextAttribute(h, 1); + cout << menu[i][j]; + SetConsoleTextAttribute(h, 7); + continue; + } + } + // else + // { + // if (i > 27 && i < 31 && j > 31 && j < 48) + // { + // SetConsoleTextAttribute(h, 1); + // cout << menu[i][j]; + // SetConsoleTextAttribute(h, 7); + + // continue; + // } + // } + cout << menu[i][j]; + } + cout << endl; + } + while (true) + { + if (_kbhit()) + { + char userInput = _getch(); + if ((userInput == 'w' || userInput == 'W') && option > 1) + { + option -= 1; + break; + } + else if ((userInput == 's' || userInput == 'S') && option < 5) + { + option += 1; + break; + } + if (userInput == 13) + { + return; + } + } + } + Sleep(10); + } +} +void options(string menu[][80], string option, int optionLength, int i) +{ + int sapce = (15 - optionLength) / 2; + menu[i][32] = "╔"; + menu[i][47] = "╗"; + menu[i + 1][32] = "║"; + menu[i + 1][47] = "║"; + menu[i + 2][32] = "╚"; + menu[i + 2][47] = "╝"; + for (int width = 33; width < 47; width++) + { + menu[i][width] = "═"; + menu[i + 2][width] = "═"; + } + for (int T = 0; T < optionLength; T++) + { + menu[i + 1][33 + sapce + T] = option.at(T); + } +} +bool repeat(char name[]) +{ + loadHistory(); + for (int i = 0; i < historyCount; i++) + { + if (strcmp(name, history[i].name) == 0) + { + return true; + } + } + return false; +} +void newGame() +{ + Player = {}; + HideCursor(true); + system("cls"); + string newGame[35][80]; + for (int H = 0; H < 35; H++) + { + for (int S = 0; S < 80; S++) + { + newGame[H][S] = " "; + } + } + newGame[0][0] = "╔"; + newGame[0][79] = "╗"; + newGame[34][0] = "╚"; + newGame[34][79] = "╝"; + for (int i = 1; i < 34; i++) + { + newGame[i][0] = "║"; + newGame[i][79] = "║"; + } + for (int i = 1; i < 79; i++) + { + newGame[0][i] = "═"; + newGame[34][i] = "═"; + } + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {0, 5}); + for (int i = 0; i < 17; i++) + { + cout << setw(45) << ""; + for (int j = 0; j < 80; j++) + { + cout << newGame[i][j]; + } + cout << endl; + } + SetConsoleCursorPosition(h, {45, 21}); + cout << "╚══════════════════════════════════════════════════════════════════════════════╝"; + SetConsoleTextAttribute(h, 10); + SetConsoleCursorPosition(h, {81, 5}); + cout << "Breakout"; + + while (Player.name[0] == 0 || repeat(Player.name)) + { + if(repeat(Player.name)) + { + SetConsoleCursorPosition(h, {64, 8}); + setColor(4); + cout << "This name is alrady used!"; + _getch(); + SetConsoleCursorPosition(h, {64, 8}); + cout << " "; + + } + + SetConsoleTextAttribute(h, 7); + SetConsoleCursorPosition(h, {47, 7}); + cout << "Enter your name: "; + SetConsoleCursorPosition(h, {64, 7}); + cout << " "; + SetConsoleCursorPosition(h, {64, 7}); + cin.getline(Player.name, 200); + } + + // ══════════════════════════════════Breakout════════════════════════════════════ +} +void help() +{ + setColor(7); + HideCursor(false); + string menu[30][80]; + for (int H = 0; H < 30; H++) + { + for (int S = 0; S < 80; S++) + { + menu[H][S] = " "; + } + } + menu[0][0] = "╔"; + menu[0][79] = "╗"; + menu[29][0] = "╚"; + menu[29][79] = "╝"; + for (int i = 1; i < 29; i++) + { + menu[i][0] = "║"; + menu[i][79] = "║"; + } + for (int i = 1; i < 79; i++) + { + menu[0][i] = "═"; + menu[29][i] = "═"; + } + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(h, {0, 5}); + for (int i = 0; i < 30; i++) + { + cout << setw(45) << ""; + for (int j = 0; j < 80; j++) + { + cout << menu[i][j]; + } + cout << endl; + } + SetConsoleCursorPosition(h, {47, 7}); + cout << "\033[38;5;215m" << "1.Use " << "\033[38;5;11m" << "W/S" << "\033[38;5;215m" << " to move between options."; + SetConsoleCursorPosition(h, {47, 9}); + cout << "\033[38;5;215m" << "1.Use " << "\033[38;5;11m" << "A/D" << "\033[38;5;215m" << " to move the Paddle."; + SetConsoleCursorPosition(h, {47, 11}); + cout << "\033[38;5;215m" << "2.Press " << "\033[38;5;141m" << "Backspace" << "\033[38;5;215m" << " to back from loadGame menu."; + SetConsoleCursorPosition(h, {47, 14}); + cout << "\033[38;5;33mB\033[38;5;82mR\033[38;5;51mI\033[38;5;196mI\033[38;5;201mK\033[38;5;226ms\033[38;5;215m:"; + SetConsoleCursorPosition(h, {47, 16}); + cout << "\033[38;5;33m1.Hard Brick: These bricks take two hits to break."; + SetConsoleCursorPosition(h, {47, 18}); + cout << "\033[38;5;196m2.TNT Brick: explode and destroy nearby bricks"; + SetConsoleCursorPosition(h, {47, 20}); + cout << "\033[38;5;226m3.Golden brick: grant extra points when destroyed"; + SetConsoleCursorPosition(h, {47, 22}); + cout << "\033[38;5;215m4.Other colors are just for your eyes:)"; + cout << "\033[0m"; + _getch(); +} diff --git a/menu.hpp b/menu.hpp new file mode 100644 index 0000000..0d06936 --- /dev/null +++ b/menu.hpp @@ -0,0 +1,17 @@ +#ifndef MENU_HPP +#define MENU_HPP +#include +struct player +{ + char name[200]; + char date[80]; + char time[80]; + int life; + int score; + bool isActive; +}; +extern int option; +void menu(); +void newGame(); +void help(); +#endif \ No newline at end of file diff --git a/menu.jpg b/menu.jpg new file mode 100644 index 0000000..f370d9d Binary files /dev/null and b/menu.jpg differ diff --git a/name.jpg b/name.jpg new file mode 100644 index 0000000..73b271c Binary files /dev/null and b/name.jpg differ diff --git a/pause.jpg b/pause.jpg new file mode 100644 index 0000000..abd5ce3 Binary files /dev/null and b/pause.jpg differ diff --git a/scores.jpg b/scores.jpg new file mode 100644 index 0000000..d7be4fd Binary files /dev/null and b/scores.jpg differ