1563 lines
48 KiB
C++
1563 lines
48 KiB
C++
#include "game.hpp"
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <conio.h>
|
|
#include <windows.h>
|
|
#include <chrono>
|
|
#include <ctime>
|
|
#include <thread>
|
|
#include <iomanip>
|
|
#include <fstream>
|
|
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<char *>(&temp), sizeof(player));
|
|
// file.read(reinterpret_cast<char *>(&Ball), sizeof(ball));
|
|
// file.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
// file.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
// size_t len;
|
|
// file.read(reinterpret_cast<char *>(&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<std::chrono::milliseconds>(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::milliseconds>(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<std::chrono::milliseconds>(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::milliseconds>(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<char *>(&p), sizeof(player));
|
|
fOut.write(reinterpret_cast<char *>(&Ball), sizeof(ball));
|
|
|
|
fOut.write(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len = Paddle.paddleChar.size();
|
|
fOut.write(reinterpret_cast<char *>(&len), sizeof(len));
|
|
fOut.write(Paddle.paddleChar.c_str(), len);
|
|
|
|
fOut.write(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&bricks), sizeof(brick) * brickCol * brickRow);
|
|
fOut.write(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
fOut.write(reinterpret_cast<char *>(&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<char *>(&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<char *>(&Ball), sizeof(ball));
|
|
|
|
file.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len;
|
|
file.read(reinterpret_cast<char *>(&len), sizeof(len)); // خواندن طول
|
|
Paddle.paddleChar.resize(len); // آمادهسازی فضا برای استرینگ
|
|
file.read(&Paddle.paddleChar[0], len); // خواندن متن
|
|
|
|
file.read(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&bricks), sizeof(brick) * brickCol * brickRow);
|
|
file.read(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&normalCount), sizeof(int));
|
|
file.seekp(pos);
|
|
file.write(reinterpret_cast<char *>(&Player), sizeof(player));
|
|
break;
|
|
}
|
|
file.read(reinterpret_cast<char *>(&Ball), sizeof(ball));
|
|
file.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len;
|
|
file.read(reinterpret_cast<char *>(&len), sizeof(len)); // خواندن طول
|
|
Paddle.paddleChar.resize(len); // آمادهسازی فضا برای استرینگ
|
|
file.read(&Paddle.paddleChar[0], len); // خواندن متن
|
|
|
|
file.read(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&bricks), sizeof(brick) * brickCol * brickRow);
|
|
file.read(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&normalCount), sizeof(int));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (count < index)
|
|
{
|
|
file.read(reinterpret_cast<char *>(&temp), sizeof(player));
|
|
if (temp.isActive == false)
|
|
{
|
|
count++;
|
|
}
|
|
file.read(reinterpret_cast<char *>(&Ball), sizeof(ball));
|
|
file.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len;
|
|
file.read(reinterpret_cast<char *>(&len), sizeof(len)); // خواندن طول
|
|
Paddle.paddleChar.resize(len); // آمادهسازی فضا برای استرینگ
|
|
file.read(&Paddle.paddleChar[0], len); // خواندن متن
|
|
|
|
file.read(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&bricks), sizeof(brick) * brickCol * brickRow);
|
|
file.read(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&normalCount), sizeof(int));
|
|
}
|
|
while (file.read(reinterpret_cast<char *>(&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<char *>(&Ball), sizeof(ball));
|
|
|
|
file.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len;
|
|
file.read(reinterpret_cast<char *>(&len), sizeof(len)); // خواندن طول
|
|
Paddle.paddleChar.resize(len); // آمادهسازی فضا برای استرینگ
|
|
file.read(&Paddle.paddleChar[0], len); // خواندن متن
|
|
|
|
file.read(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&bricks), sizeof(brick) * brickCol * brickRow);
|
|
file.read(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&normalCount), sizeof(int));
|
|
file.seekp(pos);
|
|
file.write(reinterpret_cast<char *>(&Player), sizeof(player));
|
|
break;
|
|
}
|
|
file.read(reinterpret_cast<char *>(&Ball), sizeof(ball));
|
|
file.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len;
|
|
file.read(reinterpret_cast<char *>(&len), sizeof(len)); // خواندن طول
|
|
Paddle.paddleChar.resize(len); // آمادهسازی فضا برای استرینگ
|
|
file.read(&Paddle.paddleChar[0], len); // خواندن متن
|
|
|
|
file.read(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&bricks), (sizeof(brick) * brickCol * brickRow));
|
|
file.read(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
file.read(reinterpret_cast<char *>(&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<char *>(&temp), sizeof(player)))
|
|
{
|
|
if (temp.isActive == false)
|
|
{
|
|
loadedPlayer[playerCount] = temp;
|
|
playerCount++;
|
|
}
|
|
fIn.read(reinterpret_cast<char *>(&Ball), sizeof(ball));
|
|
fIn.read(reinterpret_cast<char *>(&Paddle.width), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&Paddle.x), sizeof(int));
|
|
size_t len;
|
|
fIn.read(reinterpret_cast<char *>(&len), sizeof(len)); // خواندن طول
|
|
Paddle.paddleChar.resize(len); // آمادهسازی فضا برای استرینگ
|
|
fIn.read(&Paddle.paddleChar[0], len); // خواندن متن
|
|
|
|
fIn.read(reinterpret_cast<char *>(&brickCol), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&brickRow), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&bricks), sizeof(brick) * brickCol * brickRow);
|
|
fIn.read(reinterpret_cast<char *>(&Broken), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&goldenCount), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&TNTCount), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&HardCount), sizeof(int));
|
|
fIn.read(reinterpret_cast<char *>(&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);
|
|
} |