diff --git a/Capter1/Game.cpp b/Capter1/Game.cpp new file mode 100644 index 0000000..dbce8f4 --- /dev/null +++ b/Capter1/Game.cpp @@ -0,0 +1,245 @@ +#include "Game.h" + +const int thickness = 15; +const float paddleH = 100.0f; + +Game::Game():mWindow(nullptr),mRenderer(nullptr),mTicksCount(0),mIsRunning(true),mPaddleDir(0) +{ + +} + +bool Game::Initialize() +{ + // Initialize SDL + int sdlResult = SDL_Init(SDL_INIT_VIDEO); + if (sdlResult != 0) + { + SDL_Log("Unable to initialize SDL: %s", SDL_GetError()); + return false; + } + + // Create an SDL Window + mWindow = SDL_CreateWindow( + "Game Programming in C++ (Chapter 1)", // Window title + 100, // Top left x-coordinate of window + 100, // Top left y-coordinate of window + 1024, // Width of window + 768, // Height of window + 0 // Flags (0 for no flags set) + ); + + if (!mWindow) + { + SDL_Log("Failed to create window: %s", SDL_GetError()); + return false; + } + + //// Create SDL renderer + mRenderer = SDL_CreateRenderer( + mWindow, // Window to create renderer for + -1, // Usually -1 + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC + ); + + if (!mRenderer) + { + SDL_Log("Failed to create renderer: %s", SDL_GetError()); + return false; + } + // + mPaddlePos.x = 10.0f; + mPaddlePos.y = 768.0f/2.0f; + mBallPos.x = 1024.0f/2.0f; + mBallPos.y = 768.0f/2.0f; + mBallVel.x = -200.0f; + mBallVel.y = 235.0f; + + return true; +} + +void Game::RunLoop() +{ + while (mIsRunning) + { + ProcessInput(); + UpdateGame(); + GenerateOutput(); + } +} + +void Game::ProcessInput() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + // If we get an SDL_QUIT event, end loop + case SDL_QUIT: + mIsRunning = false; + break; + } + } + + // Get state of keyboard + const Uint8* state = SDL_GetKeyboardState(NULL); + // If escape is pressed, also end loop + if (state[SDL_SCANCODE_ESCAPE]) + { + mIsRunning = false; + } + + // Update paddle direction based on W/S keys + mPaddleDir = 0; + if (state[SDL_SCANCODE_W]) + { + mPaddleDir -= 1; + } + if (state[SDL_SCANCODE_S]) + { + mPaddleDir += 1; + } +} + +void Game::UpdateGame() +{ + // Wait until 16ms has elapsed since last frame + while (!SDL_TICKS_PASSED(SDL_GetTicks(), mTicksCount + 16)) + ; + + // Delta time is the difference in ticks from last frame + // (converted to seconds) + float deltaTime = (SDL_GetTicks() - mTicksCount) / 1000.0f; + + // Clamp maximum delta time value + if (deltaTime > 0.05f) + { + deltaTime = 0.05f; + } + + // Update tick counts (for next frame) + mTicksCount = SDL_GetTicks(); + + // Update paddle position based on direction + if (mPaddleDir != 0) + { + mPaddlePos.y += mPaddleDir * 300.0f * deltaTime; + // Make sure paddle doesn't move off screen! + if (mPaddlePos.y < (paddleH/2.0f + thickness)) + { + mPaddlePos.y = paddleH/2.0f + thickness; + } + else if (mPaddlePos.y > (768.0f - paddleH/2.0f - thickness)) + { + mPaddlePos.y = 768.0f - paddleH/2.0f - thickness; + } + } + + // Update ball position based on ball velocity + mBallPos.x += mBallVel.x * deltaTime; + mBallPos.y += mBallVel.y * deltaTime; + + // Bounce if needed + // Did we intersect with the paddle? + float diff = mPaddlePos.y - mBallPos.y; + // Take absolute value of difference + diff = (diff > 0.0f) ? diff : -diff; + if ( + // Our y-difference is small enough + diff <= paddleH / 2.0f && + // We are in the correct x-position + mBallPos.x <= 25.0f && mBallPos.x >= 20.0f && + // The ball is moving to the left + mBallVel.x < 0.0f) + { + mBallVel.x *= -1.0f; + } + // Did the ball go off the screen? (if so, end game) + else if (mBallPos.x <= 0.0f) + { + mIsRunning = false; + } + // Did the ball collide with the right wall? + else if (mBallPos.x >= (1024.0f - thickness) && mBallVel.x > 0.0f) + { + mBallVel.x *= -1.0f; + } + + // Did the ball collide with the top wall? + if (mBallPos.y <= thickness && mBallVel.y < 0.0f) + { + mBallVel.y *= -1; + } + // Did the ball collide with the bottom wall? + else if (mBallPos.y >= (768 - thickness) && + mBallVel.y > 0.0f) + { + mBallVel.y *= -1; + } +} + +void Game::GenerateOutput() +{ + // Set draw color to blue + SDL_SetRenderDrawColor( + mRenderer, + 0, // R + 0, // G + 255, // B + 255 // A + ); + + // Clear back buffer + SDL_RenderClear(mRenderer); + + // Draw walls + SDL_SetRenderDrawColor(mRenderer, 255, 255, 255, 255); + + // Draw top wall + SDL_Rect wall{ + 0, // Top left x + 0, // Top left y + 1024, // Width + thickness // Height + }; + SDL_RenderFillRect(mRenderer, &wall); + + // Draw bottom wall + wall.y = 768 - thickness; + SDL_RenderFillRect(mRenderer, &wall); + + // Draw right wall + wall.x = 1024 - thickness; + wall.y = 0; + wall.w = thickness; + wall.h = 1024; + SDL_RenderFillRect(mRenderer, &wall); + + // Draw paddle + SDL_Rect paddle{ + static_cast(mPaddlePos.x), + static_cast(mPaddlePos.y - paddleH/2), + thickness, + static_cast(paddleH) + }; + SDL_RenderFillRect(mRenderer, &paddle); + + // Draw ball + SDL_Rect ball{ + static_cast(mBallPos.x - thickness/2), + static_cast(mBallPos.y - thickness/2), + thickness, + thickness + }; + SDL_RenderFillRect(mRenderer, &ball); + + // Swap front buffer and back buffer + SDL_RenderPresent(mRenderer); +} + +void Game::Shutdown() +{ + SDL_DestroyRenderer(mRenderer); + SDL_DestroyWindow(mWindow); + SDL_Quit(); +} \ No newline at end of file diff --git a/Capter1/Game.h b/Capter1/Game.h new file mode 100644 index 0000000..93705ef --- /dev/null +++ b/Capter1/Game.h @@ -0,0 +1,47 @@ +#pragma once +#include "SDL2/SDL.h" + +// Vector2 struct just stores x/y coordinates +// (for now) +struct Vector2 +{ + float x; + float y; +}; + +// Game class +class Game +{ +public: + Game(); + // Initialize the game + bool Initialize(); + // Runs the game loop until the game is over + void RunLoop(); + // Shutdown the game + void Shutdown(); +private: + // Helper functions for the game loop + void ProcessInput(); + void UpdateGame(); + void GenerateOutput(); + + // Window created by SDL + SDL_Window* mWindow; + // Renderer for 2D drawing + SDL_Renderer* mRenderer; + // Number of ticks since start of game + Uint32 mTicksCount; + // Game should continue to run + bool mIsRunning; + + // Pong specific + // Direction of paddle + int mPaddleDir; + // Position of paddle + Vector2 mPaddlePos; + // Position of ball + Vector2 mBallPos; + // Velocity of ball + Vector2 mBallVel; +}; \ No newline at end of file diff --git a/Capter1/ax_game.cpp b/Capter1/ax_game.cpp new file mode 100644 index 0000000..6400952 --- /dev/null +++ b/Capter1/ax_game.cpp @@ -0,0 +1,41 @@ +#include "ax_game.hpp" +#include "ball.hpp" + +ax_game::ax_game() +{ + ax_Window = nullptr; + ax_Renderer = nullptr; + ax_TickCounter = 0; + ax_IsRunning = true; + + ax_ball_one = ball(); +} + +ax_game::~ax_game() +{ + ax_ball_one.~ball(); +} + +bool ax_game::Init(){ + +} + +void ax_game::RunLoop(){ + +} + +void ax_game::Shutdown(){ + +} + +void ax_game::Input(){ + +} + +void ax_game::Update(){ + +} + +void ax_game::Output(){ + +} \ No newline at end of file diff --git a/Capter1/ax_game.hpp b/Capter1/ax_game.hpp new file mode 100644 index 0000000..286584f --- /dev/null +++ b/Capter1/ax_game.hpp @@ -0,0 +1,27 @@ +#pragma once +#include "SDL2/SDL.h" +#include "ball.hpp" + +class ax_game +{ +private: + void Input(); + void Update(); + void Output(); + + SDL_Window *ax_Window; + SDL_Renderer *ax_Renderer; + Uint32 ax_TickCounter; + bool ax_IsRunning; + + ball ax_ball_one; + + +public: + ax_game(); + ~ax_game(); + bool Init(); + void RunLoop(); + void Shutdown(); +}; + diff --git a/Capter1/ball.cpp b/Capter1/ball.cpp new file mode 100644 index 0000000..f432d22 --- /dev/null +++ b/Capter1/ball.cpp @@ -0,0 +1,11 @@ +#include "ball.hpp" + +ball::ball() +{ + x = 0; + y = 0; +} + +ball::~ball() +{ +} diff --git a/Capter1/ball.hpp b/Capter1/ball.hpp new file mode 100644 index 0000000..e70a5f8 --- /dev/null +++ b/Capter1/ball.hpp @@ -0,0 +1,9 @@ +class ball +{ +private: + float x; + float y; +public: + ball(); + ~ball(); +}; diff --git a/Capter1/main b/Capter1/main new file mode 100755 index 0000000..276af1e Binary files /dev/null and b/Capter1/main differ diff --git a/Capter1/main.cpp b/Capter1/main.cpp new file mode 100644 index 0000000..19c6024 --- /dev/null +++ b/Capter1/main.cpp @@ -0,0 +1,18 @@ +//#include "Game.h" +#include "ax_game.hpp" + +int main(int argc, char** argv) +{ + /*Game game; + bool success = game.Initialize(); + if (success) + { + game.RunLoop(); + } + game.Shutdown(); + */ + + + + return 0; +} \ No newline at end of file