refactoring
-moved globals to game class -moved helper functions to util class -added more imgui functionality
This commit is contained in:
parent
6559a9dc95
commit
60a923d4c9
|
|
@ -3,40 +3,38 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <Util.h>
|
#include <Util.h>
|
||||||
|
#include <Random.h>
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <imgui-SFML.h>
|
#include <imgui-SFML.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include <Random.h>
|
|
||||||
|
|
||||||
struct Ball
|
struct Ball
|
||||||
{
|
{
|
||||||
Ball(sf::Vector2f, sf::Vector2f);
|
Ball(sf::Vector2f position_in, sf::Vector2f vel_in);
|
||||||
|
|
||||||
sf::Vector2f pos;
|
sf::Vector2f pos;
|
||||||
sf::Vector2f previousPos{};
|
sf::Vector2f previousPos{};
|
||||||
sf::Vector2f velocity;
|
sf::Vector2f velocity;
|
||||||
Color color{sf::Color::Red};
|
|
||||||
bool alive{true};
|
bool alive{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Brick
|
struct Brick
|
||||||
{
|
{
|
||||||
Brick(sf::Vector2f);
|
Brick(sf::Vector2f position_in);
|
||||||
|
|
||||||
sf::Vector2f pos;
|
sf::Vector2f pos;
|
||||||
Color color{sf::Color::White};
|
|
||||||
bool alive{true};
|
bool alive{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Player
|
struct Player
|
||||||
{
|
{
|
||||||
Player();
|
Player() = default;
|
||||||
|
Player(sf::Vector2f position_in);
|
||||||
|
|
||||||
sf::Vector2f pos;
|
sf::Vector2f pos{};
|
||||||
sf::Vector2f previousPos{};
|
sf::Vector2f previousPos{};
|
||||||
Color color{sf::Color::White};
|
|
||||||
float score{};
|
float score{};
|
||||||
int lives{3};
|
int lives{3};
|
||||||
bool left{false};
|
bool left{false};
|
||||||
|
|
@ -65,16 +63,39 @@ private:
|
||||||
|
|
||||||
void checkEndGame();
|
void checkEndGame();
|
||||||
|
|
||||||
|
void checkBallCollision();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
|
std::vector<Ball> balls;
|
||||||
std::vector<Brick> bricks;
|
std::vector<Brick> bricks;
|
||||||
std::vector<Brick> specialBricks;
|
std::vector<Brick> specialBricks;
|
||||||
std::vector<Ball> balls;
|
|
||||||
std::vector<sf::Vector2f> ballsToAdd;
|
std::vector<sf::Vector2f> ballsToAdd;
|
||||||
sf::CircleShape tempCircle;
|
sf::CircleShape tempCircle;
|
||||||
sf::RectangleShape tempRect;
|
sf::RectangleShape tempRect;
|
||||||
|
|
||||||
|
// mostly used for imgui
|
||||||
|
sf::Vector2f brickSize{50, 10};
|
||||||
|
sf::Vector2f playerSize{500, 10};
|
||||||
|
sf::Vector2f playerStartPos{700,700};
|
||||||
|
sf::Vector2f brickHalfSize{brickSize / 2.f};
|
||||||
|
sf::Vector2f playerHalfSize{playerSize / 2.f};
|
||||||
|
int rowSize{8};
|
||||||
|
int columnSize{5};
|
||||||
|
int totalSpecialBricks{3};
|
||||||
|
int totalBricks{rowSize * columnSize};
|
||||||
|
unsigned int frameRate{60};
|
||||||
|
float playerSpeed{10};
|
||||||
|
float ballRadius{5.0f};
|
||||||
|
float ballMaxSpeed{10};
|
||||||
|
Color ballColor{sf::Color::Red};
|
||||||
|
Color brickColor{sf::Color::White};
|
||||||
|
Color playerColor{sf::Color::White};
|
||||||
|
Color specialBrickColor{sf::Color::Blue};
|
||||||
|
bool windowCollasped{false};
|
||||||
|
static constexpr unsigned int numPhysicsUpdates{4};
|
||||||
};
|
};
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
struct Color
|
struct Color
|
||||||
{
|
{
|
||||||
Color() = default;
|
Color() = default;
|
||||||
Color(float r_in, float g_in, float b_in, float a_in = 255)
|
Color(float r_in, float g_in, float b_in, float a_in = 1.0f)
|
||||||
: r(r_in)
|
: r(r_in)
|
||||||
, g(g_in)
|
, g(g_in)
|
||||||
, b(b_in)
|
, b(b_in)
|
||||||
|
|
@ -13,12 +13,11 @@ struct Color
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Color(sf::Color color_in)
|
Color(sf::Color color_in)
|
||||||
{
|
: r((float)color_in.r / 255.f)
|
||||||
r = (float)color_in.r / 255.f;
|
, g((float)color_in.g / 255.f)
|
||||||
g = (float)color_in.g / 255.f;
|
, b((float)color_in.b / 255.f)
|
||||||
b = (float)color_in.b / 255.f;
|
, a((float)color_in.a / 255.f)
|
||||||
a = (float)color_in.a / 255.f;
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
float r{};
|
float r{};
|
||||||
float g{};
|
float g{};
|
||||||
|
|
@ -36,19 +35,6 @@ struct Color
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace global
|
sf::Vector2f getOverlap(sf::FloatRect first, sf::FloatRect second);
|
||||||
{
|
sf::Vector2f velocityInRandomDir(float speed_in);
|
||||||
inline sf::Vector2f playerSize{500, 10};
|
sf::Vector2f velocityInDirection(float speed_in, sf::Angle angle_in);
|
||||||
inline sf::Vector2f playerHalfSize{playerSize / 2.f};
|
|
||||||
inline sf::Vector2f brickSize{50, 10};
|
|
||||||
inline sf::Vector2f brickHalfSize{brickSize / 2.f};
|
|
||||||
inline int totalSpecialBricks{3};
|
|
||||||
inline int rowSize{8};
|
|
||||||
inline int columnSize{5};
|
|
||||||
inline int totalBricks{rowSize * columnSize};
|
|
||||||
inline float ballRadius{5.0f};
|
|
||||||
inline float ballMaxSpeed{10};
|
|
||||||
inline float playerSpeed{10};
|
|
||||||
inline sf::Vector2f playerStartPos{700,700};
|
|
||||||
inline bool windowCollasped{false};
|
|
||||||
}
|
|
||||||
266
src/Game.cpp
266
src/Game.cpp
|
|
@ -1,29 +1,16 @@
|
||||||
#include <Game.h>
|
#include <Game.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <Util.h>
|
||||||
|
#include <Random.h>
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <imgui-SFML.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
sf::Vector2f getOverlap(sf::FloatRect first, sf::FloatRect second)
|
|
||||||
{
|
|
||||||
sf::Vector2f result;
|
|
||||||
sf::Vector2f delta;
|
|
||||||
delta.x = std::abs(second.position.x - first.position.x);
|
|
||||||
delta.y = std::abs(second.position.y - first.position.y);
|
|
||||||
|
|
||||||
result.x = (first.size.x + second.size.x) - delta.x;
|
|
||||||
result.y = (first.size.y + second.size.y) - delta.y;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
sf::Vector2f velocityInRandomDir(float speed_in)
|
|
||||||
{
|
|
||||||
bool upOrDown{(bool)Random::get(0,1)};
|
|
||||||
|
|
||||||
sf::Angle angle = sf::degrees((float)upOrDown ? Random::get(225, 315) : Random::get(45, 135));
|
|
||||||
|
|
||||||
return {speed_in * std::cos(angle.asRadians()), speed_in * std::sin(angle.asRadians())};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Ball::Ball(sf::Vector2f position_in, sf::Vector2f vel_in)
|
Ball::Ball(sf::Vector2f position_in, sf::Vector2f vel_in)
|
||||||
: velocity(vel_in)
|
: velocity(vel_in)
|
||||||
, pos(position_in)
|
, pos(position_in)
|
||||||
|
|
@ -33,29 +20,29 @@ Brick::Brick(sf::Vector2f position_in)
|
||||||
: pos(position_in)
|
: pos(position_in)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Player::Player()
|
Player::Player(sf::Vector2f position_in)
|
||||||
: pos(global::playerStartPos)
|
: pos(position_in)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
Game::Game()
|
Game::Game()
|
||||||
: player()
|
: window({sf::VideoMode({ 1920u, 1080u }), "breakout"})
|
||||||
, window({sf::VideoMode({ 1920u, 1080u }), "breakout"})
|
|
||||||
{
|
{
|
||||||
window.setFramerateLimit(60);
|
window.setFramerateLimit(frameRate);
|
||||||
|
|
||||||
if (!ImGui::SFML::Init(window))
|
if (!ImGui::SFML::Init(window)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
tempCircle.setOrigin({global::ballRadius, global::ballRadius});
|
player.pos = playerStartPos;
|
||||||
|
|
||||||
bricks.reserve(global::totalBricks);
|
tempCircle.setOrigin({ballRadius, ballRadius});
|
||||||
|
|
||||||
|
bricks.reserve(totalBricks);
|
||||||
bricks.emplace_back(sf::Vector2f{200, 100});
|
bricks.emplace_back(sf::Vector2f{200, 100});
|
||||||
specialBricks.reserve(global::totalSpecialBricks);
|
specialBricks.reserve(totalSpecialBricks);
|
||||||
balls.reserve(10);
|
balls.reserve(10);
|
||||||
ballsToAdd.reserve(10);
|
ballsToAdd.reserve(10);
|
||||||
|
|
||||||
ballsToAdd.emplace_back(global::playerStartPos.x, global::playerStartPos.y - 300);
|
ballsToAdd.emplace_back(playerStartPos.x, playerStartPos.y - 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::input()
|
void Game::input()
|
||||||
|
|
@ -87,6 +74,10 @@ void Game::input()
|
||||||
player.right = true;
|
player.right = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::Scan::F1:
|
||||||
|
windowCollasped = !windowCollasped;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +107,7 @@ void Game::input()
|
||||||
switch (MouseButtonPressed->button)
|
switch (MouseButtonPressed->button)
|
||||||
{
|
{
|
||||||
case sf::Mouse::Button::Left:
|
case sf::Mouse::Button::Left:
|
||||||
bricks.emplace_back((sf::Vector2f)MouseButtonPressed->position);
|
specialBricks.emplace_back((sf::Vector2f)MouseButtonPressed->position);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -128,90 +119,103 @@ void Game::input()
|
||||||
|
|
||||||
void Game::collision()
|
void Game::collision()
|
||||||
{
|
{
|
||||||
// declaring at top so it can be used in and out of the ball collision loop
|
|
||||||
const sf:: FloatRect playerBounds = {player.pos, global::playerHalfSize};
|
checkBallCollision();
|
||||||
const sf:: FloatRect previousPlayerBounds = {player.previousPos, global::playerHalfSize};
|
|
||||||
|
const sf:: FloatRect playerBounds = {player.pos, playerHalfSize};
|
||||||
|
//player wall collide
|
||||||
|
if (playerBounds.position.x + playerBounds.size.x > window.getSize().x)
|
||||||
|
{
|
||||||
|
player.pos.x = window.getSize().x - playerHalfSize.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerBounds.position.x < playerHalfSize.x)
|
||||||
|
{
|
||||||
|
player.pos.x = playerHalfSize.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//ball collisions
|
void Game::checkBallCollision()
|
||||||
|
{
|
||||||
for (auto& ball : balls)
|
for (auto& ball : balls)
|
||||||
{
|
{
|
||||||
const sf::FloatRect ballBounds = {ball.pos, {global::ballRadius, global::ballRadius}};
|
const sf::FloatRect ballBounds = {ball.pos, {ballRadius, ballRadius}};
|
||||||
const sf::FloatRect previousBallBounds = {ball.previousPos, {global::ballRadius, global::ballRadius}};
|
const sf::FloatRect previousBallBounds = {ball.previousPos, {ballRadius, ballRadius}};
|
||||||
|
|
||||||
for (auto& brick : bricks)
|
for (auto& brick : bricks)
|
||||||
{
|
{
|
||||||
const sf::FloatRect brickBounds = {brick.pos, global::brickHalfSize};
|
const sf::FloatRect brickBounds = {brick.pos, brickHalfSize};
|
||||||
auto intersect = getOverlap(ballBounds, brickBounds);
|
auto intersect = getOverlap(ballBounds, brickBounds);
|
||||||
auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
||||||
|
|
||||||
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
||||||
{
|
|
||||||
brick.alive = false;
|
|
||||||
ball.velocity.x *= -1;
|
|
||||||
if (ball.pos.x < brick.pos.x)
|
|
||||||
{
|
{
|
||||||
ball.pos.x -= intersect.x;
|
brick.alive = false;
|
||||||
|
ball.velocity.x *= -1;
|
||||||
|
if (ball.pos.x < brick.pos.x)
|
||||||
|
{
|
||||||
|
ball.pos.x -= intersect.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ball.pos.x += intersect.x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ball.pos.x += intersect.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// coming from y direction
|
// coming from y direction
|
||||||
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
||||||
{
|
|
||||||
brick.alive = false;
|
|
||||||
ball.velocity.y *= -1;
|
|
||||||
if (ball.pos.y < brick.pos.y)
|
|
||||||
{
|
{
|
||||||
ball.pos.y -= intersect.y;
|
brick.alive = false;
|
||||||
|
ball.velocity.y *= -1;
|
||||||
|
if (ball.pos.y < brick.pos.y)
|
||||||
|
{
|
||||||
|
ball.pos.y -= intersect.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ball.pos.y += intersect.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ball.pos.y += intersect.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& brick : specialBricks)
|
for (auto& brick : specialBricks)
|
||||||
{
|
{
|
||||||
const sf::FloatRect brickBounds = {brick.pos, global::brickHalfSize};
|
const sf::FloatRect brickBounds = {brick.pos, brickHalfSize};
|
||||||
const auto intersect = getOverlap(ballBounds, brickBounds);
|
const auto intersect = getOverlap(ballBounds, brickBounds);
|
||||||
const auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
const auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
||||||
bool spawnExtraBall{false};
|
bool spawnExtraBall{false};
|
||||||
|
|
||||||
// coming from x direction
|
// coming from x direction
|
||||||
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
||||||
{
|
|
||||||
brick.alive = false;
|
|
||||||
spawnExtraBall = true;
|
|
||||||
ball.velocity.x *= -1;
|
|
||||||
if (ball.pos.x < brick.pos.x)
|
|
||||||
{
|
{
|
||||||
ball.pos.x -= intersect.x;
|
brick.alive = false;
|
||||||
|
spawnExtraBall = true;
|
||||||
|
ball.velocity.x *= -1;
|
||||||
|
if (ball.pos.x < brick.pos.x)
|
||||||
|
{
|
||||||
|
ball.pos.x -= intersect.x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ball.pos.x += intersect.x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ball.pos.x += intersect.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// coming from y direction
|
// coming from y direction
|
||||||
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
||||||
{
|
|
||||||
brick.alive = false;
|
|
||||||
spawnExtraBall = true;
|
|
||||||
ball.velocity.y *= -1;
|
|
||||||
if (ball.pos.y < brick.pos.y)
|
|
||||||
{
|
{
|
||||||
ball.pos.y -= intersect.y;
|
brick.alive = false;
|
||||||
|
spawnExtraBall = true;
|
||||||
|
ball.velocity.y *= -1;
|
||||||
|
if (ball.pos.y < brick.pos.y)
|
||||||
|
{
|
||||||
|
ball.pos.y -= intersect.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ball.pos.y += intersect.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ball.pos.y += intersect.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spawnExtraBall)
|
if (spawnExtraBall)
|
||||||
{
|
{
|
||||||
|
|
@ -226,25 +230,28 @@ void Game::collision()
|
||||||
ball.alive = false;
|
ball.alive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ball.pos.x - global::ballRadius <= 0)
|
if (ball.pos.x - ballRadius <= 0)
|
||||||
{
|
{
|
||||||
ball.pos.x = global::ballRadius;
|
ball.pos.x = ballRadius;
|
||||||
ball.velocity.x *= -1;
|
ball.velocity.x *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ball.pos.x + global::ballRadius >= window.getSize().x)
|
if (ball.pos.x + ballRadius >= window.getSize().x)
|
||||||
{
|
{
|
||||||
ball.pos.x = window.getSize().x - global::ballRadius;
|
ball.pos.x = window.getSize().x - ballRadius;
|
||||||
ball.velocity.x *= -1;
|
ball.velocity.x *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ball.pos.y - global::ballRadius < 0)
|
if (ball.pos.y - ballRadius < 0)
|
||||||
{
|
{
|
||||||
ball.pos.y = global::ballRadius;
|
ball.pos.y = ballRadius;
|
||||||
ball.velocity.y *= -1;
|
ball.velocity.y *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// player collide
|
// player collide
|
||||||
|
const sf:: FloatRect playerBounds = {player.pos, playerHalfSize};
|
||||||
|
const sf:: FloatRect previousPlayerBounds = {player.previousPos, playerHalfSize};
|
||||||
|
|
||||||
auto intersect = getOverlap(ballBounds, playerBounds);
|
auto intersect = getOverlap(ballBounds, playerBounds);
|
||||||
auto previousIntersect = getOverlap(previousBallBounds, previousPlayerBounds);
|
auto previousIntersect = getOverlap(previousBallBounds, previousPlayerBounds);
|
||||||
|
|
||||||
|
|
@ -277,29 +284,19 @@ void Game::collision()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//player wall collide
|
|
||||||
if (playerBounds.position.x + playerBounds.size.x > window.getSize().x)
|
|
||||||
{
|
|
||||||
player.pos.x = window.getSize().x - global::playerHalfSize.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerBounds.position.x < global::playerHalfSize.x)
|
|
||||||
{
|
|
||||||
player.pos.x = global::playerHalfSize.x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::updateEntities()
|
void Game::updateEntities()
|
||||||
{
|
{
|
||||||
balls.erase(std::remove_if(balls.begin(), balls.end(), [](const Ball& ball){ return !ball.alive; }), balls.end());
|
balls.erase(std::remove_if(balls.begin(), balls.end(), [](const Ball& ball){ return !ball.alive; }), balls.end());
|
||||||
bricks.erase(std::remove_if(bricks.begin(), bricks.end(), [](const Brick& brick){ return !brick.alive; }), bricks.end());
|
bricks.erase(std::remove_if(bricks.begin(), bricks.end(), [](const Brick& brick){ return !brick.alive; }), bricks.end());
|
||||||
|
specialBricks.erase(std::remove_if(specialBricks.begin(), specialBricks.end(), [](const Brick& brick){ return !brick.alive; }), specialBricks.end());
|
||||||
|
|
||||||
const auto limit = ballsToAdd.size();
|
const auto limit = ballsToAdd.size();
|
||||||
|
|
||||||
for (int i = 0; i < limit; i++)
|
for (int i = 0; i < limit; i++)
|
||||||
{
|
{
|
||||||
balls.emplace_back(ballsToAdd[i], velocityInRandomDir(global::ballMaxSpeed));
|
balls.emplace_back(ballsToAdd[i], velocityInRandomDir(ballMaxSpeed / numPhysicsUpdates));
|
||||||
ballsToAdd[i] = {0,0};
|
ballsToAdd[i] = {0,0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,7 +329,7 @@ void Game::movement()
|
||||||
int dir = player.right - player.left;
|
int dir = player.right - player.left;
|
||||||
|
|
||||||
player.previousPos = player.pos;
|
player.previousPos = player.pos;
|
||||||
player.pos.x += global::playerSpeed * dir;
|
player.pos.x += (playerSpeed / numPhysicsUpdates) * dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::imgui()
|
void Game::imgui()
|
||||||
|
|
@ -340,7 +337,7 @@ void Game::imgui()
|
||||||
ImGui::SFML::Update(window, clock.restart());
|
ImGui::SFML::Update(window, clock.restart());
|
||||||
|
|
||||||
ImGui::Begin("menu");
|
ImGui::Begin("menu");
|
||||||
ImGui::SetWindowCollapsed(global::windowCollasped);
|
ImGui::SetWindowCollapsed(windowCollasped);
|
||||||
ImGui::Text("Controls:");
|
ImGui::Text("Controls:");
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
ImGui::Text("A/D or arrow keys: move left and right");
|
ImGui::Text("A/D or arrow keys: move left and right");
|
||||||
|
|
@ -349,40 +346,52 @@ void Game::imgui()
|
||||||
ImGui::Text("left click: spawn brick");
|
ImGui::Text("left click: spawn brick");
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
ImGui::SliderFloat("Player Speed", &playerSpeed, 1.f, 50.f);
|
||||||
|
ImGui::SliderFloat("Ball Speed", &ballMaxSpeed, 1.f, 50.f);
|
||||||
|
if (ImGui::SliderFloat("Player Length", &playerSize.x, 1.f, 600.f))
|
||||||
|
{
|
||||||
|
playerHalfSize.x = playerSize.x / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::ColorEdit3("Player Color", playerColor.imgui());
|
||||||
|
ImGui::ColorEdit3("Ball Color", ballColor.imgui());
|
||||||
|
ImGui::ColorEdit3("Brick Color", brickColor.imgui());
|
||||||
|
ImGui::ColorEdit3("Special Brick Color", specialBrickColor.imgui());
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::render()
|
void Game::render()
|
||||||
{
|
{
|
||||||
window.clear();
|
window.clear();
|
||||||
|
|
||||||
|
|
||||||
tempRect.setOrigin(global::brickHalfSize);
|
tempRect.setOrigin(brickHalfSize);
|
||||||
tempRect.setSize(global::brickSize);
|
tempRect.setSize(brickSize);
|
||||||
for (auto& brick : bricks)
|
for (auto& brick : bricks)
|
||||||
{
|
{
|
||||||
tempRect.setPosition(brick.pos);
|
tempRect.setPosition(brick.pos);
|
||||||
tempRect.setFillColor(brick.color.sfml());
|
tempRect.setFillColor(brickColor.sfml());
|
||||||
window.draw(tempRect);
|
window.draw(tempRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& brick : specialBricks)
|
for (auto& brick : specialBricks)
|
||||||
{
|
{
|
||||||
tempRect.setPosition(brick.pos);
|
tempRect.setPosition(brick.pos);
|
||||||
tempRect.setFillColor(brick.color.sfml());
|
tempRect.setFillColor(specialBrickColor.sfml());
|
||||||
window.draw(tempRect);
|
window.draw(tempRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
tempRect.setOrigin(global::playerHalfSize);
|
tempRect.setOrigin(playerHalfSize);
|
||||||
tempRect.setSize(global::playerSize);
|
tempRect.setSize(playerSize);
|
||||||
tempRect.setPosition(player.pos);
|
tempRect.setPosition(player.pos);
|
||||||
tempRect.setFillColor(player.color.sfml());
|
tempRect.setFillColor(playerColor.sfml());
|
||||||
window.draw(tempRect);
|
window.draw(tempRect);
|
||||||
tempCircle.setRadius(global::ballRadius);
|
|
||||||
|
tempCircle.setRadius(ballRadius);
|
||||||
for (auto& ball : balls)
|
for (auto& ball : balls)
|
||||||
{
|
{
|
||||||
tempCircle.setPosition(ball.pos);
|
tempCircle.setPosition(ball.pos);
|
||||||
tempCircle.setFillColor(ball.color.sfml());
|
tempCircle.setFillColor(ballColor.sfml());
|
||||||
window.draw(tempCircle);
|
window.draw(tempCircle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,13 +405,16 @@ void Game::run()
|
||||||
while(window.isOpen())
|
while(window.isOpen())
|
||||||
{
|
{
|
||||||
input();
|
input();
|
||||||
|
|
||||||
updateEntities();
|
|
||||||
|
|
||||||
movement();
|
for (int i = 0; i <= numPhysicsUpdates; i++)
|
||||||
|
{
|
||||||
collision();
|
updateEntities();
|
||||||
|
|
||||||
|
movement();
|
||||||
|
|
||||||
|
collision();
|
||||||
|
}
|
||||||
|
|
||||||
checkEndGame();
|
checkEndGame();
|
||||||
|
|
||||||
imgui();
|
imgui();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include <Util.h>
|
||||||
|
#include <Random.h>
|
||||||
|
|
||||||
|
sf::Vector2f getOverlap(sf::FloatRect first, sf::FloatRect second)
|
||||||
|
{
|
||||||
|
sf::Vector2f result;
|
||||||
|
sf::Vector2f delta;
|
||||||
|
delta.x = std::abs(second.position.x - first.position.x);
|
||||||
|
delta.y = std::abs(second.position.y - first.position.y);
|
||||||
|
|
||||||
|
result.x = (first.size.x + second.size.x) - delta.x;
|
||||||
|
result.y = (first.size.y + second.size.y) - delta.y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f velocityInRandomDir(float speed_in)
|
||||||
|
{
|
||||||
|
const bool upOrDown{(bool)Random::get(0,1)};
|
||||||
|
|
||||||
|
// get angle within certain ranges so that the ball does not
|
||||||
|
// start moving straight side to side or up and down
|
||||||
|
sf::Angle angle = sf::degrees(upOrDown ? Random::get(225, 315) : Random::get(45, 135));
|
||||||
|
if (angle.asDegrees() == 90.f || angle.asDegrees() == 270)
|
||||||
|
{
|
||||||
|
angle += sf::degrees(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sf::Vector2f{speed_in * std::cos(angle.asRadians()), speed_in * std::sin(angle.asRadians())};
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for debugging
|
||||||
|
sf::Vector2f velocityInDirection(float speed_in, sf::Angle angle_in)
|
||||||
|
{
|
||||||
|
return sf::Vector2f{speed_in * std::cos(angle_in.asRadians()), speed_in * std::sin(angle_in.asRadians())};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue