/* FlappyBird Copyright (C) 2024 Patrick_Pluto This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include bool sdlPipe(SDL_Rect *pipeRect, SDL_Rect *birdRect, SDL_Renderer *renderer, SDL_Texture *flappyBird, SDL_Texture *pipe) { // Render the pipes SDL_RenderCopy(renderer, pipe, nullptr, pipeRect); // Draw pipes and check for collisions. if (SDL_HasIntersection(pipeRect, birdRect)) { return true; } pipeRect->y += 1150; // move sprite for rendering the bottom pipe SDL_RenderCopyEx(renderer, pipe, nullptr, pipeRect, 0.0, nullptr, SDL_FLIP_VERTICAL); pipeRect->x -= 2; if (SDL_HasIntersection(pipeRect, birdRect)) { return true; } pipeRect->y -= 1150; // moving it back if (pipeRect->x <= -50) { std::random_device rd; // Obtain a random number from hardware std::mt19937 eng(rd()); // Seed the generator std::uniform_int_distribution<> distr(-950, -650); // Define the range // Generate the random number pipeRect->y = distr(eng); pipeRect->x = 800; } return false; } void setPipe(SDL_Rect* pipeRect, int offsetX) { // Create a random number generator std::random_device rd; // Obtain a random number from hardware std::mt19937 eng(rd()); // Seed the generator std::uniform_int_distribution<> distr(-950, -650); // Define the range pipeRect->x = offsetX; pipeRect->y = distr(eng); pipeRect->w = 64; pipeRect->h = 1024; } int main(int argc, char *argv[]) { // Initialize SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl; return 1; } // Create a window SDL_Window *window = SDL_CreateWindow("Flappy Bird", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN); if (window == nullptr) { std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl; SDL_Quit(); return 1; } // Create a renderer SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (renderer == nullptr) { std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl; SDL_DestroyWindow(window); SDL_Quit(); return 1; } // Load the sprite texture SDL_Texture *flappyBird = IMG_LoadTexture(renderer, "assets/bird.png"); if (flappyBird == nullptr) { std::cerr << "Failed to load texture! SDL_Error: " << SDL_GetError() << std::endl; // Handle error } SDL_Texture *pipe = IMG_LoadTexture(renderer, "assets/pipe.png"); if (pipe == nullptr) { std::cerr << "Failed to load texture! SDL_Error: " << SDL_GetError() << std::endl; // Handle error } // Sprite position and size SDL_Rect birdRect; birdRect.x = 300; // Initial x position birdRect.y = 200; // Initial y position birdRect.w = 48; // Width of the sprite birdRect.h = 36; // Height of the sprite // Create a random number generator std::random_device rd; // Obtain a random number from hardware std::mt19937 eng(rd()); // Seed the generator std::uniform_int_distribution<> distr(-950, -650); // Define the range SDL_Rect pipe1Rect; setPipe(&pipe1Rect, 650); SDL_Rect pipe2Rect; setPipe(&pipe2Rect, 850); SDL_Rect pipe3Rect; setPipe(&pipe3Rect, 1050); SDL_Rect pipe4Rect; setPipe(&pipe4Rect, 1250); // Sprite Velocity double velocityY = 0; // Main loop flag bool quit = false; SDL_Event e; Uint32 frameStart; int frameTime; const int TARGET_FPS = 60; const int FRAME_DELAY = 1000 / TARGET_FPS; // Delay in milliseconds // Main loop while (!quit) { frameStart = SDL_GetTicks(); // Handle events while (SDL_PollEvent(&e) != 0) { // User requests quit if (e.type == SDL_QUIT) { quit = true; } if (e.type == SDL_KEYDOWN) { switch (e.key.keysym.sym) { case SDLK_SPACE: // Flap velocityY = -5; break; } } } velocityY += 0.25; birdRect.y += velocityY; // Clear the window with a color (e.g., white) SDL_SetRenderDrawColor(renderer, 63, 63, 255, 255); // White color SDL_RenderClear(renderer); // Set the color for the bottom part (green) SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); // Green color // Define the rectangle for the bottom part of the screen SDL_Rect bottomRect; bottomRect.x = 0; // Start from the left edge bottomRect.y = 550; // Start from the vertical position (adjust as needed) bottomRect.w = 800; // Width of the screen (adjust based on your window size) bottomRect.h = 50; // Height of the green area (adjust as needed) // Render the green rectangle SDL_RenderFillRect(renderer, &bottomRect); // Render the sprite SDL_RenderCopy(renderer, flappyBird, nullptr, &birdRect); quit = sdlPipe(&pipe1Rect, &birdRect, renderer, flappyBird, pipe); if (!quit) { quit = sdlPipe(&pipe2Rect, &birdRect, renderer, flappyBird, pipe); } if (!quit) { quit = sdlPipe(&pipe3Rect, &birdRect, renderer, flappyBird, pipe); } if (!quit) { quit = sdlPipe(&pipe4Rect, &birdRect, renderer, flappyBird, pipe); } // Present the renderer SDL_RenderPresent(renderer); frameTime = SDL_GetTicks() - frameStart; if (frameTime < FRAME_DELAY) { SDL_Delay(FRAME_DELAY - frameTime); } if (SDL_HasIntersection(&bottomRect, &birdRect)) { quit = true; } } // Clean up SDL_DestroyTexture(flappyBird); SDL_DestroyTexture(pipe); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }