#include "pong.h" #include "sounds.h" #include int Difficulty = 1; atomic_int Ticks = 0; bool GameGoing = true; mtx_t AudioQueueBeingModified; int AudioQueue[20]; int internal_clock() { const struct timespec Delay = { 0, 20000000 }; struct timespec Remaining; while(GameGoing == true) { atomic_fetch_add(&Ticks, 1); thrd_sleep(&Delay, &Remaining); } thrd_exit(0); } int audio() { int i; InitAudioDevice(); Sound Bounce = LoadSound("resources/bounce.wav"); Sound TitleScreen = LoadSound("resources/title.wav"); Sound Victory = LoadSound("resources/victory.wav"); Sound Defeat = LoadSound("resources/defeat.wav"); const struct timespec Delay = { 0, 20000000 }; struct timespec Remaining; while(GameGoing == true) { for(i = 0; i < 20; i++) { if(AudioQueue[i] != -1){ switch(AudioQueue[i]) { case 0: //Play bounce sound. PlaySoundMulti(Bounce); break; case 1: //Play game over PlaySoundMulti(Defeat); break; case 2: //Play win PlaySoundMulti(Victory); break; case 3: //Title Screen PlaySoundMulti(TitleScreen); break; case 99: //Stop All Sounds StopSoundMulti(); break; default: break; } while(mtx_trylock(&AudioQueueBeingModified) == thrd_busy) thrd_sleep(&Delay, &Remaining); AudioQueue[i] = -1; mtx_unlock(&AudioQueueBeingModified); } } thrd_sleep(&Delay, &Remaining); } thrd_exit(0); } bool play_audio(int SoundEffect) { int i; while(mtx_trylock(&AudioQueueBeingModified) == thrd_busy); for(i = 1; i != 20; i++) { if (AudioQueue[i-1] == -1) { AudioQueue[i-1] = AudioQueue[i]; } } for(i = 0; AudioQueue[i] != -1; i++) { if(i > sizeof(AudioQueue)) { mtx_unlock(&AudioQueueBeingModified); return false; } } AudioQueue[i] = SoundEffect; mtx_unlock(&AudioQueueBeingModified); return true; } int main() { //Raylib Init InitWindow(1280, 720, "Pong"); SetTargetFPS(60); SetExitKey(KEY_Q); Image Icon = LoadImage("resources/ball.png"); SetWindowIcon(Icon); SetWindowState(FLAG_VSYNC_HINT); SetWindowState(FLAG_WINDOW_RESIZABLE); //Initialize Variables Camera2D MainCamera; MainCamera.target = (Vector2){0, 0}; MainCamera.offset = (Vector2){0, 0}; MainCamera.rotation = 0; //Populate Audio Queue for(int i = 0; i < sizeof(AudioQueue); i++) { AudioQueue[i] = -1; printf("%d\n", AudioQueue[i]); } mtx_init(&AudioQueueBeingModified, mtx_plain); // Init Player Variables struct Players Player; Player.Score = 0; char PlayerScore[50]; // Used later to display score on screen. // Init Enemy Variables struct Players Enemy; Enemy.Score = 0; Enemy.Direction = 0; char EnemyScore[50]; struct Balls Ball; Ball.X = 1280/2.0f; Ball.Y = 720/2.0f; Ball.Direction = LEFT; Ball.Speed = 3.0f; Ball.Angle = 0.0f; // Set Sprites Texture2D PaddleSprite = LoadTexture("resources/paddle.png"); Texture2D BallSprite = LoadTexture("resources/ball.png"); // Set Collision Boxes Player.HitBox = (Rectangle){80, Player.Y, 5, PaddleSprite.height}; Enemy.HitBox = (Rectangle){1200, Enemy.Y, 5, PaddleSprite.height}; Ball.HitBox = (Rectangle){Ball.X, Ball.Y, BallSprite.width, BallSprite.height}; Enemy.BallDetector = (Rectangle){0, Enemy.Y+120, 1280, PaddleSprite.height/5.0f}; // Debug Player.Y = 200; // Initialize Internal Clock thrd_t InternalClock; thrd_create(&InternalClock, internal_clock, NULL); thrd_t AudioThread; thrd_create(&AudioThread, audio, NULL); // Launch Title Screen jmp_buf RestartGame; setjmp(RestartGame); title_screen(); play_audio(99); Enemy.Score = 0; Player.Score = 0; while(!WindowShouldClose() && GameGoing == true) { MainCamera.zoom = GetScreenHeight()/720.0f; if (Enemy.Score >= 5) { play_audio(MUSIC_DEFEAT); longjmp(RestartGame, 0); } else if (Player.Score >= 5) { play_audio(MUSIC_VICTORY); longjmp(RestartGame, 0); } //Controls if(IsKeyDown(KEY_UP)) { Player.Y -= 10; } else if (IsKeyDown(KEY_DOWN)) { Player.Y += 10; } else if(IsKeyPressed(KEY_ESCAPE)) { EnableCursor(); } else if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT) || IsCursorHidden() == true) { Player.Y = GetMouseY()-PaddleSprite.height/2.0f; DisableCursor(); } if(GetMouseY() < 0) { SetMousePosition(0, 0); } else if(GetMouseY() > 720) { SetMousePosition(0, 720); } //Check if players are off-screen if (Player.Y < 0) { Player.Y = 0; } else if (Player.Y > 480) { Player.Y = 480; } enemy(&Enemy, Ball); // Collision ball(&Player.HitBox, &Enemy.HitBox, &Ball, &Player.Score, &Enemy.Score); //Updates hitbox with player's position. Player.HitBox.y = Player.Y; //Turn Scores into strings. snprintf(PlayerScore, 50, "Player: %d", Player.Score); snprintf(EnemyScore, 50, "Enemy: %d", Enemy.Score); BeginDrawing(); ClearBackground(BLACK); BeginMode2D(MainCamera); DrawTexture(PaddleSprite, 0, Player.Y, WHITE); DrawTexture(PaddleSprite, 1200, Enemy.Y, WHITE); DrawTexture(BallSprite, Ball.X, Ball.Y, WHITE); //DrawRectangleRec(Enemy.BallDetector, RED); DrawText(PlayerScore, 0, 0, 32, GREEN); DrawText(EnemyScore, 1130, 688, 32, RED); EndMode2D(); EndDrawing(); } GameGoing = false; thrd_join(AudioThread, NULL); CloseWindow(); return(0); }