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 <Util.h>
|
||||
#include <Random.h>
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <imgui-SFML.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include <Random.h>
|
||||
|
||||
struct Ball
|
||||
{
|
||||
Ball(sf::Vector2f, sf::Vector2f);
|
||||
Ball(sf::Vector2f position_in, sf::Vector2f vel_in);
|
||||
|
||||
sf::Vector2f pos;
|
||||
sf::Vector2f previousPos{};
|
||||
sf::Vector2f velocity;
|
||||
Color color{sf::Color::Red};
|
||||
bool alive{true};
|
||||
};
|
||||
|
||||
struct Brick
|
||||
{
|
||||
Brick(sf::Vector2f);
|
||||
Brick(sf::Vector2f position_in);
|
||||
|
||||
sf::Vector2f pos;
|
||||
Color color{sf::Color::White};
|
||||
bool alive{true};
|
||||
};
|
||||
|
||||
struct Player
|
||||
{
|
||||
Player();
|
||||
Player() = default;
|
||||
Player(sf::Vector2f position_in);
|
||||
|
||||
sf::Vector2f pos;
|
||||
sf::Vector2f pos{};
|
||||
sf::Vector2f previousPos{};
|
||||
Color color{sf::Color::White};
|
||||
float score{};
|
||||
int lives{3};
|
||||
bool left{false};
|
||||
|
|
@ -65,16 +63,39 @@ private:
|
|||
|
||||
void checkEndGame();
|
||||
|
||||
void checkBallCollision();
|
||||
|
||||
|
||||
private:
|
||||
sf::Clock clock;
|
||||
sf::RenderWindow window;
|
||||
|
||||
Player player;
|
||||
std::vector<Ball> balls;
|
||||
std::vector<Brick> bricks;
|
||||
std::vector<Brick> specialBricks;
|
||||
std::vector<Ball> balls;
|
||||
std::vector<sf::Vector2f> ballsToAdd;
|
||||
sf::CircleShape tempCircle;
|
||||
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
|
||||
{
|
||||
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)
|
||||
, g(g_in)
|
||||
, b(b_in)
|
||||
|
|
@ -13,12 +13,11 @@ struct Color
|
|||
{ }
|
||||
|
||||
Color(sf::Color color_in)
|
||||
{
|
||||
r = (float)color_in.r / 255.f;
|
||||
g = (float)color_in.g / 255.f;
|
||||
b = (float)color_in.b / 255.f;
|
||||
a = (float)color_in.a / 255.f;
|
||||
}
|
||||
: r((float)color_in.r / 255.f)
|
||||
, g((float)color_in.g / 255.f)
|
||||
, b((float)color_in.b / 255.f)
|
||||
, a((float)color_in.a / 255.f)
|
||||
{ }
|
||||
|
||||
float r{};
|
||||
float g{};
|
||||
|
|
@ -36,19 +35,6 @@ struct Color
|
|||
}
|
||||
};
|
||||
|
||||
namespace global
|
||||
{
|
||||
inline sf::Vector2f playerSize{500, 10};
|
||||
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};
|
||||
}
|
||||
sf::Vector2f getOverlap(sf::FloatRect first, sf::FloatRect second);
|
||||
sf::Vector2f velocityInRandomDir(float speed_in);
|
||||
sf::Vector2f velocityInDirection(float speed_in, sf::Angle angle_in);
|
||||
266
src/Game.cpp
266
src/Game.cpp
|
|
@ -1,29 +1,16 @@
|
|||
#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 <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)
|
||||
: velocity(vel_in)
|
||||
, pos(position_in)
|
||||
|
|
@ -33,29 +20,29 @@ Brick::Brick(sf::Vector2f position_in)
|
|||
: pos(position_in)
|
||||
{ }
|
||||
|
||||
Player::Player()
|
||||
: pos(global::playerStartPos)
|
||||
Player::Player(sf::Vector2f position_in)
|
||||
: pos(position_in)
|
||||
{ }
|
||||
|
||||
|
||||
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))
|
||||
return;
|
||||
if (!ImGui::SFML::Init(window)) 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});
|
||||
specialBricks.reserve(global::totalSpecialBricks);
|
||||
specialBricks.reserve(totalSpecialBricks);
|
||||
balls.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()
|
||||
|
|
@ -87,6 +74,10 @@ void Game::input()
|
|||
player.right = true;
|
||||
break;
|
||||
|
||||
case sf::Keyboard::Scan::F1:
|
||||
windowCollasped = !windowCollasped;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -116,7 +107,7 @@ void Game::input()
|
|||
switch (MouseButtonPressed->button)
|
||||
{
|
||||
case sf::Mouse::Button::Left:
|
||||
bricks.emplace_back((sf::Vector2f)MouseButtonPressed->position);
|
||||
specialBricks.emplace_back((sf::Vector2f)MouseButtonPressed->position);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -128,90 +119,103 @@ void Game::input()
|
|||
|
||||
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};
|
||||
const sf:: FloatRect previousPlayerBounds = {player.previousPos, global::playerHalfSize};
|
||||
|
||||
checkBallCollision();
|
||||
|
||||
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)
|
||||
{
|
||||
const sf::FloatRect ballBounds = {ball.pos, {global::ballRadius, global::ballRadius}};
|
||||
const sf::FloatRect previousBallBounds = {ball.previousPos, {global::ballRadius, global::ballRadius}};
|
||||
const sf::FloatRect ballBounds = {ball.pos, {ballRadius, ballRadius}};
|
||||
const sf::FloatRect previousBallBounds = {ball.previousPos, {ballRadius, ballRadius}};
|
||||
|
||||
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 previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
||||
|
||||
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
||||
{
|
||||
brick.alive = false;
|
||||
ball.velocity.x *= -1;
|
||||
if (ball.pos.x < brick.pos.x)
|
||||
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
||||
{
|
||||
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
|
||||
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
||||
{
|
||||
brick.alive = false;
|
||||
ball.velocity.y *= -1;
|
||||
if (ball.pos.y < brick.pos.y)
|
||||
// coming from y direction
|
||||
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
const sf::FloatRect brickBounds = {brick.pos, global::brickHalfSize};
|
||||
const sf::FloatRect brickBounds = {brick.pos, brickHalfSize};
|
||||
const auto intersect = getOverlap(ballBounds, brickBounds);
|
||||
const auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
||||
bool spawnExtraBall{false};
|
||||
|
||||
// coming from x direction
|
||||
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)
|
||||
// coming from x direction
|
||||
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
||||
{
|
||||
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
|
||||
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)
|
||||
// coming from y direction
|
||||
if (intersect.y > 0 && previousIntersect.y <= 0 && intersect.x > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -226,25 +230,28 @@ void Game::collision()
|
|||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// player collide
|
||||
const sf:: FloatRect playerBounds = {player.pos, playerHalfSize};
|
||||
const sf:: FloatRect previousPlayerBounds = {player.previousPos, playerHalfSize};
|
||||
|
||||
auto intersect = getOverlap(ballBounds, playerBounds);
|
||||
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()
|
||||
{
|
||||
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());
|
||||
specialBricks.erase(std::remove_if(specialBricks.begin(), specialBricks.end(), [](const Brick& brick){ return !brick.alive; }), specialBricks.end());
|
||||
|
||||
const auto limit = ballsToAdd.size();
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +329,7 @@ void Game::movement()
|
|||
int dir = player.right - player.left;
|
||||
|
||||
player.previousPos = player.pos;
|
||||
player.pos.x += global::playerSpeed * dir;
|
||||
player.pos.x += (playerSpeed / numPhysicsUpdates) * dir;
|
||||
}
|
||||
|
||||
void Game::imgui()
|
||||
|
|
@ -340,7 +337,7 @@ void Game::imgui()
|
|||
ImGui::SFML::Update(window, clock.restart());
|
||||
|
||||
ImGui::Begin("menu");
|
||||
ImGui::SetWindowCollapsed(global::windowCollasped);
|
||||
ImGui::SetWindowCollapsed(windowCollasped);
|
||||
ImGui::Text("Controls:");
|
||||
ImGui::Indent();
|
||||
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::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();
|
||||
}
|
||||
|
||||
void Game::render()
|
||||
{
|
||||
window.clear();
|
||||
|
||||
|
||||
tempRect.setOrigin(global::brickHalfSize);
|
||||
tempRect.setSize(global::brickSize);
|
||||
tempRect.setOrigin(brickHalfSize);
|
||||
tempRect.setSize(brickSize);
|
||||
for (auto& brick : bricks)
|
||||
{
|
||||
tempRect.setPosition(brick.pos);
|
||||
tempRect.setFillColor(brick.color.sfml());
|
||||
tempRect.setFillColor(brickColor.sfml());
|
||||
window.draw(tempRect);
|
||||
}
|
||||
|
||||
for (auto& brick : specialBricks)
|
||||
{
|
||||
tempRect.setPosition(brick.pos);
|
||||
tempRect.setFillColor(brick.color.sfml());
|
||||
tempRect.setFillColor(specialBrickColor.sfml());
|
||||
window.draw(tempRect);
|
||||
}
|
||||
|
||||
tempRect.setOrigin(global::playerHalfSize);
|
||||
tempRect.setSize(global::playerSize);
|
||||
tempRect.setOrigin(playerHalfSize);
|
||||
tempRect.setSize(playerSize);
|
||||
tempRect.setPosition(player.pos);
|
||||
tempRect.setFillColor(player.color.sfml());
|
||||
tempRect.setFillColor(playerColor.sfml());
|
||||
window.draw(tempRect);
|
||||
tempCircle.setRadius(global::ballRadius);
|
||||
|
||||
tempCircle.setRadius(ballRadius);
|
||||
for (auto& ball : balls)
|
||||
{
|
||||
tempCircle.setPosition(ball.pos);
|
||||
tempCircle.setFillColor(ball.color.sfml());
|
||||
tempCircle.setFillColor(ballColor.sfml());
|
||||
window.draw(tempCircle);
|
||||
}
|
||||
|
||||
|
|
@ -396,13 +405,16 @@ void Game::run()
|
|||
while(window.isOpen())
|
||||
{
|
||||
input();
|
||||
|
||||
updateEntities();
|
||||
|
||||
movement();
|
||||
|
||||
collision();
|
||||
|
||||
for (int i = 0; i <= numPhysicsUpdates; i++)
|
||||
{
|
||||
updateEntities();
|
||||
|
||||
movement();
|
||||
|
||||
collision();
|
||||
}
|
||||
|
||||
checkEndGame();
|
||||
|
||||
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