Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
8.2 kB
4
Indexable
Never
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <SDL2/SDL_image.h>

// Screen dimensions
const int SCREEN_WIDTH = 1200;
const int SCREEN_HEIGHT = 600;

// Player dimensions
const int PLAYER_WIDTH = 50;
const int PLAYER_HEIGHT = 100;

// Jumping variables
const int JUMP_HEIGHT = 10000;

// Player speeds
const int PLAYER_SPEED = 10;

// Ball dimensions
const int BALL_SIZE = 20;

// Ball speed
const float BALL_SPEED = 5.0f;

// Background image
SDL_Texture *backgroundTexture = NULL;

// Player struct
typedef struct
{
    int x;
    int y;
    int velocity_y;
    int remaining_jumps;
    bool jumping;
} Player;

// Ball struct
typedef struct
{
    float x;
    float y;
    float velocity_x;
    float velocity_y;
} Ball;

// Initialize SDL and create a window
bool init(SDL_Window **window, SDL_Renderer **renderer)
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
        return false;
    }

    *window = SDL_CreateWindow("Two Players", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (*window == NULL)
    {
        printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
        return false;
    }

    *renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_ACCELERATED);
    if (*renderer == NULL)
    {
        printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError());
        return false;
    }

    return true;
}

// Load background image
bool loadBackground(SDL_Renderer *renderer)
{
    SDL_Surface *backgroundSurface = IMG_Load("background.jpg");
    if (backgroundSurface == NULL)
    {
        printf("Unable to load background image! SDL_Image Error: %s\n", IMG_GetError());
        return false;
    }

    backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface);
    if (backgroundTexture == NULL)
    {
        printf("Unable to create texture from background image! SDL Error: %s\n", SDL_GetError());
        return false;
    }

    SDL_FreeSurface(backgroundSurface);
    return true;
}

// Draw a player
void drawPlayer(SDL_Renderer *renderer, Player *player, Uint8 red, Uint8 green, Uint8 blue)
{
    SDL_SetRenderDrawColor(renderer, red, green, blue, 255);
    SDL_Rect playerRect = {player->x, player->y, PLAYER_WIDTH, PLAYER_HEIGHT};
    SDL_RenderFillRect(renderer, &playerRect);
}

// Draw the ball
void drawBall(SDL_Renderer *renderer, Ball *ball)
{
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_Rect ballRect = {(int)ball->x, (int)ball->y, BALL_SIZE, BALL_SIZE};
    SDL_RenderFillRect(renderer, &ballRect);
}

// Check for Collision
bool checkCollision(int x1, int y1, int x2, int y2, int width, int height)
{
    return (x1 < x2 + width &&
            x1 + PLAYER_WIDTH > x2 &&
            y1 < y2 + height &&
            y1 + PLAYER_HEIGHT > y2);
}

void updatePlayerPosition(Player *player)
{
    if (player->jumping)
    {
        player->y += player->velocity_y;
        player->velocity_y += 1;
        if (player->y >= SCREEN_HEIGHT - PLAYER_HEIGHT)
        {
            player->y = SCREEN_HEIGHT - PLAYER_HEIGHT;
            player->jumping = false;
            player->remaining_jumps = 2;
        }
    }
}

void updateBallPosition(Ball *ball)
{
    ball->x += ball->velocity_x;
    ball->y += ball->velocity_y;

    // Reflect the ball if it hits the screen boundaries
    if (ball->x <= 0 || ball->x + BALL_SIZE >= SCREEN_WIDTH)
    {
        ball->velocity_x = -ball->velocity_x;
    }

    if (ball->y <= 0 || ball->y + BALL_SIZE >= SCREEN_HEIGHT)
    {
        ball->velocity_y = -ball->velocity_y;
    }
}

int main(int argc, char *argv[])
{
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;

    if (!init(&window, &renderer))
    {
        return 1;
    }

    if (!loadBackground(renderer))
    {
        return 1;
    }

    Player player1 = {100, SCREEN_HEIGHT - PLAYER_HEIGHT, 0, 2, false};
    Player player2 = {650, SCREEN_HEIGHT - PLAYER_HEIGHT, 0, 2, false};

    Ball ball = {SCREEN_WIDTH / 2 - BALL_SIZE / 2, SCREEN_HEIGHT / 2 - BALL_SIZE / 2, BALL_SPEED, BALL_SPEED};

    bool quit = false;
    SDL_Event e;

    while (!quit)
    {
        // Uint64 start = SDL_GetPerformanceCounter();

        while (SDL_PollEvent(&e) != 0)
        {
            if (e.type == SDL_QUIT)
            {
                quit = true;
            }

            if (e.type == SDL_KEYDOWN)
            {
                // Player 1 jump
                if (e.key.keysym.sym == SDLK_w)
                {
                    if (player1.remaining_jumps > 0)
                    {
                        player1.jumping = true;
                        player1.velocity_y = -20;
                        player1.remaining_jumps--;
                    }
                }

                // Player 2 jump
                if (e.key.keysym.sym == SDLK_UP)
                {
                    if (player2.remaining_jumps > 0)
                    {
                        player2.jumping = true;
                        player2.velocity_y = -20;
                        player2.remaining_jumps--;
                    }
                }
            }
        }

        updatePlayerPosition(&player1);
        updatePlayerPosition(&player2);
        updateBallPosition(&ball);

        while (SDL_PollEvent(&e) != 0)
        {
            if (e.type == SDL_QUIT)
            {
                quit = true;
            }
        }

        const Uint8 *currentKeyStates = SDL_GetKeyboardState(NULL);

        if (checkCollision(player1.x, player1.y, ball.x, ball.y, PLAYER_WIDTH, PLAYER_HEIGHT))
        {
            ball.velocity_x = -ball.velocity_x;
        }

        if (checkCollision(player2.x, player2.y, ball.x, ball.y, PLAYER_WIDTH, PLAYER_HEIGHT))
        {
            ball.velocity_x = -ball.velocity_x;
        }

        if (checkCollision(player1.x, player1.y, player2.x, player2.y, PLAYER_WIDTH, PLAYER_HEIGHT))
        {
            if (player1.x < player2.x)
            {
                player1.x--;
                player2.x++;
            }
            else
            {
                player1.x++;
                player2.x--;
            }
        }
        else
        {
            // Player 1 movement
            if (currentKeyStates[SDL_SCANCODE_A])
            {
                player1.x -= PLAYER_SPEED;
            }
            if (currentKeyStates[SDL_SCANCODE_D])
            {
                player1.x += PLAYER_SPEED;
            }

            // Player 2 movement
            if (currentKeyStates[SDL_SCANCODE_LEFT])
            {
                player2.x -= PLAYER_SPEED;
            }
            if (currentKeyStates[SDL_SCANCODE_RIGHT])
            {
                player2.x += PLAYER_SPEED;
            }

            // Keep players within the screen boundaries
            if (player1.x < 0)
            {
                player1.x = 0;
            }
            if (player1.x > SCREEN_WIDTH - PLAYER_WIDTH)
            {
                player1.x = SCREEN_WIDTH - PLAYER_WIDTH;
            }

            if (player2.x < 0)
            {
                player2.x = 0;
            }
            if (player2.x > SCREEN_WIDTH - PLAYER_WIDTH)
            {
                player2.x = SCREEN_WIDTH - PLAYER_WIDTH;
            }
        }

        // Clear the screen
        SDL_RenderClear(renderer);

        // Draw the background
        SDL_RenderCopy(renderer, backgroundTexture, NULL, NULL);

        // Draw Player 1 (red rectangle)
        drawPlayer(renderer, &player1, 255, 0, 0);

        // Draw Player 2 (blue rectangle)
        drawPlayer(renderer, &player2, 0, 0, 255);

        // Draw the ball
        drawBall(renderer, &ball);

        // Update the screen
        SDL_RenderPresent(renderer);

        //Uint64 end = SDL_GetPerformanceCounter();

        //float elapsedMS = (end - start) / (float)SDL_GetPerformanceFrequency() * 1000.0f;

        // Cap to 60 FPS
        //SDL_Delay((int)(16.666f - elapsedMS));
    }

    // Cleanup and exit
    SDL_DestroyTexture(backgroundTexture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}