mirror of
https://github.com/Floriansylvain/SFMLplayground.git
synced 2026-08-19 11:43:24 +02:00
refac: moved draw & input code out of game class
This commit is contained in:
@@ -1,101 +1,9 @@
|
|||||||
# CMake SFML Project Template
|
# SFML Playground
|
||||||
|
|
||||||
This repository template should allow for a fast and hassle-free kick start of your next SFML project using CMake.
|
Simple CMake project w/ SFML 3 to play around with.
|
||||||
Thanks to [GitHub's nature of templates](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template), you can fork this repository without inheriting its Git history.
|
|
||||||
|
|
||||||
The template starts out very basic, but might receive additional features over time:
|
## TODO
|
||||||
|
|
||||||
- Basic CMake script to build your project and link SFML on any operating system
|
- [ ] Add a toggle for debug stuff
|
||||||
- Basic [GitHub Actions](https://github.com/features/actions) script for all major platforms
|
- [ ] Add debug text (for ball velocity, position, rest status, etc.)
|
||||||
|
- [ ] Refactor game class to split input handling and debug stuff into their own classes
|
||||||
## How to Use
|
|
||||||
|
|
||||||
1. Install [Git](https://git-scm.com/downloads) and [CMake](https://cmake.org/download/). Use your system's package manager if available.
|
|
||||||
2. Follow [GitHub's instructions](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) for how to use their project template feature to create your own project. If you don't want to use GitHub, see the section below.
|
|
||||||
3. Clone your new GitHub repo and open the repo in your text editor of choice.
|
|
||||||
4. Open [CMakeLists.txt](CMakeLists.txt). Rename the project and the target name of the executable to whatever name you want. Make sure to change all occurrences.
|
|
||||||
5. If you want to add or remove any .cpp files, change the source files listed in the `add_executable` call in CMakeLists.txt to match the source files your project requires. If you plan on keeping the default main.cpp file then no changes are required.
|
|
||||||
6. If your code uses the Audio or Network modules then add `SFML::Audio` or `SFML::Network` to the `target_link_libraries` call alongside the existing `SFML::Graphics` library that is being linked.
|
|
||||||
7. If you use Linux, install SFML's dependencies using your system package manager. On Ubuntu and other Debian-based distributions you can use the following commands:
|
|
||||||
```
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install \
|
|
||||||
libxrandr-dev \
|
|
||||||
libxcursor-dev \
|
|
||||||
libxi-dev \
|
|
||||||
libudev-dev \
|
|
||||||
libfreetype-dev \
|
|
||||||
libflac-dev \
|
|
||||||
libvorbis-dev \
|
|
||||||
libgl1-mesa-dev \
|
|
||||||
libegl1-mesa-dev \
|
|
||||||
libfreetype-dev
|
|
||||||
```
|
|
||||||
8. Configure and build your project. Most popular IDEs support CMake projects with very little effort on your part.
|
|
||||||
|
|
||||||
- [VS Code](https://code.visualstudio.com) via the [CMake extension](https://code.visualstudio.com/docs/cpp/cmake-linux)
|
|
||||||
- [Visual Studio](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-170)
|
|
||||||
- [CLion](https://www.jetbrains.com/clion/features/cmake-support.html)
|
|
||||||
- [Qt Creator](https://doc.qt.io/qtcreator/creator-project-cmake.html)
|
|
||||||
|
|
||||||
Using CMake from the command line is straightforward as well.
|
|
||||||
Be sure to run these commands in the root directory of the project you just created.
|
|
||||||
|
|
||||||
```
|
|
||||||
cmake -B build
|
|
||||||
cmake --build build
|
|
||||||
```
|
|
||||||
|
|
||||||
9. Enjoy!
|
|
||||||
|
|
||||||
## Upgrading SFML
|
|
||||||
|
|
||||||
SFML is found via CMake's [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module.
|
|
||||||
FetchContent automatically downloads SFML from GitHub and builds it alongside your own code.
|
|
||||||
Beyond the convenience of not having to install SFML yourself, this ensures ABI compatibility and simplifies things like specifying static versus shared libraries.
|
|
||||||
|
|
||||||
Modifying what version of SFML you want is as easy as changing the `GIT_TAG` argument.
|
|
||||||
Currently it uses SFML 3 via the `3.0.0` tag.
|
|
||||||
|
|
||||||
## But I want to...
|
|
||||||
|
|
||||||
Modify CMake options by adding them as configuration parameters (with a `-D` flag) or by modifying the contents of CMakeCache.txt and rebuilding.
|
|
||||||
|
|
||||||
### Not use GitHub
|
|
||||||
|
|
||||||
You can use this project without a GitHub account by [downloading the contents](https://github.com/SFML/cmake-sfml-project/archive/refs/heads/master.zip) of the repository as a ZIP archive and unpacking it locally.
|
|
||||||
This approach also avoids using Git entirely if you would prefer to not do that.
|
|
||||||
|
|
||||||
### Change Compilers
|
|
||||||
|
|
||||||
See the variety of [`CMAKE_<LANG>_COMPILER`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html) options.
|
|
||||||
In particular you'll want to modify `CMAKE_CXX_COMPILER` to point to the C++ compiler you wish to use.
|
|
||||||
|
|
||||||
### Change Compiler Optimizations
|
|
||||||
|
|
||||||
CMake abstracts away specific optimizer flags through the [`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) option.
|
|
||||||
By default this project recommends `Release` builds which enable optimizations.
|
|
||||||
Other build types include `Debug` builds which enable debug symbols but disable optimizations.
|
|
||||||
If you're using a multi-configuration generator (as is often the case on Windows), you can modify the [`CMAKE_CONFIGURATION_TYPES`](https://cmake.org/cmake/help/latest/variable/CMAKE_CONFIGURATION_TYPES.html#variable:CMAKE_CONFIGURATION_TYPES) option.
|
|
||||||
|
|
||||||
### Change Generators
|
|
||||||
|
|
||||||
While CMake will attempt to pick a suitable default generator, some systems offer a number of generators to choose from.
|
|
||||||
Ubuntu, for example, offers Makefiles and Ninja as two potential options.
|
|
||||||
For a list of generators, click [here](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
|
|
||||||
To modify the generator you're using you must reconfigure your project providing a `-G` flag with a value corresponding to the generator you want.
|
|
||||||
You can't simply modify an entry in the CMakeCache.txt file unlike the above options.
|
|
||||||
Then you may rebuild your project with this new generator.
|
|
||||||
|
|
||||||
## More Reading
|
|
||||||
|
|
||||||
Here are some useful resources if you want to learn more about CMake:
|
|
||||||
|
|
||||||
- [Official CMake Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/)
|
|
||||||
- [How to Use CMake Without the Agonizing Pain - Part 1](https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html)
|
|
||||||
- [How to Use CMake Without the Agonizing Pain - Part 2](https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-2.html)
|
|
||||||
- [Better CMake YouTube series by Jefferon Amstutz](https://www.youtube.com/playlist?list=PL8i3OhJb4FNV10aIZ8oF0AA46HgA2ed8g)
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
The source code is dual licensed under Public Domain and MIT -- choose whichever you prefer.
|
|
||||||
|
|||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
# CMake SFML Project Template
|
||||||
|
|
||||||
|
This repository template should allow for a fast and hassle-free kick start of your next SFML project using CMake.
|
||||||
|
Thanks to [GitHub's nature of templates](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template), you can fork this repository without inheriting its Git history.
|
||||||
|
|
||||||
|
The template starts out very basic, but might receive additional features over time:
|
||||||
|
|
||||||
|
- Basic CMake script to build your project and link SFML on any operating system
|
||||||
|
- Basic [GitHub Actions](https://github.com/features/actions) script for all major platforms
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
|
||||||
|
1. Install [Git](https://git-scm.com/downloads) and [CMake](https://cmake.org/download/). Use your system's package manager if available.
|
||||||
|
2. Follow [GitHub's instructions](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) for how to use their project template feature to create your own project. If you don't want to use GitHub, see the section below.
|
||||||
|
3. Clone your new GitHub repo and open the repo in your text editor of choice.
|
||||||
|
4. Open [CMakeLists.txt](CMakeLists.txt). Rename the project and the target name of the executable to whatever name you want. Make sure to change all occurrences.
|
||||||
|
5. If you want to add or remove any .cpp files, change the source files listed in the `add_executable` call in CMakeLists.txt to match the source files your project requires. If you plan on keeping the default main.cpp file then no changes are required.
|
||||||
|
6. If your code uses the Audio or Network modules then add `SFML::Audio` or `SFML::Network` to the `target_link_libraries` call alongside the existing `SFML::Graphics` library that is being linked.
|
||||||
|
7. If you use Linux, install SFML's dependencies using your system package manager. On Ubuntu and other Debian-based distributions you can use the following commands:
|
||||||
|
```
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install \
|
||||||
|
libxrandr-dev \
|
||||||
|
libxcursor-dev \
|
||||||
|
libxi-dev \
|
||||||
|
libudev-dev \
|
||||||
|
libfreetype-dev \
|
||||||
|
libflac-dev \
|
||||||
|
libvorbis-dev \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
libegl1-mesa-dev \
|
||||||
|
libfreetype-dev
|
||||||
|
```
|
||||||
|
8. Configure and build your project. Most popular IDEs support CMake projects with very little effort on your part.
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com) via the [CMake extension](https://code.visualstudio.com/docs/cpp/cmake-linux)
|
||||||
|
- [Visual Studio](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-170)
|
||||||
|
- [CLion](https://www.jetbrains.com/clion/features/cmake-support.html)
|
||||||
|
- [Qt Creator](https://doc.qt.io/qtcreator/creator-project-cmake.html)
|
||||||
|
|
||||||
|
Using CMake from the command line is straightforward as well.
|
||||||
|
Be sure to run these commands in the root directory of the project you just created.
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -B build
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
9. Enjoy!
|
||||||
|
|
||||||
|
## Upgrading SFML
|
||||||
|
|
||||||
|
SFML is found via CMake's [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module.
|
||||||
|
FetchContent automatically downloads SFML from GitHub and builds it alongside your own code.
|
||||||
|
Beyond the convenience of not having to install SFML yourself, this ensures ABI compatibility and simplifies things like specifying static versus shared libraries.
|
||||||
|
|
||||||
|
Modifying what version of SFML you want is as easy as changing the `GIT_TAG` argument.
|
||||||
|
Currently it uses SFML 3 via the `3.0.0` tag.
|
||||||
|
|
||||||
|
## But I want to...
|
||||||
|
|
||||||
|
Modify CMake options by adding them as configuration parameters (with a `-D` flag) or by modifying the contents of CMakeCache.txt and rebuilding.
|
||||||
|
|
||||||
|
### Not use GitHub
|
||||||
|
|
||||||
|
You can use this project without a GitHub account by [downloading the contents](https://github.com/SFML/cmake-sfml-project/archive/refs/heads/master.zip) of the repository as a ZIP archive and unpacking it locally.
|
||||||
|
This approach also avoids using Git entirely if you would prefer to not do that.
|
||||||
|
|
||||||
|
### Change Compilers
|
||||||
|
|
||||||
|
See the variety of [`CMAKE_<LANG>_COMPILER`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html) options.
|
||||||
|
In particular you'll want to modify `CMAKE_CXX_COMPILER` to point to the C++ compiler you wish to use.
|
||||||
|
|
||||||
|
### Change Compiler Optimizations
|
||||||
|
|
||||||
|
CMake abstracts away specific optimizer flags through the [`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) option.
|
||||||
|
By default this project recommends `Release` builds which enable optimizations.
|
||||||
|
Other build types include `Debug` builds which enable debug symbols but disable optimizations.
|
||||||
|
If you're using a multi-configuration generator (as is often the case on Windows), you can modify the [`CMAKE_CONFIGURATION_TYPES`](https://cmake.org/cmake/help/latest/variable/CMAKE_CONFIGURATION_TYPES.html#variable:CMAKE_CONFIGURATION_TYPES) option.
|
||||||
|
|
||||||
|
### Change Generators
|
||||||
|
|
||||||
|
While CMake will attempt to pick a suitable default generator, some systems offer a number of generators to choose from.
|
||||||
|
Ubuntu, for example, offers Makefiles and Ninja as two potential options.
|
||||||
|
For a list of generators, click [here](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
|
||||||
|
To modify the generator you're using you must reconfigure your project providing a `-G` flag with a value corresponding to the generator you want.
|
||||||
|
You can't simply modify an entry in the CMakeCache.txt file unlike the above options.
|
||||||
|
Then you may rebuild your project with this new generator.
|
||||||
|
|
||||||
|
## More Reading
|
||||||
|
|
||||||
|
Here are some useful resources if you want to learn more about CMake:
|
||||||
|
|
||||||
|
- [Official CMake Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/)
|
||||||
|
- [How to Use CMake Without the Agonizing Pain - Part 1](https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html)
|
||||||
|
- [How to Use CMake Without the Agonizing Pain - Part 2](https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-2.html)
|
||||||
|
- [Better CMake YouTube series by Jefferon Amstutz](https://www.youtube.com/playlist?list=PL8i3OhJb4FNV10aIZ8oF0AA46HgA2ed8g)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The source code is dual licensed under Public Domain and MIT -- choose whichever you prefer.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "DebugDraw.hpp"
|
||||||
|
|
||||||
|
#include <SFML/Window/Mouse.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "VectorMath.hpp"
|
||||||
|
|
||||||
|
float clamp(float value, float minVal, float maxVal) {
|
||||||
|
return std::max(minVal, std::min(value, maxVal));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugDraw::drawLine(sf::RenderWindow& window, const sf::Vector2f& start,
|
||||||
|
const sf::Vector2f& direction, float length,
|
||||||
|
const sf::Color& color) {
|
||||||
|
sf::Vector2f endPoint = start + VectorMath::normalize(direction) * length;
|
||||||
|
sf::Vertex line[] = {{start, color}, {endPoint, color}};
|
||||||
|
|
||||||
|
window.draw(line, 2, sf::PrimitiveType::Lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugDraw::drawDirectionLine(sf::RenderWindow& window, const Ball* ball) {
|
||||||
|
sf::Vector2f ballCenter = ball->getPosition();
|
||||||
|
sf::Vector2i mousePixel = sf::Mouse::getPosition(window);
|
||||||
|
sf::Vector2f mouseWorld(static_cast<float>(mousePixel.x),
|
||||||
|
static_cast<float>(mousePixel.y));
|
||||||
|
sf::Vector2f dir = mouseWorld - ballCenter;
|
||||||
|
|
||||||
|
drawLine(window, ballCenter, dir, 100.f, sf::Color::Green);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugDraw::drawVelocityLine(sf::RenderWindow& window, const Ball* ball) {
|
||||||
|
if (ball->isAtRest()) return;
|
||||||
|
|
||||||
|
sf::Vector2f ballCenter = ball->getPosition();
|
||||||
|
sf::Vector2f velocity = ball->getVelocity();
|
||||||
|
float velLength = VectorMath::length(velocity);
|
||||||
|
float clampedLength = std::max(0.f, std::min(velLength, 100.f));
|
||||||
|
|
||||||
|
drawLine(window, ballCenter, velocity, clampedLength, sf::Color::Blue);
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SFML/Graphics/Color.hpp>
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
|
||||||
|
#include "Ball.hpp"
|
||||||
|
|
||||||
|
class DebugDraw {
|
||||||
|
public:
|
||||||
|
static void drawLine(sf::RenderWindow& window, const sf::Vector2f& start,
|
||||||
|
const sf::Vector2f& direction, float length,
|
||||||
|
const sf::Color& color);
|
||||||
|
static void drawDirectionLine(sf::RenderWindow& window, const Ball* ball);
|
||||||
|
static void drawVelocityLine(sf::RenderWindow& window, const Ball* ball);
|
||||||
|
};
|
||||||
+15
-55
@@ -4,9 +4,13 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
|
#include "DebugDraw.hpp"
|
||||||
#include "VectorMath.hpp"
|
#include "VectorMath.hpp"
|
||||||
|
|
||||||
Game::Game() {
|
Game::Game()
|
||||||
|
: m_inputManager(
|
||||||
|
std::bind(&Game::processKeyPressed, this, std::placeholders::_1),
|
||||||
|
std::bind(&Game::processMousePressed, this, std::placeholders::_1)) {
|
||||||
m_window.create(sf::VideoMode({Constants::WIDTH, Constants::HEIGHT}),
|
m_window.create(sf::VideoMode({Constants::WIDTH, Constants::HEIGHT}),
|
||||||
"SFML Playground");
|
"SFML Playground");
|
||||||
m_window.setVerticalSyncEnabled(true);
|
m_window.setVerticalSyncEnabled(true);
|
||||||
@@ -18,7 +22,7 @@ Game::Game() {
|
|||||||
sf::Vector2f(400.f, 0.f)));
|
sf::Vector2f(400.f, 0.f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::processKeyPressed(const sf::Event::KeyPressed& kP) {
|
void Game::processKeyPressed(const sf::Event::KeyPressed &kP) {
|
||||||
if (kP.code == sf::Keyboard::Key::Equal) {
|
if (kP.code == sf::Keyboard::Key::Equal) {
|
||||||
m_timeScale *= 1.1f;
|
m_timeScale *= 1.1f;
|
||||||
} else if (kP.code == sf::Keyboard::Key::Hyphen) {
|
} else if (kP.code == sf::Keyboard::Key::Hyphen) {
|
||||||
@@ -27,26 +31,13 @@ void Game::processKeyPressed(const sf::Event::KeyPressed& kP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::processMousePressed(const sf::Event::MouseButtonPressed& mP) {
|
void Game::processMousePressed(const sf::Event::MouseButtonPressed &mP) {
|
||||||
if (mP.button != sf::Mouse::Button::Left) return;
|
if (mP.button != sf::Mouse::Button::Left) return;
|
||||||
handleMouseClick(sf::Vector2i(mP.position.x, mP.position.y));
|
handleMouseClick(sf::Vector2i(mP.position.x, mP.position.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::processEvents() {
|
void Game::handleMouseClick(const sf::Vector2i &mousePos) {
|
||||||
while (const std::optional event = m_window.pollEvent()) {
|
auto *ball = dynamic_cast<Ball *>(m_objects[0].get());
|
||||||
if (event->is<sf::Event::Closed>()) {
|
|
||||||
m_window.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (auto kP = event->getIf<sf::Event::KeyPressed>())
|
|
||||||
processKeyPressed(*kP);
|
|
||||||
if (auto mP = event->getIf<sf::Event::MouseButtonPressed>())
|
|
||||||
processMousePressed(*mP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::handleMouseClick(const sf::Vector2i& mousePos) {
|
|
||||||
auto* ball = dynamic_cast<Ball*>(m_objects[0].get());
|
|
||||||
if (!ball) return;
|
if (!ball) return;
|
||||||
|
|
||||||
sf::Vector2f mouseWorld(static_cast<float>(mousePos.x),
|
sf::Vector2f mouseWorld(static_cast<float>(mousePos.x),
|
||||||
@@ -58,48 +49,17 @@ void Game::handleMouseClick(const sf::Vector2i& mousePos) {
|
|||||||
|
|
||||||
void Game::update() {
|
void Game::update() {
|
||||||
float dt = m_clock.restart().asSeconds() * m_timeScale;
|
float dt = m_clock.restart().asSeconds() * m_timeScale;
|
||||||
for (auto& object : m_objects) object->update(dt);
|
for (auto &object : m_objects) object->update(dt);
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawLine(const sf::Vector2f& start, const sf::Vector2f& direction,
|
|
||||||
float length, const sf::Color& color) {
|
|
||||||
float dirLength =
|
|
||||||
std::sqrt(direction.x * direction.x + direction.y * direction.y);
|
|
||||||
sf::Vector2f dirNorm =
|
|
||||||
(dirLength != 0.f) ? direction / dirLength : sf::Vector2f(1.f, 0.f);
|
|
||||||
sf::Vector2f endPoint = start + dirNorm * length;
|
|
||||||
|
|
||||||
sf::Vertex line[] = {{start, color}, {endPoint, color}};
|
|
||||||
m_window.draw(line, 2, sf::PrimitiveType::Lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawDirectionLine(const Ball* ball) {
|
|
||||||
sf::Vector2f ballCenter = ball->getPosition();
|
|
||||||
sf::Vector2i mousePixel = sf::Mouse::getPosition(m_window);
|
|
||||||
sf::Vector2f mouseWorld(static_cast<float>(mousePixel.x),
|
|
||||||
static_cast<float>(mousePixel.y));
|
|
||||||
sf::Vector2f dir = mouseWorld - ballCenter;
|
|
||||||
drawLine(ballCenter, dir, 100.f, sf::Color::Green);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawVelocityLine(const Ball* ball) {
|
|
||||||
if (ball->isAtRest()) return;
|
|
||||||
sf::Vector2f ballCenter = ball->getPosition();
|
|
||||||
sf::Vector2f velocity = ball->getVelocity();
|
|
||||||
float velLength =
|
|
||||||
std::sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
|
|
||||||
float clampedLength = std::min(100.f, std::max(0.f, velLength));
|
|
||||||
drawLine(ballCenter, velocity, clampedLength, sf::Color::Blue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::render() {
|
void Game::render() {
|
||||||
m_window.clear(sf::Color::Black);
|
m_window.clear(sf::Color::Black);
|
||||||
for (auto& object : m_objects) object->draw(m_window);
|
for (auto &object : m_objects) object->draw(m_window);
|
||||||
|
|
||||||
auto* ball = dynamic_cast<Ball*>(m_objects[0].get());
|
auto *ball = dynamic_cast<Ball *>(m_objects[0].get());
|
||||||
if (ball) {
|
if (ball) {
|
||||||
drawDirectionLine(ball);
|
DebugDraw::drawDirectionLine(m_window, ball);
|
||||||
drawVelocityLine(ball);
|
DebugDraw::drawVelocityLine(m_window, ball);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_window.display();
|
m_window.display();
|
||||||
@@ -107,7 +67,7 @@ void Game::render() {
|
|||||||
|
|
||||||
void Game::run() {
|
void Game::run() {
|
||||||
while (m_window.isOpen()) {
|
while (m_window.isOpen()) {
|
||||||
processEvents();
|
m_inputManager.processEvents(m_window);
|
||||||
update();
|
update();
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -7,6 +7,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Ball.hpp"
|
#include "Ball.hpp"
|
||||||
|
#include "InputManager.hpp"
|
||||||
#include "PhysicalObject.hpp"
|
#include "PhysicalObject.hpp"
|
||||||
|
|
||||||
class Ball;
|
class Ball;
|
||||||
@@ -18,19 +19,13 @@ class Game {
|
|||||||
sf::RenderWindow m_window;
|
sf::RenderWindow m_window;
|
||||||
std::vector<std::unique_ptr<PhysicalObject>> m_objects;
|
std::vector<std::unique_ptr<PhysicalObject>> m_objects;
|
||||||
sf::Clock m_clock;
|
sf::Clock m_clock;
|
||||||
|
InputManager m_inputManager;
|
||||||
void processEvents();
|
|
||||||
void processKeyPressed(const sf::Event::KeyPressed& keyPressed);
|
void processKeyPressed(const sf::Event::KeyPressed& keyPressed);
|
||||||
void processMousePressed(const sf::Event::MouseButtonPressed& mousePressed);
|
void processMousePressed(const sf::Event::MouseButtonPressed& mousePressed);
|
||||||
void handleMouseClick(const sf::Vector2i& mousePos);
|
void handleMouseClick(const sf::Vector2i& mousePos);
|
||||||
void update();
|
void update();
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
void drawLine(const sf::Vector2f& start, const sf::Vector2f& direction,
|
|
||||||
float length, const sf::Color& color);
|
|
||||||
void drawDirectionLine(const Ball* ball);
|
|
||||||
void drawVelocityLine(const Ball* ball);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Game();
|
Game();
|
||||||
void run();
|
void run();
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include "InputManager.hpp"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
InputManager::InputManager(KeyCallback keyCb, MouseCallback mouseCb)
|
||||||
|
: m_keyCallback(std::move(keyCb)), m_mouseCallback(std::move(mouseCb)) {}
|
||||||
|
|
||||||
|
void InputManager::processEvents(sf::Window& window) {
|
||||||
|
while (const std::optional event = window.pollEvent()) {
|
||||||
|
if (event->is<sf::Event::Closed>()) {
|
||||||
|
window.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (auto kP = event->getIf<sf::Event::KeyPressed>()) m_keyCallback(*kP);
|
||||||
|
if (auto mP = event->getIf<sf::Event::MouseButtonPressed>())
|
||||||
|
m_mouseCallback(*mP);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
#include <SFML/Window/Window.hpp>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class InputManager {
|
||||||
|
public:
|
||||||
|
using KeyCallback = std::function<void(const sf::Event::KeyPressed&)>;
|
||||||
|
using MouseCallback =
|
||||||
|
std::function<void(const sf::Event::MouseButtonPressed&)>;
|
||||||
|
|
||||||
|
InputManager(KeyCallback keyCb, MouseCallback mouseCb);
|
||||||
|
|
||||||
|
void processEvents(sf::Window& window);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KeyCallback m_keyCallback;
|
||||||
|
MouseCallback m_mouseCallback;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user