Gra Arkanoid

0
#include<iostream>
#include<array>
#include<vector>
#include<thread>
#include<chrono>
#include<string>
#include<conio.h>
#include<random>

struct GameObject {
public:
	float X;
	float Y;
	std::vector<std::vector<std::string>> SPRITE;
	std::array<float, 2> Direction = { -1,-1 };
	float Multiplier = 1;
	GameObject(int x, int y,  std::vector<std::vector<std::string>> sprite) {
		X = x;
		Y = y;
		SPRITE = sprite;
	}
};
void SetMap(std::array<std::array<std::string, 20>, 20>& map,std::vector<GameObject>& objects) {
	map = { {
		{"#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"}
	} };
	for (int i = 0; i < objects.size(); i++) {
		for (int j = 0; j < objects[i].SPRITE.size(); j++) {
			for (int k = 0; k < objects[i].SPRITE[j].size(); k++) {
				map[std::floor(objects[i].Y) + j][std::floor(objects[i].X) + k] = objects[i].SPRITE[j][k];
			}
		}

	}
}
int Collision(GameObject& object1, GameObject& object2) {
	int return_id = -1;
	if (std::floor(object1.Y) >= std::floor(object2.Y) && std::floor(object1.Y) + object1.SPRITE.size() - 1 <= object2.Y + object2.SPRITE.size() - 1 or std::floor(object2.Y) >= std::floor(object1.Y) && std::floor(object2.Y) + object2.SPRITE.size() - 1 <= std::floor(object1.Y) + object1.SPRITE.size() - 1) {
		if (object1.X == object2.X + object2.SPRITE[0].size() - 1 + 1) {
			return_id = 0;
		}
		if (object1.X + object1.SPRITE[0].size() - 1 == object2.X + object2.SPRITE[0].size() - 1 - 1) {
			return_id = 1;
		}
	}
	if (object1.X >= object2.X && object1.X + object1.SPRITE[0].size() - 1 <= object2.X + object2.SPRITE[0].size() - 1 or object2.X >= object1.X && object2.X + object2.SPRITE[0].size() - 1 <= object1.X + object1.SPRITE[0].size() - 1) {
		if (std::floor(object1.Y) + object1.SPRITE.size() - 1 == std::floor(object2.Y) - 1 ) {
			return_id = 2;
		}
		if (std::floor(object1.Y) == std::floor(object2.Y)  + object2.SPRITE.size() - 1 + 1) {
			return_id = 3;
		}
	}
	if (object1.X + object1.SPRITE[0].size() - 1 + object1.Direction[0] == object2.X && std::floor(object1.Y) + object1.SPRITE.size() - 1 + object1.Direction[1] == std::floor(object2.Y) && object2.SPRITE[0].size() > 1 && return_id == -1) {
		return_id = 4;
	}
	if (object1.X + object1.Direction[0] == object2.X + object2.SPRITE[0].size() - 1 && std::floor(object1.Y) + object1.SPRITE.size() - 1 + object1.Direction[1] == std::floor(object2.Y) && object2.SPRITE[0].size() > 1 && return_id == -1) {
		return_id = 5;
	}
	if (object1.X + object1.SPRITE[0].size() - 1 + object1.Direction[0] == object2.X && std::floor(object1.Y) + object1.SPRITE.size() - 1 + object1.Direction[1] == std::floor(object2.Y) + object2.SPRITE.size() - 1 && object2.SPRITE[0].size() > 1 && return_id == -1)  {
		return_id = 6;
	}
	if (object1.X + object1.Direction[0] == object2.X + object2.SPRITE[0].size() - 1 && std::floor(object1.Y) + object1.SPRITE.size() - 1 + object1.Direction[1] == std::floor(object2.Y) + object2.SPRITE.size() - 1 && object2.SPRITE[0].size() > 1 && return_id == -1) {
		return_id = 7;
	}
	return return_id;
	

}
void Draw(std::array<std::array<std::string, 20>, 20>& map) {
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			std::cout << map[i][j];
		}
		std::cout << "\n";
	}
	for (int i = 0; i < 21; i++) {
		std::cout << "\033[F";
	}
}
void Input(char& key) {
	for (;;) {
		key = _getch();
	}
}


void BallPhysics(std::vector<GameObject>& objects,std::chrono::steady_clock::time_point& ball_movment, std::vector<std::vector<std::string>>& PLATFORM_SPRITE,int& PLATFORM_COUNT, std::vector<std::vector<std::string>>& PLAYER_SPRITE) {
	for (int i = 0; i < objects.size(); i++) {
		if (i != 1) {
			if (Collision(objects[1], objects[i]) == 0 or Collision(objects[1], objects[i]) == 1) {

				objects[1].Direction = { -objects[1].Direction[0],objects[1].Direction[1] };
				
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT=PLATFORM_COUNT-1;
				}
				
				ball_movment -= std::chrono::milliseconds(1000);

			}
			if (Collision(objects[1], objects[i]) == 2 or Collision(objects[1], objects[i]) == 3) {
				

				objects[1].Direction = { objects[1].Direction[0],-objects[1].Direction[1] };
				if (objects[i].SPRITE == PLAYER_SPRITE && objects[i].Direction[0] != 0) {
					std::random_device device;
					std::uniform_int_distribution<int> dist(1,4);
					objects[1].Multiplier = dist(device);
					objects[1].Multiplier = 1 / objects[1].Multiplier;
					objects[1].Direction = { objects[i].Direction[0],objects[1].Direction[1] };
				}
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment -= std::chrono::milliseconds(1000);
				
			}
			if (Collision(objects[1], objects[i]) >= 4 && Collision(objects[1], objects[i]) <= 8) {
				objects[1].Direction = { -objects[1].Direction[0],-objects[1].Direction[1] };
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment -= std::chrono::milliseconds(1000);
				break;
			}
		}
	}
}


int main() {
	system("cls");
	int PLATFORM_COUNT = 12;
	char Key;
	std::array<std::array<std::string, 20>, 20> map;
	std::vector<GameObject> objects;
	std::vector<std::vector<std::string>> PLAYER_SPRITE = { {
		{"x","x","x","x"}
	} };
	std::vector<std::vector<std::string>> PLATFORM_SPRITE = { {
		{"[","-","]"},
	} };
	std::vector<std::vector<std::string>> WALL_SPRITE = { {
		{"#"}
	} };
	std::vector<std::vector<std::string>> BALL_SPRITE = { {
		{"+"}
	} };
	map = { {
		{"#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#"},
		{"#","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"}
	} };
	objects.push_back(GameObject(1, 19, PLAYER_SPRITE));
	objects.push_back(GameObject(8, 18, BALL_SPRITE));
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			if (map[i][j] == "#") {
				objects.push_back(GameObject(j, i, WALL_SPRITE));
			}
			if (map[i][j] == "[") {
				objects.push_back(GameObject(j, i, PLATFORM_SPRITE));
			}
			
		}
	}
	std::thread InputThread(Input, std::ref(Key));
	std::chrono::steady_clock::time_point ball_movment;
	std::chrono::steady_clock::time_point check_clock;
	for (;;) {
		std::chrono::steady_clock::time_point clock = std::chrono::steady_clock::now();
		SetMap(map, objects);
		Draw(map);		
		if (PLATFORM_COUNT <= 0) {
			for (int i = 0; i < 21; i++) {
				std::cout << "\n";
			}
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
			std::cout << "YOU WIN\n";
			exit(0);
		}
		BallPhysics(objects, ball_movment, PLATFORM_SPRITE, PLATFORM_COUNT, PLAYER_SPRITE);

		if (objects[1].Y >= 19) {
			for (int i = 0; i < 21; i++) {
				std::cout << "\n";
			}
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
			std::cout << "YOU LOSE\n";
			exit(0);
		}
		if (Key == 'd' && objects[0].X + objects[0].SPRITE[0].size() < 19) {
			objects[0].X += 1;
			Key = '.';
			objects[0].Direction = { 1,objects[0].Direction[1] };
			check_clock = clock;

		}
		else if (Key == 'a' && objects[0].X > 1) {
			objects[0].X -= 1;
			Key = '.';
			objects[0].Direction = { -1,objects[0].Direction[1] };
			check_clock = clock;

		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - check_clock).count() >= 1000) {
			objects[0].Direction = { 0,objects[0].Direction[1] };
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment).count() >= 200) {
			objects[1].Y += objects[1].Direction[1]*objects[1].Multiplier;
			objects[1].X += objects[1].Direction[0];
			ball_movment = clock;
		}

	}
	InputThread.detach();

}
0

ball_movment

To słowo się pisze movement.

1

Wybacz powierzchowność, ale… będzie widać, czemu, w trzecim punkcie:

  1. #include<conio.h>
    Na pewno byli lepsi kandydaci — może ncurses albo pdcurses?
  2. Jest jakiś powód, dla którego mapa to std::array<std::array<std::string, 20>, 20>, zamiast std::array<std::array<char, 20>, 20>, skoro i tak przechowuje tylko pojedyncze znaki? Mogłem czegoś nie zauważyć, bo (patrz punkt trzeci).
  3. (linijka 57., a nie jest ona tutaj jedyna…)
    Borze Szumiący, długość wiersza… Trzysta osiem znaków. Trzysta. Osiem. Znaków. Nie dość, że mi monitora brakło… dwóch monitorów mi brakło. Ja się zgadzam, że „klasyczne” ograniczenie do osiemdziesięciu znaków na wiersz jest już mocno przestarzałe i zaniżone… ale zachowajmy, proszę, umiar! Tak ze sto, sto dwadzieścia, to jeszcze przejdzie… a nie trzy razy tyle!

Zerknę na to jeszcze jutro (jak zapamiętam), ale dzisiaj w robocie się na spaghetti napatrzyłem i mi cierpliwości brakło…

0

a nie dałoby się mapy zapisać jako jeden wielki string?

"####################\n" + 
"#[-][-][-][-][-][-]#\n"

itp.
?
(nie pamiętam już czy to prawidłowa składnia w C++, ale chodzi o koncepcję, żeby zrobić jeden duży string. Byłoby czytelniej

3

Przez ten skaczący kursor niespecjalnie da się grać.
screenshot-20231201011021.gif

Masz też błąd przez który piłka wizualnie nigdy nie dotyka platformy gracza.
screenshot-20231201011454.gif

1

Dziękuję za krytykę. @several to jest akurat bląd z kolizją na osi Y. Wartości Y zaokrąglam i przez to kolizja jest niedokładna :/. @Althorion sorka za migrenę :( nie jestem jeszcze dobry w pisaniu kodu. Postaram się w sobotę poprawić kod używając twoich rad.

1

@Ktoś_Tam: Skoro robisz tą grę w konsoli, to używanie floatów (a co za tym idzie - zaokrąglanie) nie ma sensu.
Widoczny ruch i tak zachodzi między dwiema komórkami.

0

@Spine: oh nie zauważyłem tego,dzięki za pomoc.

1

Masz sporo "magicznych liczb", np. objects[1] i objects[0] się przewijają często. Wygląda to bardzo niejasno, trzeba przedrzeć się przez resztę kodu żeby zrozumieć, że aha pierwszy element to PLAYER, a drugi to BALL.

Natomiast w innym miejscu masz:

objects[i].SPRITE == PLAYER_SPRITE

Czyli w jednym miejscu znajdujesz obiekt PLAYER poprzez stały indeks 0, a w drugim sprawdzasz na podstawie SPRITE

Przyjmij albo jeden sposób, albo drugi i się go trzymaj, ale nie mieszaj obu. I zamiast ezoterycznego objects[1] zdefiniuj sobie chociaż nazwę dla tych indeksów, żeby było widać co to jest kiedy ktoś czyta kod:

#define PLAYER_INDEX 0
#define BALL_INDEX 1

Podobnie np. tutaj:

void BallPhysics(...) {
	for (int i = 0; i < objects.size(); i++) {
		if (i != 1) {
			...
		}
	}
}

Znowu, magiczny indeks 1 w if (i != 1) i trzeba się domyślić że chodzi o to, że pod tym indeksem jest BALL. I znowu przydałaby się chociaż nazwa dla tego indeksu i wtedy widziałbym if ( i != BALL_INDEX ) i od razu ma to więcej sensu.

int Collision(GameObject& object1, GameObject& object2) {
	int return_id = -1;
	if (...) {
		if (... {
			return_id = 0;
		}
		if (...) {
			return_id = 1;
		}
	}
	if (...) {
		if (... {
			return_id = 2;
		}
		if (...) {
			return_id = 3;
		}
	}
	if (...) {
		return_id = 4;
	}
	if (...) {
		return_id = 5;
	}
	if (...)  {
		return_id = 6;
	}
	if (...) {
		return_id = 7;
	}
	return return_id;
}

Po pierwsze, to return_id to jakaś magiczna liczba . Co to jest, co znaczy 0, co znaczy 1, co znaczy 2 itd.? Rozumiem że oznacza jakiś inny rodzaj kolizji, ale ja widzę tylko jakieś nic nie znaczące liczby od 0 do 7, oraz -1 który wydaje mi się że oznacza brak kolizji, ale brzmi bardziej jak błąd.

Znowu, przydałoby się to jakoś nazwać chociaż. Jakieś COLLISION_TOUCHING_X, COLLISION_OVERLAP_Y czy cokolwiek to ma być.

Ja nie wiem co to za kolizje i nie chcę się wczytywać, więc już ty musisz opisać co to jest.

I tutaj akurat moim zdaniem lepszy będzie enum niż #define bo wygląda na to, że te liczby nie są jakimiś indexami tylko służą do oznaczenia wyniku, więc nie ma znaczenia jaka wartość tam faktycznie stoi.

enum CollisionResult { NoCollision, CollisionTouchingX, CollisionOverlapX, ... }

Po drugie, masz wiele ifów z ogromnymi warunkami które nie mieszczą się na ekranie.

Kod powinno się czytać praktycznie jak słowny opis. Kod powinien podzielony na małe kawałki, w których na wierzchu mam ogólny zarys i mogę schodzić coraz niżej do większej szczegółowości. Innymi słowy, czytając kod funkcji chcę widzieć prosty do zrozumienia opis bez szczegółów, a szczegóły chcę mieć ukryte w oddzielnych funkcjach.

Czyli nie chcę czytać czegoś takiego:

Jeżeli podłoga ze współrzędnej Y obiektu 1 jest większa lub równa podłodze współrzędnej Y obiektu 2, oraz podłoga współrzędnej Y obiektu 1 dodana do rozmiaru pierwszego wymiaru tablicy sprite'a tego obiektu minus 1 jest mniejsza lub równa... to wtedy:
  Jeżeli współrzędna X obiektu 1 jest równa współrzędnej X obiektu 2 plus rozmiar drugiego wymiaru tablicy sprite'a obiektu 2 minus 1 plus 1, to zwróć 0
  W p.p. jeżeli współrzędna X obiektu 1 plus rozmiar sprite'a obiektu 1 minus 1 jest równa współrzędnej X obiektu dwa plus rozmiar sprite'a obiektu 2 minus 1 minus 1, to zwróć 1
W p.p. jeżeli współrzędna obiektu 1...

Sam musisz przyznać, że ciężko się to czyta.

Wolę czytać:

Jeżeli (przypadek kolizji 1) to...
Jeżeli (przypadek kolizji 2) to...

Albo:

Sprawdź przypadek kolizji 1
Sprawdź przypadek kolizji 2

I oddzielnie od tego mogę, ale nie muszę, przeczytać:

Przypadek kolizji 1:
Jeżeli współrzędna Y obiektu 1 jest coś tam coś tam oraz współrzędna X jest coś tam coś tam to...

I wtedy widzę ogólny zarys algorytmu działania tej funkcji i nie muszę się zastanawiać co robią te sprawdzenia współrzędnych.

Wydziel pls te wielkie warunki / ify do oddzielnych funkcji, na przykład chociaż coś podobnego do tego:

int Collision(GameObject& object1, GameObject& object2) {
	int return_id = -1;
	if (CollisionCase1(...)) {
		return_id = COLLISION_CASE_1;
	}
	if (CollisionCase2(...)) {
		return_id = COLLISION_CASE_2;
	}
	...
	return return_id;
}

bool CollisionCase1(...) {
	return std::floor(object1.Y) >= std::floor(object2.Y) && std::floor(object1.Y) + object1.SPRITE.size() - 1 <= object2.Y + object2.SPRITE.size() - 1 or ...
}

bool CollisionCase2(...) {
	return object1.X >= object2.X && object1.X + object1.SPRITE[0].size() - 1 <= object2.X + object2.SPRITE[0].size() - 1 or ...
}

Tylko oczywiście wymyśl jakieś lepsze nazwy :)

Przy czym te pod-warunki w warunkach, tj. object1.X >= object2.X && object1.X + object1.SPRITE[0].size() - 1 oraz std::floor(object1.Y) + object1.SPRITE.size() - 1 <= object2.Y + object2.SPRITE.size() - 1 itd. też dobrze by było oddzielić i nazwać.

Masz GameObject zdefiniowany jako jego położenie - współrzędne X, Y, oraz tablicę dwuwymiarową - jego SPRITE. Używasz rozmiaru tej tablicy SPRITE żeby sprawdzić zakres współrzędnych gdzie ten obiekt się znajduje, tj. jego krańcowe X oraz Y, przykładowo:

std::floor(object1.Y) + object1.SPRITE.size() - 1
oraz
object1.X + object1.SPRITE[0].size() - 1

To jest nie jasne co tu się dzieje i dlaczego dodajesz współrzędne do rozmiaru tablicy. Musisz też pamiętać że SPRITE.size() to Y, a SPRITE[0].size to X. IMO lepiej jakbyś dodał do GameObject pomocniczą funkcję na wyliczenie tego żeby nie śmiecić w kodzie tym magicznym dodawaniem, nawet coś takiego:

struct GameObject {
public:
	float X0; //zmienilem nazwe zeby bylo jasniej
	float Y0;
	...
    float X1() { return sprite[0].size; }
	float Y1() { return sprite.size; }
};

To też nie jest idealnie, bo X0 masz jako publiczną zmienną, a X1 jako metodę i jest to niespójne. Pomijam też tu kwestię używania floatów do współrzędnych.

Więcej nie mam już siły sprawdzać, mam nadzieję że kumasz ogólny problem czytelności

0

@dalbajob:

#include<iostream>
#include<array>
#include<vector>
#include<thread>
#include<chrono>
#include<string>
#include<random>
#include<conio.h>


enum OBJECT_INDEX {
	PLAYER_INDEX = 0,
	BALL_INDEX = 1
};
enum COLLISION_TYPE {
	NO_COLLISION = -1,
	COLLISION_LEFT = 0,
	COLLIISON_RIGHT = 1,
	COLLISION_DOWN = 2,
	COLLISION_UP = 3,
	COLLISION_LEFT_DOWN = 4,
	COLLISION_RIGHT_DOWN = 5,
	COLLISION_LEFT_UP = 6,
	COLLISION_RIGHT_UP = 7,

};

struct GameObject {
public:
	std::vector<std::vector<std::string>> SPRITE;
	std::array<int, 2> Direction = { -1,-1 };
	float Multiplier = 1;
	int X;
	int Y;
	int X1() {
		return X + SPRITE[0].size() - 1;
	}
	int Y1() {
		return Y + SPRITE.size() - 1;
	}
	GameObject(int x, int y,  std::vector<std::vector<std::string>> sprite) {
		X = x;
		Y = y;
		SPRITE = sprite;
	}
};
void SetMap(std::array<std::array<std::string, 20>, 20>& map,std::vector<GameObject>& objects) {
	map = { {
		{"#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"}
	} };
	for (int i = 0; i < objects.size(); i++) {
		for (int j = 0; j < objects[i].SPRITE.size(); j++) {
			for (int k = 0; k < objects[i].SPRITE[j].size(); k++) {
				map[objects[i].Y + j][objects[i].X + k] = objects[i].SPRITE[j][k];
			}
		}

	}
}
bool CollisionX(GameObject& object1, GameObject& object2) {
	return (object1.Y >= object2.Y && object1.Y1() <= object2.Y1() or object2.Y >= object1.Y && object2.Y1() <= object1.Y1());
}
bool CollisionY(GameObject& object1, GameObject& object2) {
	return (object1.X >= object2.X && object1.X1() <= object2.X1() or object2.X >= object1.X && object2.X1() <= object1.X1());
}
bool EdgeCollision(GameObject& object2, int& return_id) {
	return (object2.SPRITE[0].size() > 1 && return_id == NO_COLLISION);
}
bool CollisionLeft(GameObject& object1, GameObject& object2) {
	return (object1.X == object2.X1() + 1);
}
bool CollisionRight(GameObject& object1, GameObject& object2) {
	return (object1.X1() == object2.X1() - 1);
}
bool CollisionDown(GameObject& object1, GameObject& object2) {
	return (object1.Y1() == object2.Y - 1);
}
bool CollisionUp(GameObject& object1, GameObject& object2) {
	return (object1.Y1() == object2.Y + 1);
}
bool CollisionLeftDown(GameObject& object1, GameObject& object2) {
	return (object1.X1() + object1.Direction[0] == object2.X && object1.Y1() + object1.Direction[1] == object2.Y);
}
bool CollisionRightDown(GameObject& object1, GameObject& object2) {
	return (object1.X + object1.Direction[0] == object2.X1() && object1.Y1() + object1.Direction[1] == object2.Y);
}
bool CollisionLeftUp(GameObject& object1, GameObject& object2) {
	return (object1.X1() + object1.Direction[0] == object2.X && object1.Y1() + object1.Direction[1] == object2.Y1());
}
bool CollisionRightUp(GameObject& object1, GameObject& object2) {
	return (object1.X + object1.Direction[0] == object2.X1() && object1.Y1() + object1.Direction[1] == object2.Y1());
}


int Collision(GameObject& object1, GameObject& object2) {
	int return_id = NO_COLLISION;
	if (CollisionX(object1,object2) && CollisionLeft(object1,object2)) {
		return_id = COLLISION_LEFT;
	}
	if (CollisionX(object1, object2) && CollisionRight(object1, object2)) {
		return_id = COLLIISON_RIGHT;
	}
	if (CollisionY(object1, object2) && CollisionDown(object1,object2)) {
		return_id = COLLISION_DOWN;
	}
	if (CollisionY(object1, object2) && CollisionUp(object1, object2)) {
		return_id = COLLISION_UP;
	}
	if (CollisionLeftDown(object1,object2) && EdgeCollision(object2,return_id)) {
		return_id = COLLISION_LEFT_DOWN;
	}
	if (CollisionRightDown(object1, object2) && EdgeCollision(object2, return_id)) {
		return_id = COLLISION_RIGHT_DOWN;
	}
	if (CollisionLeftUp(object1, object2) && EdgeCollision(object2, return_id))  {
		return_id = COLLISION_LEFT_UP;
	}
	if (CollisionRightUp(object1, object2) && EdgeCollision(object2, return_id)) {
		return_id = COLLISION_RIGHT_UP;
	}
	return return_id;
	

}
void Draw(std::array<std::array<std::string, 20>, 20>& map) {
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			std::cout << map[i][j];
		}
		std::cout << "\n";
	}
	for (int i = 0; i < 21; i++) {
		std::cout << "\033[F";
	}
}
void Input(char& key) {
	for (;;) {
		key = _getch();
	}
}


void BallPhysics(std::vector<GameObject>& objects,std::chrono::steady_clock::time_point& ball_movment_X, std::chrono::steady_clock::time_point& ball_movment_Y, std::vector<std::vector<std::string>>& PLATFORM_SPRITE,int& PLATFORM_COUNT) {
	for (int i = 0; i < objects.size(); i++) {
		if (i != BALL_INDEX) {
			if (Collision(objects[BALL_INDEX], objects[i]) == COLLISION_LEFT or Collision(objects[BALL_INDEX], objects[i]) == COLLIISON_RIGHT) {

				objects[BALL_INDEX].Direction = { -objects[BALL_INDEX].Direction[0],objects[BALL_INDEX].Direction[1] };
				
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT=PLATFORM_COUNT-1;
				}
				
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);

			}
			if (Collision(objects[BALL_INDEX], objects[i]) == COLLISION_DOWN or Collision(objects[BALL_INDEX], objects[i]) == COLLISION_UP) {
				

				objects[BALL_INDEX].Direction = { objects[BALL_INDEX].Direction[0],-objects[BALL_INDEX].Direction[1] };
				
				if (i == PLAYER_INDEX) {
					std::random_device device;
					std::uniform_int_distribution<int> dist(1, 4);
					objects[BALL_INDEX].Multiplier = dist(device);
					if (objects[PLAYER_INDEX].Direction[0] != 0) {
						objects[BALL_INDEX].Direction = { objects[PLAYER_INDEX].Direction[0],objects[BALL_INDEX].Direction[1] };
					}
				}
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);
				
			}
			if (Collision(objects[BALL_INDEX], objects[i]) >= COLLISION_LEFT_DOWN && Collision(objects[BALL_INDEX], objects[i]) <= COLLISION_RIGHT_UP + 1) {
				objects[BALL_INDEX].Direction = { -objects[BALL_INDEX].Direction[0],-objects[BALL_INDEX].Direction[1] };
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);
				break;
			}
		}
	}
}


int main() {
	system("cls");
	int PLATFORM_COUNT = 12;
	char Key;
	std::array<std::array<std::string, 20>, 20> map;
	std::vector<GameObject> objects;
	std::vector<std::vector<std::string>> PLAYER_SPRITE = { {
		{"x","x","x","x"}
	} };
	std::vector<std::vector<std::string>> PLATFORM_SPRITE = { {
		{"[","-","]"},
	} };
	std::vector<std::vector<std::string>> WALL_SPRITE = { {
		{"#"}
	} };
	std::vector<std::vector<std::string>> BALL_SPRITE = { {
		{"+"}
	} };
	map = { {
		{"#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#"},
		{"#","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","[","-","]","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"},
		{"#"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ","#"}
	} };
	objects.push_back(GameObject(1, 19, PLAYER_SPRITE));
	objects.push_back(GameObject(8, 18, BALL_SPRITE));
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			if (map[i][j] == "#") {
				objects.push_back(GameObject(j, i, WALL_SPRITE));
			}
			if (map[i][j] == "[") {
				objects.push_back(GameObject(j, i, PLATFORM_SPRITE));
			}
			
		}
	}
	std::thread InputThread(Input, std::ref(Key));
	std::chrono::steady_clock::time_point ball_movment_X;
	std::chrono::steady_clock::time_point ball_movment_Y;
	std::chrono::steady_clock::time_point check_clock;
	for (;;) {
		std::chrono::steady_clock::time_point clock = std::chrono::steady_clock::now();
		SetMap(map, objects);
		Draw(map);		
		if (PLATFORM_COUNT <= 0) {
			for (int i = 0; i < 21; i++) {
				std::cout << "\n";
			}
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
			std::cout << "YOU WIN\n";
			exit(0);
		}
		BallPhysics(objects, ball_movment_X,ball_movment_Y, PLATFORM_SPRITE, PLATFORM_COUNT);

		if (objects[BALL_INDEX].Y >= 19) {
			for (int i = 0; i < 21; i++) {
				std::cout << "\n";
			}
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
			std::cout << "YOU LOSE\n";
			exit(0);
		}
		if (Key == 'd' && objects[PLAYER_INDEX].X + objects[PLAYER_INDEX].SPRITE[0].size() < 19) {
			objects[PLAYER_INDEX].X += 1;
			Key = '.';
			objects[PLAYER_INDEX].Direction = { 1,objects[PLAYER_INDEX].Direction[1] };
			check_clock = clock;

		}
		else if (Key == 'a' && objects[PLAYER_INDEX].X > 1) {
			objects[PLAYER_INDEX].X -= 1;
			Key = '.';
			objects[PLAYER_INDEX].Direction = { -1,objects[PLAYER_INDEX].Direction[1] };
			check_clock = clock;

		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - check_clock).count() >= 1000) {
			objects[PLAYER_INDEX].Direction = { 0,objects[PLAYER_INDEX].Direction[1] };
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment_Y).count() >= 500 / objects[BALL_INDEX].Multiplier) {
			objects[BALL_INDEX].Y += objects[BALL_INDEX].Direction[1];
			ball_movment_Y = clock;
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment_X).count() >= 500) {
			objects[BALL_INDEX].X += objects[BALL_INDEX].Direction[0];
			ball_movment_X = clock;
		}

	}
	InputThread.detach();

}

Coś w tym stylu? Planuje jeszcze dodać bibliotekę ncurses i zmienić std::array string na char

1

dalej masz magiczne liczby:

void Draw(std::array<std::array<std::string, 20>, 20>& map) {
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			std::cout << map[i][j];
		}
		std::cout << "\n";
	}
	for (int i = 0; i < 21; i++) {
		std::cout << "\033[F";
	}

Jak rozumiem 20 i 20 to szerokość i wysokość mapy, dlatego wszędzie się pojawia.

Jednak pomyśl, co zrobisz, jeśli będziesz chciał zmienić szerokość i wysokość mapy? Jak masz to na sztywno napisane, to wszędzie musiał będziesz zmieniać. Takie rzeczy najlepiej wydzielić do jakiejś stałej albo zmiennej.

1

Okej, to jest finalna wersja kodu. Myślę, że już poprawiłem, co miałem poprawić. Dodałem jeszcze ncurses, żeby nie używać conio.h i zmieniłem std::array string na char @Althorion. Dodatkowo nie ma już latającego kursora. @several

#include<array>
#include<vector>
#include<thread>
#include<chrono>
#include<string>
#include<random>
#include<curses.h>

#define MAP_WIDTH 20
#define MAP_HEIGHT 20

enum OBJECT_INDEX {
	PLAYER_INDEX = 0,
	BALL_INDEX = 1
};
enum COLLISION_TYPE {
	NO_COLLISION = -1,
	COLLISION_LEFT = 0,
	COLLIISON_RIGHT = 1,
	COLLISION_DOWN = 2,
	COLLISION_UP = 3,
	COLLISION_LEFT_DOWN = 4,
	COLLISION_RIGHT_DOWN = 5,
	COLLISION_LEFT_UP = 6,
	COLLISION_RIGHT_UP = 7,

};

struct GameObject {
public:
	std::vector<std::vector<char>> SPRITE;
	std::array<int, 2> Direction = { -1,-1 };
	float Multiplier = 1;
	int X;
	int Y;
	int X1() {
		return X + SPRITE[0].size() - 1;
	}
	int Y1() {
		return Y + SPRITE.size() - 1;
	}
	GameObject(int x, int y,  std::vector<std::vector<char>> sprite) {
		X = x;
		Y = y;
		SPRITE = sprite;
	}
};
void SetMap(std::array<std::array<char, MAP_WIDTH>, MAP_HEIGHT>& map,std::vector<GameObject>& objects) {
	map = { {
		{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'}
	} };
	for (int i = 0; i < objects.size(); i++) {
		for (int j = 0; j < objects[i].SPRITE.size(); j++) {
			for (int k = 0; k < objects[i].SPRITE[j].size(); k++) {
				if (objects[i].Y + j < MAP_HEIGHT && objects[i].X + k < MAP_WIDTH) {
					*(&map[objects[i].Y + j][objects[i].X + k]) = *(&objects[i].SPRITE[j][k]);

				}
				
			}
		}

	}
}
bool CollisionX(GameObject& object1, GameObject& object2) {
	return (object1.Y >= object2.Y && object1.Y1() <= object2.Y1() or object2.Y >= object1.Y && object2.Y1() <= object1.Y1());
}
bool CollisionY(GameObject& object1, GameObject& object2) {
	return (object1.X >= object2.X && object1.X1() <= object2.X1() or object2.X >= object1.X && object2.X1() <= object1.X1());
}
bool EdgeCollision(GameObject& object2, int& return_id) {
	return (object2.SPRITE[0].size() > 1 && return_id == NO_COLLISION);
}
bool CollisionLeft(GameObject& object1, GameObject& object2) {
	return (object1.X == object2.X1() + 1);
}
bool CollisionRight(GameObject& object1, GameObject& object2) {
	return (object1.X1() == object2.X1() - 1);
}
bool CollisionDown(GameObject& object1, GameObject& object2) {
	return (object1.Y1() == object2.Y - 1);
}
bool CollisionUp(GameObject& object1, GameObject& object2) {
	return (object1.Y1() == object2.Y + 1);
}
bool CollisionLeftDown(GameObject& object1, GameObject& object2) {
	return (object1.X1() + object1.Direction[0] == object2.X && object1.Y1() + object1.Direction[1] == object2.Y);
}
bool CollisionRightDown(GameObject& object1, GameObject& object2) {
	return (object1.X + object1.Direction[0] == object2.X1() && object1.Y1() + object1.Direction[1] == object2.Y);
}
bool CollisionLeftUp(GameObject& object1, GameObject& object2) {
	return (object1.X1() + object1.Direction[0] == object2.X && object1.Y1() + object1.Direction[1] == object2.Y1());
}
bool CollisionRightUp(GameObject& object1, GameObject& object2) {
	return (object1.X + object1.Direction[0] == object2.X1() && object1.Y1() + object1.Direction[1] == object2.Y1());
}


int Collision(GameObject& object1, GameObject& object2) {
	int return_id = NO_COLLISION;
	if (CollisionX(object1,object2) && CollisionLeft(object1,object2)) {
		return_id = COLLISION_LEFT;
	}
	if (CollisionX(object1, object2) && CollisionRight(object1, object2)) {
		return_id = COLLIISON_RIGHT;
	}
	if (CollisionY(object1, object2) && CollisionDown(object1,object2)) {
		return_id = COLLISION_DOWN;
	}
	if (CollisionY(object1, object2) && CollisionUp(object1, object2)) {
		return_id = COLLISION_UP;
	}
	if (CollisionLeftDown(object1,object2) && EdgeCollision(object2,return_id)) {
		return_id = COLLISION_LEFT_DOWN;
	}
	if (CollisionRightDown(object1, object2) && EdgeCollision(object2, return_id)) {
		return_id = COLLISION_RIGHT_DOWN;
	}
	if (CollisionLeftUp(object1, object2) && EdgeCollision(object2, return_id))  {
		return_id = COLLISION_LEFT_UP;
	}
	if (CollisionRightUp(object1, object2) && EdgeCollision(object2, return_id)) {
		return_id = COLLISION_RIGHT_UP;
	}
	return return_id;
}
void Draw(std::array<std::array<char, MAP_WIDTH>, MAP_HEIGHT>& map,WINDOW* win) {
	for (int i = 0; i < MAP_HEIGHT; i++) {
		for (int j = 0; j < MAP_WIDTH; j++) {
			addch(map[i][j]);
		}
		addch('\n');
	}

	wrefresh(win);
	clear();
}
void Input(char& key) {
	for (;;) {
		key = getch();
	}
}


void BallPhysics(std::vector<GameObject>& objects,std::chrono::steady_clock::time_point& ball_movment_X, std::chrono::steady_clock::time_point& ball_movment_Y, std::vector<std::vector<char>>& PLATFORM_SPRITE,int& PLATFORM_COUNT) {
	for (int i = 0; i < objects.size(); i++) {
		if (i != BALL_INDEX) {
			if (Collision(objects[BALL_INDEX], objects[i]) == COLLISION_LEFT or Collision(objects[BALL_INDEX], objects[i]) == COLLIISON_RIGHT) {

				objects[BALL_INDEX].Direction = { -objects[BALL_INDEX].Direction[0],objects[BALL_INDEX].Direction[1] };
				
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT=PLATFORM_COUNT-1;
				}
				
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);

			}
			if (Collision(objects[BALL_INDEX], objects[i]) == COLLISION_DOWN or Collision(objects[BALL_INDEX], objects[i]) == COLLISION_UP) {
				objects[BALL_INDEX].Direction = { objects[BALL_INDEX].Direction[0],-objects[BALL_INDEX].Direction[1] };
				if (i == PLAYER_INDEX) {
					std::random_device device;
					std::uniform_real_distribution<float> dist(0.5, 2);
					objects[BALL_INDEX].Multiplier = dist(device);
					if (objects[PLAYER_INDEX].Direction[0] != 0) {
						objects[BALL_INDEX].Direction = { objects[PLAYER_INDEX].Direction[0],objects[BALL_INDEX].Direction[1] };
					}
				}
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);
				
			}
			if (Collision(objects[BALL_INDEX], objects[i]) >= COLLISION_LEFT_DOWN && Collision(objects[BALL_INDEX], objects[i]) <= COLLISION_RIGHT_UP + 1) {
				objects[BALL_INDEX].Direction = { -objects[BALL_INDEX].Direction[0],-objects[BALL_INDEX].Direction[1] };
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);
				break;
			}
		}
	}
}


int main() {
	
	WINDOW *win = initscr();
	noecho();
	int PLATFORM_COUNT = 12;
	char Key;
	std::array<std::array<char, MAP_WIDTH>,MAP_HEIGHT > map;
	std::vector<GameObject> objects;
	std::vector<std::vector<char>> PLAYER_SPRITE = { {
		{'x','x','x','x'}
	} };
	std::vector<std::vector<char>> PLATFORM_SPRITE = { {
		{'[','-',']'},
	} };
	std::vector<std::vector<char>> WALL_SPRITE = { {
		{'#'}
	} };
	std::vector<std::vector<char>> BALL_SPRITE = { {
		{'+'}
	} };
	map = { {
		{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
		{'#','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'}
	} };
	objects.push_back(GameObject(1, 19, PLAYER_SPRITE));
	objects.push_back(GameObject(8, 18, BALL_SPRITE));
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			if (map[i][j] == '#') {
				objects.push_back(GameObject(j, i, WALL_SPRITE));
			}
			if (map[i][j] == '[') {
				objects.push_back(GameObject(j, i, PLATFORM_SPRITE));
			}
			
		}
	}
	std::thread InputThread(Input, std::ref(Key));
	InputThread.detach();
	std::chrono::steady_clock::time_point ball_movment_X;
	std::chrono::steady_clock::time_point ball_movment_Y;
	std::chrono::steady_clock::time_point check_clock;
	for (;;) {
		std::chrono::steady_clock::time_point clock = std::chrono::steady_clock::now();
		SetMap(map, objects);
		Draw(map,win);
		if (PLATFORM_COUNT <= 0) {
			clear();
			printw("YOU WIN\n");
			wrefresh(win);
			napms(1000);
			break;
		}
		BallPhysics(objects, ball_movment_X,ball_movment_Y, PLATFORM_SPRITE, PLATFORM_COUNT);

		if (objects[BALL_INDEX].Y >= MAP_HEIGHT - 1) {
			clear();
			printw("YOU LOSE\n");
			wrefresh(win);
			napms(1000);
			break;
		}
		if (Key == 'd' && objects[PLAYER_INDEX].X + objects[PLAYER_INDEX].SPRITE[0].size() < 19) {
			objects[PLAYER_INDEX].X += 1;
			Key = '.';
			objects[PLAYER_INDEX].Direction = { 1,objects[PLAYER_INDEX].Direction[1] };
			check_clock = clock;

		}
		else if (Key == 'a' && objects[PLAYER_INDEX].X > 1) {
			objects[PLAYER_INDEX].X -= 1;
			Key = '.';
			objects[PLAYER_INDEX].Direction = { -1,objects[PLAYER_INDEX].Direction[1] };
			check_clock = clock;

		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - check_clock).count() >= 1000) {
			objects[PLAYER_INDEX].Direction = { 0,objects[PLAYER_INDEX].Direction[1] };
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment_Y).count() >= 500 / objects[BALL_INDEX].Multiplier) {
			objects[BALL_INDEX].Y += objects[BALL_INDEX].Direction[1];
			ball_movment_Y = clock;
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment_X).count() >= 500) {
			objects[BALL_INDEX].X += objects[BALL_INDEX].Direction[0];
			ball_movment_X = clock;
		}

	}
	endwin();
}
2

O, i już jest dużo, dużo lepiej.

Dalsze uwagi:

  1. W C++ lepiej mieć stałą const, może nawet znaną w trakcie kompilacji constexpr, niż posługiwać się preprocesorem #define do deklarowania stałych — dzięki temu kompilator może za nas łatwiej pilnować typów, minimalizując szanse popełnienia błędów.
  2. COLLISION_TYPE zaczynający się od -1 wydaje się lekko dziwny, ale jak gdzieś się to później przydaje, to w porządku. Jak nie, to sugerowałbym zmianę, będzie (nieco) mniej zaskakujące dla czytających kod.
  3. Wielokrotnie reinicjalizujesz generator pseudolosowy (linijka 184.) w pętli (linijka 166.). To zazwyczaj nie jest dobrym rozwiązaniem — to ma być, co do zasady, front na systemowe źródło losowości, co często oznacza umiarkowanie duży czas inicjalizacji i ograniczony bandwidth.
  4. Kontynuacja punktu wyżej — używasz systemowego generatora pseudolosowego bezpośrednio (linijka 186.), w sytuacji, gdy potrzebujesz takiego wyniku często (w pętli). Z powodów jak wyżej, to nie jest, zazwyczaj, dobre rozwiązanie. Oczekiwałbym w programie zainicjalizowania jakiegoś PRNG poza tą funkcją, i wstrzyknięcia jej tego w parametrze jako zależności.
  5. Nazwa int PLATFORM_COUNT = 12; — pisana wielkimi literami — sugeruje, jakby to miała być stała… a nie jest.
  6. Chciałoby się trochę static_assertów (lub w ogóle assertów) pilnujących poprawności logiki — na przykład czy rozmiar map jest zgodny z MAP_WIDTH/MAP_HEIGHT.
  7. Wciąż trochę magicznych stałych — Direction[1], SPRITE[0].
0

@Althorion Okej, zachwile to poprawię :)

0

Dziękuje wszystkim za krytykę jeszcz raz. Oto (w końcu ;) ) ostateczna wersja kodu :D.

#include<array>
#include<vector>
#include<thread>
#include<chrono>
#include<string>
#include<random>
#include<curses.h>

const int MAP_WIDTH = 20;
const int MAP_HEIGHT = 20;

enum AXIS  {
	X_AXIS = 0,
	Y_AXIS = 1
};
enum OBJECT_INDEX {
	PLAYER_INDEX = 0,
	BALL_INDEX = 1
};
enum COLLISION_TYPE {
	NO_COLLISION = 0,
	COLLISION_LEFT = 1,
	COLLIISON_RIGHT = 2,
	COLLISION_DOWN = 3,
	COLLISION_UP = 4,
	COLLISION_LEFT_DOWN = 5,
	COLLISION_RIGHT_DOWN = 6,
	COLLISION_LEFT_UP = 7,
	COLLISION_RIGHT_UP = 8,

};

struct GameObject {
public:
	std::vector<std::vector<char>> SPRITE;
	std::array<int, 2> Direction = { -1,-1 };
	float Multiplier = 1;
	int X;
	int Y;
	int X1() {
		return X + SPRITE[0].size() - 1;
	}
	int Y1() {
		return Y + SPRITE.size() - 1;
	}
	GameObject(int x, int y,  std::vector<std::vector<char>> sprite) {
		X = x;
		Y = y;
		SPRITE = sprite;
	}
};
void SetMap(std::array<std::array<char, MAP_WIDTH>, MAP_HEIGHT>& map,std::vector<GameObject>& objects) {
	map = { {
		{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'}
	} };
	for (int i = 0; i < objects.size(); i++) {
		for (int j = 0; j < objects[i].SPRITE.size(); j++) {
			for (int k = 0; k < objects[i].SPRITE[j].size(); k++) {
				if (objects[i].Y + j < MAP_HEIGHT && objects[i].X + k < MAP_WIDTH) {
					*(&map[objects[i].Y + j][objects[i].X + k]) = *(&objects[i].SPRITE[j][k]);

				}
				
			}
		}

	}
}
bool CollisionX(GameObject& object1, GameObject& object2) {
	return (object1.Y >= object2.Y && object1.Y1() <= object2.Y1() or object2.Y >= object1.Y && object2.Y1() <= object1.Y1());
}
bool CollisionY(GameObject& object1, GameObject& object2) {
	return (object1.X >= object2.X && object1.X1() <= object2.X1() or object2.X >= object1.X && object2.X1() <= object1.X1());
}
bool EdgeCollision(GameObject& object2, int& return_id) {
	return (object2.X1() + 1 > 1 && return_id == NO_COLLISION);
}
bool CollisionLeft(GameObject& object1, GameObject& object2) {
	return (object1.X == object2.X1() + 1);
}
bool CollisionRight(GameObject& object1, GameObject& object2) {
	return (object1.X1() == object2.X1() - 1);
}
bool CollisionDown(GameObject& object1, GameObject& object2) {
	return (object1.Y1() == object2.Y - 1);
}
bool CollisionUp(GameObject& object1, GameObject& object2) {
	return (object1.Y1() == object2.Y + 1);
}
bool CollisionLeftDown(GameObject& object1, GameObject& object2) {
	return (object1.X1() + object1.Direction[X_AXIS] == object2.X && object1.Y1() + object1.Direction[Y_AXIS] == object2.Y);
}
bool CollisionRightDown(GameObject& object1, GameObject& object2) {
	return (object1.X + object1.Direction[X_AXIS] == object2.X1() && object1.Y1() + object1.Direction[Y_AXIS] == object2.Y);
}
bool CollisionLeftUp(GameObject& object1, GameObject& object2) {
	return (object1.X1() + object1.Direction[X_AXIS] == object2.X && object1.Y1() + object1.Direction[Y_AXIS] == object2.Y1());
}
bool CollisionRightUp(GameObject& object1, GameObject& object2) {
	return (object1.X + object1.Direction[X_AXIS] == object2.X1() && object1.Y1() + object1.Direction[Y_AXIS] == object2.Y1());
}


int Collision(GameObject& object1, GameObject& object2) {
	int return_id = NO_COLLISION;
	if (CollisionX(object1,object2) && CollisionLeft(object1,object2)) {
		return_id = COLLISION_LEFT;
	}
	if (CollisionX(object1, object2) && CollisionRight(object1, object2)) {
		return_id = COLLIISON_RIGHT;
	}
	if (CollisionY(object1, object2) && CollisionDown(object1,object2)) {
		return_id = COLLISION_DOWN;
	}
	if (CollisionY(object1, object2) && CollisionUp(object1, object2)) {
		return_id = COLLISION_UP;
	}
	if (CollisionLeftDown(object1,object2) && EdgeCollision(object2,return_id)) {
		return_id = COLLISION_LEFT_DOWN;
	}
	if (CollisionRightDown(object1, object2) && EdgeCollision(object2, return_id)) {
		return_id = COLLISION_RIGHT_DOWN;
	}
	if (CollisionLeftUp(object1, object2) && EdgeCollision(object2, return_id))  {
		return_id = COLLISION_LEFT_UP;
	}
	if (CollisionRightUp(object1, object2) && EdgeCollision(object2, return_id)) {
		return_id = COLLISION_RIGHT_UP;
	}
	return return_id;
}
void Draw(std::array<std::array<char, MAP_WIDTH>, MAP_HEIGHT>& map,WINDOW* win) {
	for (int i = 0; i < MAP_HEIGHT; i++) {
		for (int j = 0; j < MAP_WIDTH; j++) {
			addch(map[i][j]);
		}
		addch('\n');
	}

	wrefresh(win);
	clear();
}
void Input(char& key) {
	for (;;) {
		key = getch();
	}
}


void BallPhysics(std::vector<GameObject>& objects,std::chrono::steady_clock::time_point& ball_movment_X, std::chrono::steady_clock::time_point& ball_movment_Y, std::vector<std::vector<char>>& PLATFORM_SPRITE,int& PLATFORM_COUNT, std::random_device& device, std::uniform_real_distribution<float>& dist) {
	for (int i = 0; i < objects.size(); i++) {
		if (i != BALL_INDEX) {
			if (Collision(objects[BALL_INDEX], objects[i]) == COLLISION_LEFT or Collision(objects[BALL_INDEX], objects[i]) == COLLIISON_RIGHT) {

				objects[BALL_INDEX].Direction = { -objects[BALL_INDEX].Direction[X_AXIS],objects[BALL_INDEX].Direction[Y_AXIS] };
				
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT=PLATFORM_COUNT-1;
				}
				
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);

			}
			if (Collision(objects[BALL_INDEX], objects[i]) == COLLISION_DOWN or Collision(objects[BALL_INDEX], objects[i]) == COLLISION_UP) {
				objects[BALL_INDEX].Direction = { objects[BALL_INDEX].Direction[X_AXIS],-objects[BALL_INDEX].Direction[Y_AXIS] };
				if (i == PLAYER_INDEX) {
					objects[BALL_INDEX].Multiplier = dist(device);
					if (objects[PLAYER_INDEX].Direction[X_AXIS] != 0) {
						objects[BALL_INDEX].Direction = { objects[PLAYER_INDEX].Direction[X_AXIS],objects[BALL_INDEX].Direction[Y_AXIS] };
					}
				}
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);
				
			}
			if (Collision(objects[BALL_INDEX], objects[i]) >= COLLISION_LEFT_DOWN && Collision(objects[BALL_INDEX], objects[i]) <= COLLISION_RIGHT_UP + 1) {
				objects[BALL_INDEX].Direction = { -objects[BALL_INDEX].Direction[X_AXIS],-objects[BALL_INDEX].Direction[Y_AXIS] };
				if (objects[i].SPRITE == PLATFORM_SPRITE) {
					objects.erase(objects.begin() + i);
					PLATFORM_COUNT = PLATFORM_COUNT - 1;

				}
				ball_movment_X -= std::chrono::milliseconds(1000);
				ball_movment_Y -= std::chrono::milliseconds(1000);
				break;
			}
		}
	}
}


int main() {
	
	WINDOW *win = initscr();
	noecho();
	int Platform_count = 12;
	char Key;
	std::array<std::array<char, MAP_WIDTH>,MAP_HEIGHT > map;
	std::vector<GameObject> objects;
	std::random_device device;
	std::uniform_real_distribution<float> dist(0.5, 2);
	std::vector<std::vector<char>> PLAYER_SPRITE = { {
		{'x','x','x','x'}
	} };
	std::vector<std::vector<char>> PLATFORM_SPRITE = { {
		{'[','-',']'},
	} };
	std::vector<std::vector<char>> WALL_SPRITE = { {
		{'#'}
	} };
	std::vector<std::vector<char>> BALL_SPRITE = { {
		{'+'}
	} };
	map = { {
		{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
		{'#','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','[','-',']','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
		{'#','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','#'}
	} };
	objects.push_back(GameObject(1, 19, PLAYER_SPRITE));
	objects.push_back(GameObject(8, 18, BALL_SPRITE));
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < 20; j++) {
			if (map[i][j] == '#') {
				objects.push_back(GameObject(j, i, WALL_SPRITE));
			}
			if (map[i][j] == '[') {
				objects.push_back(GameObject(j, i, PLATFORM_SPRITE));
			}
			
		}
	}
	std::thread InputThread(Input, std::ref(Key));
	InputThread.detach();
	std::chrono::steady_clock::time_point ball_movment_X;
	std::chrono::steady_clock::time_point ball_movment_Y;
	std::chrono::steady_clock::time_point check_clock;
	for (;;) {
		std::chrono::steady_clock::time_point clock = std::chrono::steady_clock::now();
		SetMap(map, objects);
		Draw(map,win);
		if (Platform_count <= 0) {
			clear();
			printw("YOU WIN\n");
			wrefresh(win);
			napms(1000);
			break;
		}
		BallPhysics(objects, ball_movment_X,ball_movment_Y, PLATFORM_SPRITE, Platform_count,device,dist);

		if (objects[BALL_INDEX].Y >= MAP_HEIGHT - 1) {
			clear();
			printw("YOU LOSE\n");
			wrefresh(win);
			napms(1000);
			break;
		}
		if (Key == 'd' && objects[PLAYER_INDEX].X1() + 1 < 19) {
			objects[PLAYER_INDEX].X += 1;
			Key = '.';
			objects[PLAYER_INDEX].Direction = { 1,objects[PLAYER_INDEX].Direction[Y_AXIS] };
			check_clock = clock;

		}
		else if (Key == 'a' && objects[PLAYER_INDEX].X > 1) {
			objects[PLAYER_INDEX].X -= 1;
			Key = '.';
			objects[PLAYER_INDEX].Direction = { -1,objects[PLAYER_INDEX].Direction[Y_AXIS] };
			check_clock = clock;

		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - check_clock).count() >= 1000) {
			objects[PLAYER_INDEX].Direction = { 0,objects[PLAYER_INDEX].Direction[Y_AXIS] };
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment_Y).count() >= 500 / objects[BALL_INDEX].Multiplier) {
			objects[BALL_INDEX].Y += objects[BALL_INDEX].Direction[Y_AXIS];
			ball_movment_Y = clock;
		}
		if (std::chrono::duration_cast<std::chrono::milliseconds>(clock - ball_movment_X).count() >= 500) {
			objects[BALL_INDEX].X += objects[BALL_INDEX].Direction[X_AXIS];
			ball_movment_X = clock;
		}

	}
	endwin();
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1