Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <vector>
- #include <cmath>
- #include <ctime>
- #include <algorithm> // Include this header for std::min and std::max
- #define WIN_WIDTH 800
- #define WIN_HEIGHT 600
- // Add with other global variables
- bool keyStates[256] = { false }; // Track key states
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- void DrawTriangle(HDC hdc, POINT pts[], int x, int y, double angle);
- void DrawAsteroid(HDC hdc, POINT pts[], int x, int y, double angle);
- bool CheckCollision(POINT player[], POINT asteroid[], int px, int py, int ax, int ay);
- void MoveAsteroids();
- void ShootBullet();
- void DrawBullet(HDC hdc, int x, int y);
- bool CheckBulletCollision(int bx, int by);
- bool DoLinesIntersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
- int Direction(int x1, int y1, int x2, int y2, int x3, int y3);
- bool OnSegment(int x1, int y1, int x2, int y2, int x3, int y3);
- bool PointInPolygon(int px, int py, POINT polygon[], int ox, int oy);
- void GenerateAsteroids();
- void SpawnNewAsteroid();
- void UpdatePlayerMovement();
- struct Asteroid {
- int x, y;
- double angle;
- POINT shape[8];
- };
- struct Bullet {
- int x, y;
- double angle;
- };
- std::vector<Asteroid> asteroids;
- std::vector<Bullet> bullets;
- POINT player[3] = { {0, -30}, {20, 20}, {-20, 20} };
- int playerX = WIN_WIDTH / 2, playerY = WIN_HEIGHT / 2;
- double playerAngle = 0;
- int score = 0;
- int lives = 3;
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- WNDCLASSEX wcex;
- HWND hwnd;
- MSG msg;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wcex.lpszMenuName = NULL;
- wcex.lpszClassName = TEXT("Asteroids");
- wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- RegisterClassEx(&wcex);
- hwnd = CreateWindow(TEXT("Asteroids"), TEXT("Asteroids"), WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, WIN_WIDTH, WIN_HEIGHT, NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, nCmdShow);
- UpdateWindow(hwnd);
- srand(static_cast<unsigned int>(time(0)));
- GenerateAsteroids();
- // Main game loop
- // Then modify the main game loop in WinMain:
- while (true) {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT) break;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else {
- UpdatePlayerMovement(); // Add this line
- // Add this collision check right after
- for (auto& ast : asteroids) {
- if (CheckCollision(player, ast.shape, playerX, playerY, ast.x, ast.y)) {
- lives--;
- if (lives <= 0) {
- MessageBox(hwnd, TEXT("Game Over!"), TEXT("Asteroids"), MB_OK);
- PostQuitMessage(0);
- }
- playerX = WIN_WIDTH / 2;
- playerY = WIN_HEIGHT / 2;
- playerAngle = 0;
- // Reset movement
- memset(keyStates, 0, sizeof(keyStates));
- }
- }
- // Add random asteroid spawning
- if (rand() % 100 < 2) { // 2% chance each frame to spawn a new asteroid
- SpawnNewAsteroid();
- }
- MoveAsteroids();
- for (auto it = bullets.begin(); it != bullets.end();) {
- it->x += 10 * cos(it->angle * 3.14159 / 180);
- it->y += 10 * sin(it->angle * 3.14159 / 180);
- if (CheckBulletCollision(it->x, it->y)) {
- it = bullets.erase(it);
- }
- else {
- ++it;
- }
- }
- InvalidateRect(hwnd, NULL, TRUE);
- Sleep(16); // ~60 FPS
- }
- }
- return (int)msg.wParam;
- }
- /* LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- HDC hdc;
- PAINTSTRUCT ps;
- RECT rect;
- static TCHAR scoreText[50];
- switch (msg) {
- case WM_PAINT:
- {
- hdc = BeginPaint(hwnd, &ps);
- GetClientRect(hwnd, &rect);
- // Clear screen
- //FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1));
- // Replace the FillRect line in WM_PAINT
- HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
- FillRect(hdc, &rect, blackBrush);
- DeleteObject(blackBrush);
- // Draw player
- DrawTriangle(hdc, player, playerX, playerY, playerAngle);
- // Draw asteroids
- for (auto& ast : asteroids) {
- DrawAsteroid(hdc, ast.shape, ast.x, ast.y, ast.angle);
- }
- // Draw bullets
- for (auto& bullet : bullets) {
- DrawBullet(hdc, bullet.x, bullet.y);
- }
- // Draw score and lives
- wsprintf(scoreText, TEXT("Score: %d Lives: %d"), score, lives);
- // Before TextOut call
- SetTextColor(hdc, RGB(255, 255, 255));
- SetBkMode(hdc, TRANSPARENT);
- TextOut(hdc, 10, 10, scoreText, lstrlen(scoreText));
- EndPaint(hwnd, &ps);
- }
- break;
- case WM_KEYDOWN:
- keyStates[wParam] = true;
- break; */ //USEFUL FUNCTION
- /* switch (wParam) { //deprecated code block
- case VK_LEFT:
- playerAngle -= 5;
- break;
- case VK_RIGHT:
- playerAngle += 5;
- break;
- case VK_UP:
- // Calculate movement from the tip of the triangle
- playerX += 5 * cos((playerAngle - 90) * 3.14159 / 180);
- playerY += 5 * sin((playerAngle - 90) * 3.14159 / 180);
- break;
- case VK_SPACE:
- ShootBullet();
- break;
- }
- */
- //USEFUL UNCOMMENT
- /*case WM_KEYUP:
- keyStates[wParam] = false;
- break;
- // Wrap around screen
- if (playerX < 0) playerX = WIN_WIDTH;
- if (playerX > WIN_WIDTH) playerX = 0;
- if (playerY < 0) playerY = WIN_HEIGHT;
- if (playerY > WIN_HEIGHT) playerY = 0;
- // Check for collisions
- for (auto& ast : asteroids) {
- if (CheckCollision(player, ast.shape, playerX, playerY, ast.x, ast.y)) {
- lives--;
- if (lives <= 0) {
- MessageBox(hwnd, TEXT("Game Over!"), TEXT("Asteroids"), MB_OK);
- PostQuitMessage(0);
- }
- playerX = WIN_WIDTH / 2;
- playerY = WIN_HEIGHT / 2;
- playerAngle = 0;
- }
- }
- InvalidateRect(hwnd, NULL, TRUE);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return 0;
- }*/
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- HDC hdc;
- PAINTSTRUCT ps;
- RECT rect;
- static TCHAR scoreText[50];
- switch (msg) {
- case WM_PAINT:
- {
- hdc = BeginPaint(hwnd, &ps);
- GetClientRect(hwnd, &rect);
- HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0));
- FillRect(hdc, &rect, blackBrush);
- DeleteObject(blackBrush);
- // Draw player
- DrawTriangle(hdc, player, playerX, playerY, playerAngle);
- // Draw asteroids
- for (auto& ast : asteroids) {
- DrawAsteroid(hdc, ast.shape, ast.x, ast.y, ast.angle);
- }
- // Draw bullets
- for (auto& bullet : bullets) {
- DrawBullet(hdc, bullet.x, bullet.y);
- }
- // Draw score and lives
- SetTextColor(hdc, RGB(255, 255, 255));
- SetBkMode(hdc, TRANSPARENT);
- wsprintf(scoreText, TEXT("Score: %d Lives: %d"), score, lives);
- TextOut(hdc, 10, 10, scoreText, lstrlen(scoreText));
- EndPaint(hwnd, &ps);
- }
- break;
- case WM_KEYDOWN:
- keyStates[wParam] = true;
- break;
- case WM_KEYUP:
- keyStates[wParam] = false;
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return 0;
- }
- void DrawTriangle(HDC hdc, POINT pts[], int x, int y, double angle) {
- POINT rotated[3];
- for (int i = 0; i < 3; ++i) {
- rotated[i].x = pts[i].x * cos(angle * 3.14159 / 180) - pts[i].y * sin(angle * 3.14159 / 180);
- rotated[i].y = pts[i].x * sin(angle * 3.14159 / 180) + pts[i].y * cos(angle * 3.14159 / 180);
- rotated[i].x += x;
- rotated[i].y += y;
- }
- // In DrawTriangle function, before Polygon call
- HPEN hotPinkPen = CreatePen(PS_SOLID, 1, RGB(255, 20, 147));
- HBRUSH hotPinkBrush = CreateSolidBrush(RGB(255, 20, 147));
- SelectObject(hdc, hotPinkPen);
- SelectObject(hdc, hotPinkBrush);
- Polygon(hdc, rotated, 3);
- DeleteObject(hotPinkPen);
- DeleteObject(hotPinkBrush);
- }
- void DrawAsteroid(HDC hdc, POINT pts[], int x, int y, double angle) {
- POINT rotated[8];
- for (int i = 0; i < 8; ++i) {
- rotated[i].x = pts[i].x * cos(angle * 3.14159 / 180) - pts[i].y * sin(angle * 3.14159 / 180);
- rotated[i].y = pts[i].x * sin(angle * 3.14159 / 180) + pts[i].y * cos(angle * 3.14159 / 180);
- rotated[i].x += x;
- rotated[i].y += y;
- }
- // In DrawAsteroid function, before Polygon call
- HPEN goldPen = CreatePen(PS_SOLID, 1, RGB(255, 215, 0));
- HBRUSH goldBrush = CreateSolidBrush(RGB(255, 215, 0));
- SelectObject(hdc, goldPen);
- SelectObject(hdc, goldBrush);
- Polygon(hdc, rotated, 8);
- DeleteObject(goldPen);
- DeleteObject(goldBrush);
- }
- void UpdatePlayerMovement() {
- if (keyStates[VK_LEFT]) {
- playerAngle -= 5;
- }
- if (keyStates[VK_RIGHT]) {
- playerAngle += 5;
- }
- if (keyStates[VK_UP]) {
- playerX += 5 * cos((playerAngle - 90) * 3.14159 / 180);
- playerY += 5 * sin((playerAngle - 90) * 3.14159 / 180);
- }
- // Add to UpdatePlayerMovement() function
- if (keyStates[VK_DOWN]) {
- playerX -= 5 * cos((playerAngle - 90) * 3.14159 / 180);
- playerY -= 5 * sin((playerAngle - 90) * 3.14159 / 180);
- }
- // Add to UpdatePlayerMovement() function
- static int shootCooldown = 0;
- if (keyStates[VK_SPACE] && shootCooldown == 0) {
- ShootBullet();
- shootCooldown = 10; // Adjust this value to control firing rate
- }
- if (shootCooldown > 0) {
- shootCooldown--;
- }
- // Wrap around screen
- if (playerX < 0) playerX = WIN_WIDTH;
- if (playerX > WIN_WIDTH) playerX = 0;
- if (playerY < 0) playerY = WIN_HEIGHT;
- if (playerY > WIN_HEIGHT) playerY = 0;
- }
- bool CheckCollision(POINT player[], POINT asteroid[], int px, int py, int ax, int ay) {
- for (int i = 0; i < 3; ++i) {
- int px1 = player[i].x + px;
- int py1 = player[i].y + py;
- int px2 = player[(i + 1) % 3].x + px;
- int py2 = player[(i + 1) % 3].y + py;
- for (int j = 0; j < 8; ++j) {
- int ax1 = asteroid[j].x + ax;
- int ay1 = asteroid[j].y + ay;
- int ax2 = asteroid[(j + 1) % 8].x + ax;
- int ay2 = asteroid[(j + 1) % 8].y + ay;
- // Check if the line segments intersect
- if (DoLinesIntersect(px1, py1, px2, py2, ax1, ay1, ax2, ay2)) {
- return true;
- }
- }
- }
- return false;
- }
- bool DoLinesIntersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
- // Calculate the direction of the lines
- int d1 = Direction(x3, y3, x4, y4, x1, y1);
- int d2 = Direction(x3, y3, x4, y4, x2, y2);
- int d3 = Direction(x1, y1, x2, y2, x3, y3);
- int d4 = Direction(x1, y1, x2, y2, x4, y4);
- // Check if the lines intersect
- if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) {
- return true;
- }
- // Check for collinear points
- if (d1 == 0 && OnSegment(x3, y3, x4, y4, x1, y1)) return true;
- if (d2 == 0 && OnSegment(x3, y3, x4, y4, x2, y2)) return true;
- if (d3 == 0 && OnSegment(x1, y1, x2, y2, x3, y3)) return true;
- if (d4 == 0 && OnSegment(x1, y1, x2, y2, x4, y4)) return true;
- return false;
- }
- int Direction(int x1, int y1, int x2, int y2, int x3, int y3) {
- return (x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1);
- }
- bool OnSegment(int x1, int y1, int x2, int y2, int x3, int y3) {
- int minX = x1 < x2 ? x1 : x2;
- int maxX = x1 > x2 ? x1 : x2;
- int minY = y1 < y2 ? y1 : y2;
- int maxY = y1 > y2 ? y1 : y2;
- if (minX <= x3 && x3 <= maxX && minY <= y3 && y3 <= maxY) {
- return true;
- }
- return false;
- }
- void MoveAsteroids() {
- for (auto& ast : asteroids) {
- ast.x += 2 * cos(ast.angle * 3.14159 / 180);
- ast.y += 2 * sin(ast.angle * 3.14159 / 180);
- // Wrap around screen
- if (ast.x < 0) ast.x = WIN_WIDTH;
- if (ast.x > WIN_WIDTH) ast.x = 0;
- if (ast.y < 0) ast.y = WIN_HEIGHT;
- if (ast.y > WIN_HEIGHT) ast.y = 0;
- }
- }
- void ShootBullet() {
- Bullet bullet;
- // Calculate the tip of the triangle (point[0] is the top vertex)
- bullet.x = playerX + player[0].x * cos(playerAngle * 3.14159 / 180)
- - player[0].y * sin(playerAngle * 3.14159 / 180);
- bullet.y = playerY + player[0].x * sin(playerAngle * 3.14159 / 180)
- + player[0].y * cos(playerAngle * 3.14159 / 180);
- // Adjust the bullet angle to match the ship's orientation
- bullet.angle = playerAngle - 90; // Subtract 90 degrees to align with the ship's nose
- bullets.push_back(bullet);
- }
- // Modified DrawBullet function for green bullets
- void DrawBullet(HDC hdc, int x, int y) {
- HPEN greenPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)); // Bright green
- HBRUSH greenBrush = CreateSolidBrush(RGB(0, 255, 0)); // Bright green
- SelectObject(hdc, greenPen);
- SelectObject(hdc, greenBrush);
- Ellipse(hdc, x - 4, y - 4, x + 4, y + 4);
- DeleteObject(greenPen);
- DeleteObject(greenBrush);
- }
- bool CheckBulletCollision(int bx, int by) {
- for (auto it = asteroids.begin(); it != asteroids.end();) {
- if (PointInPolygon(bx, by, it->shape, it->x, it->y)) {
- it = asteroids.erase(it);
- score += 10;
- return true;
- }
- else {
- ++it;
- }
- }
- return false;
- }
- bool PointInPolygon(int px, int py, POINT polygon[], int ox, int oy) {
- int i, j, nvert = 8;
- bool c = false;
- for (i = 0, j = nvert - 1; i < nvert; j = i++) {
- int polyX1 = polygon[i].x + ox;
- int polyY1 = polygon[i].y + oy;
- int polyX2 = polygon[j].x + ox;
- int polyY2 = polygon[j].y + oy;
- if (((polyY1 > py) != (polyY2 > py)) &&
- (px < (polyX2 - polyX1) * (py - polyY1) / (polyY2 - polyY1) + polyX1)) {
- c = !c;
- }
- }
- return c;
- }
- void GenerateAsteroids() {
- for (int i = 0; i < 5; ++i) {
- Asteroid ast;
- ast.x = rand() % WIN_WIDTH;
- ast.y = rand() % WIN_HEIGHT;
- ast.angle = rand() % 360;
- for (int j = 0; j < 8; ++j) {
- double angle = j * 45 * 3.14159 / 180;
- ast.shape[j].x = (rand() % 20 + 10) * cos(angle);
- ast.shape[j].y = (rand() % 20 + 10) * sin(angle);
- }
- asteroids.push_back(ast);
- }
- }
- void SpawnNewAsteroid() {
- Asteroid ast;
- // Randomly choose a side of the screen to spawn from
- int side = rand() % 4;
- switch (side) {
- case 0: // Top
- ast.x = rand() % WIN_WIDTH;
- ast.y = -30;
- break;
- case 1: // Right
- ast.x = WIN_WIDTH + 30;
- ast.y = rand() % WIN_HEIGHT;
- break;
- case 2: // Bottom
- ast.x = rand() % WIN_WIDTH;
- ast.y = WIN_HEIGHT + 30;
- break;
- case 3: // Left
- ast.x = -30;
- ast.y = rand() % WIN_HEIGHT;
- break;
- }
- ast.angle = rand() % 360;
- for (int j = 0; j < 8; ++j) {
- double angle = j * 45 * 3.14159 / 180;
- ast.shape[j].x = (rand() % 20 + 10) * cos(angle);
- ast.shape[j].y = (rand() % 20 + 10) * sin(angle);
- }
- asteroids.push_back(ast);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement