FlappyBird/main.cpp
2024-09-09 07:59:43 +02:00

220 lines
5.9 KiB
C++

/*
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 <https://www.gnu.org/licenses/>.
*/
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
#include <random>
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
SDL_Rect *pipeRect[4];
int dist = 650;
for (int i = 0; i < 4; i++) {
pipeRect[i] = new SDL_Rect();
setPipe(pipeRect[i], dist);
dist += 210;
}
// 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);
for (int i = 0; i < 4; i++) {
quit = sdlPipe(pipeRect[i], &birdRect, renderer, flappyBird, pipe);
if (quit) {
break;
}
}
// 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;
}