#include #include #include "pong.h" Pong* Pong_init() { Pong *p = malloc(sizeof(Pong)); p->ball = Ball_init(PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, PONG_BALL_POSX); p->racketL = Racket_init(PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, PONG_RACKET_POSX, PONG_SCREEN_HEIGHT/2, SDL_SCANCODE_E, SDL_SCANCODE_D); if (p->racketL == NULL) { Ball_free(p->ball); free(p); return NULL; } p->racketR = Racket_init(PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, PONG_SCREEN_WIDTH - PONG_RACKET_POSX - RACKET_WIDTH, PONG_SCREEN_HEIGHT/2, SDL_SCANCODE_I, SDL_SCANCODE_K); if (p->racketR == NULL) { Ball_free(p->ball); Racket_free(p->racketL); free(p); return NULL; } p->window = SDL_CreateWindow( "Pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if( p->window == NULL ) { printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); Pong_free(p); return NULL; } p->renderer = SDL_CreateRenderer(p->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); p->screenSurface = SDL_GetWindowSurface( p->window ); SDL_FillRect( p->screenSurface, NULL, SDL_MapRGB( p->screenSurface->format, 0, 0, 0 ) ); SDL_UpdateWindowSurface( p->window ); return p; } void Pong_free(Pong *p) { SDL_DestroyRenderer(p->renderer); SDL_FreeSurface(p->screenSurface); SDL_DestroyWindow(p->window); Ball_free(p->ball); Racket_free(p->racketL); Racket_free(p->racketR); free(p); } void Pong_clear(Pong *p) { SDL_SetRenderDrawColor(p->renderer, 0, 0, 0, 255 ); SDL_RenderClear( p->renderer ); } int Pong_render(Pong *p, int start) { Pong_clear(p); int error = Ball_render(p->ball, p->renderer) + Racket_render(p->racketL, p->renderer) + Racket_render(p->racketR, p->renderer); if (!start) { Text *start_text = Text_init(50, 400, "Regular", 8); const char *start_text_str = "Press any key to begin..."; error += Text_render(start_text, p->renderer, start_text_str, 400, 50); Text_free(start_text); } if (error > 0) { return error; } SDL_RenderPresent(p->renderer); return 0; } void Ball_move(Ball *b, Pong *p) { b->posX += b->velX; if (Ball_collision(b, p->racketL) || Ball_collision(b, p->racketR)) { b->posX -= b->velX; b->velX = -b->velX; } if (b->posX < 0) { p->racketR->score->score++; Ball_reset(b, -1); } else if(b->posX + BALL_WIDTH > b->SCREEN_WIDTH) { p->racketL->score->score++; Ball_reset(b, 1); } b->posY += b->velY; if ((b->posY < 0) || (b->posY + BALL_HEIGHT > b->SCREEN_HEIGHT)) { b->posY -= b->velY; b->velY = -b->velY; } } void Pong_run(Pong *p) { int start = false; int quit = false; Pong_render(p, start); while (!start) { fflush(stdout); while( SDL_PollEvent( &(p->e) ) != 0 ) { if( p->e.type == SDL_KEYDOWN) start = true; } } putc('\n', stdout); while (!quit) { while( SDL_PollEvent( &(p->e) ) != 0 ) { if( p->e.type == SDL_QUIT) quit = true; } const Uint8* currentKeyStates = SDL_GetKeyboardState( NULL ); if (currentKeyStates[SDL_SCANCODE_ESCAPE]) quit = true; Racket_handle_event(p->racketL, currentKeyStates); Racket_handle_event(p->racketR, currentKeyStates); Ball_move(p->ball, p); Racket_move(p->racketL); Racket_move(p->racketR); if (Pong_render(p, start) > 0) quit = true; Pong_status(p, quit); } } void Pong_status(const Pong *p, int quit) { printf("[STATUS] SCORE: L %i | R %i", p->racketL->score->score, p->racketR->score->score); if (quit) { putc('\n', stdout); } else { putc('\r', stdout); } }