Start trying own game
This commit is contained in:
245
Capter1/Game.cpp
Normal file
245
Capter1/Game.cpp
Normal file
@@ -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<int>(mPaddlePos.x),
|
||||||
|
static_cast<int>(mPaddlePos.y - paddleH/2),
|
||||||
|
thickness,
|
||||||
|
static_cast<int>(paddleH)
|
||||||
|
};
|
||||||
|
SDL_RenderFillRect(mRenderer, &paddle);
|
||||||
|
|
||||||
|
// Draw ball
|
||||||
|
SDL_Rect ball{
|
||||||
|
static_cast<int>(mBallPos.x - thickness/2),
|
||||||
|
static_cast<int>(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();
|
||||||
|
}
|
||||||
47
Capter1/Game.h
Normal file
47
Capter1/Game.h
Normal file
@@ -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;
|
||||||
|
};
|
||||||
41
Capter1/ax_game.cpp
Normal file
41
Capter1/ax_game.cpp
Normal file
@@ -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(){
|
||||||
|
|
||||||
|
}
|
||||||
27
Capter1/ax_game.hpp
Normal file
27
Capter1/ax_game.hpp
Normal file
@@ -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();
|
||||||
|
};
|
||||||
|
|
||||||
11
Capter1/ball.cpp
Normal file
11
Capter1/ball.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include "ball.hpp"
|
||||||
|
|
||||||
|
ball::ball()
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ball::~ball()
|
||||||
|
{
|
||||||
|
}
|
||||||
9
Capter1/ball.hpp
Normal file
9
Capter1/ball.hpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class ball
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
public:
|
||||||
|
ball();
|
||||||
|
~ball();
|
||||||
|
};
|
||||||
BIN
Capter1/main
Executable file
BIN
Capter1/main
Executable file
Binary file not shown.
18
Capter1/main.cpp
Normal file
18
Capter1/main.cpp
Normal file
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user