forked from rich/ReWalker
Compare commits
13 Commits
ReWindow-I
...
main
Author | SHA1 | Date | |
---|---|---|---|
f18c8c3fe3 | |||
4f6080a962 | |||
ffb989cd19 | |||
f204dc5898 | |||
9b06da8ee1 | |||
28a2d42369 | |||
0be005a877 | |||
27dd9b3639 | |||
07c970749f | |||
ca55970ed9 | |||
|
9f4b8987c0 | ||
|
a3d67ef18a | ||
|
01f2acca60 |
@@ -28,20 +28,39 @@ include(cmake/CPM.cmake)
|
||||
# You specify the release name to target against. See the link below for releases:
|
||||
# https://git.redacted.cc/Redacted/ReWindow/releases
|
||||
|
||||
CPMAddPackage(
|
||||
NAME mcolor
|
||||
URL https://git.redacted.cc/maxine/mcolor/archive/Prerelease-5.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME ReWindow
|
||||
URL URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-31.zip
|
||||
URL https://git.redacted.cc/Redacted/ReWindow/archive/Prerelease-32.zip
|
||||
)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME JGL
|
||||
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-47.zip
|
||||
)
|
||||
|
||||
add_executable(ReWalkerApp main.cpp)
|
||||
|
||||
target_include_directories(ReWalkerApp PUBLIC ${ReWindow_SOURCE_DIR}/include ${J3ML_SOURCE_DIR}/include)
|
||||
target_include_directories(ReWalkerApp PUBLIC
|
||||
${ReWindow_SOURCE_DIR}/include
|
||||
${J3ML_SOURCE_DIR}/include
|
||||
${mcolor_SOURCE_DIR}/include
|
||||
${JGL_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
target_link_libraries(ReWalkerApp PUBLIC J3ML ReWindowLibrary)
|
||||
target_link_libraries(ReWalkerApp PUBLIC J3ML ReWindow mcolor JGL)
|
||||
|
||||
# simple window test
|
||||
add_executable(TestWindowApp test.cpp)
|
||||
|
||||
target_include_directories(TestWindowApp PUBLIC ${ReWindow_SOURCE_DIR}/include ${J3ML_SOURCE_DIR}/include)
|
||||
target_include_directories(TestWindowApp PUBLIC
|
||||
${ReWindow_SOURCE_DIR}/include
|
||||
${J3ML_SOURCE_DIR}/include
|
||||
${mcolor_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
target_link_libraries(TestWindowApp PUBLIC J3ML ReWindowLibrary)
|
||||
target_link_libraries(TestWindowApp PUBLIC J3ML ReWindow)
|
37
README.md
37
README.md
@@ -1,9 +1,42 @@
|
||||
# ReWalker
|
||||
ReWalker is a simple random walker program that uses ReWindow to handle windowing and mouse operations.
|
||||
|
||||
This is a simple random walker that has a little twist that if the user clicks the mouse over the window it "blows" the walker away from the mouse pointer.
|
||||
This is a simple random walker that has a little twist that if the user clicks the mouse over the window it "blows" the walker away from the mouse pointer. Pressing the space bar will reset the walker back to the centre of the screen and pressing the esc key will close the application.
|
||||
|
||||
The user can user the number 1, 2, 3, 4 and 5 keys to change the force at which the walker is blown away from the mouse pointer. 1 is lowest force and 5 is highest.
|
||||
|
||||
test.cpp builds to TestWindowApp as a test to help me understand how ReWindow works.
|
||||
|
||||
main.cpp builds to ReWalkerApp which is the main random walker program.
|
||||
|
||||
Thanks to Bill, Josh and Maxine for sorting the correct ReWindow Integration.
|
||||
|
||||
## Run ReWalker
|
||||
|
||||
|
||||
Install dependencies
|
||||
|
||||
```bash
|
||||
Rocky/Fedora/RHEL: dnf install cmake make gcc-g++ libX11 libX11-devel mesa-libGL-devel
|
||||
Pop_OS!/Ubuntu/Debian: apt-get install cmake make gcc g++ libx11-6 libx11-dev libgl-dev libxrandr-dev
|
||||
```
|
||||
|
||||
Clone the repository
|
||||
|
||||
```bash
|
||||
git clone https://git.redacted.cc/rich/ReWalker.git
|
||||
```
|
||||
|
||||
Build
|
||||
|
||||
```bash
|
||||
cd ReWalker && mkdir build && cd build && cmake .. && make
|
||||
```
|
||||
|
||||
Run it
|
||||
|
||||
```bash
|
||||
./ReWalkerApp
|
||||
```
|
||||
## Thanks
|
||||
|
||||
Thanks to Bill, Josh and Maxine for sorting the correct ReWindow Integration, and other things.
|
203
main.cpp
203
main.cpp
@@ -1,53 +1,216 @@
|
||||
// ReWalker
|
||||
// A random walker that moves around the screen
|
||||
// A random walker that moves around the screen with a fading trail and mouse interaction.
|
||||
// Now with real-time adjustable push force using number keys 1-5!
|
||||
// Written using Redacted ReWindow https://git.redacted.cc/Redacted/ReWindow
|
||||
// Written by Rich
|
||||
// With help from (and thanks to) from Maxine, Josh and Bill
|
||||
|
||||
#include <rewindow/types/window.h>
|
||||
#include <rewindow/logger/logger.h>
|
||||
#include <GL/gl.h>
|
||||
#include <ReWindow/types/Window.h>
|
||||
#include <ReWindow/Logger.h>
|
||||
#include <JGL/JGL.h>
|
||||
#include <Color4.hpp>
|
||||
#include <memory>
|
||||
|
||||
// define window size and dot size (dot size should be odd)
|
||||
// Define window size and dot size (dot size should be odd for symmetry)
|
||||
#define WIDTH 800
|
||||
#define HEIGHT 600
|
||||
#define DOT_SIZE 5
|
||||
|
||||
// Define fading speed (higher = faster fading, range: 0.001 - 0.2)
|
||||
#define FADE_SPEED 0.05f
|
||||
|
||||
constexpr unsigned int TRAIL_LENGTH = 20;
|
||||
|
||||
// Enable debug mode (set to 0 to disable debug output)
|
||||
#define DEBUG 0
|
||||
|
||||
/**
|
||||
* @brief Represents the walker that moves randomly on the screen.
|
||||
*/
|
||||
struct Walker {
|
||||
float x, y;
|
||||
Vector2 position{}; // Current position of the walker
|
||||
|
||||
Walker() : x(WIDTH / 2.0f), y(HEIGHT / 2.0f) {}
|
||||
/**
|
||||
* @brief Constructor initializes the walker at the center of the screen.
|
||||
*/
|
||||
Walker() : position(WIDTH / 2.0f, HEIGHT / 2.0f) {}
|
||||
|
||||
/**
|
||||
* @brief Moves the walker one step in a random direction.
|
||||
*/
|
||||
void step() {
|
||||
float angle = static_cast<float>(rand()) / RAND_MAX * 360.0f;
|
||||
angle = angle * M_PI / 180.0f;
|
||||
angle = Math::Radians(angle);
|
||||
float dx = std::cos(angle);
|
||||
float dy = std::sin(angle);
|
||||
|
||||
x = std::clamp(x + dx, 0.0f, static_cast<float>(WIDTH - 1));
|
||||
y = std::clamp(y + dy, 0.0f, static_cast<float>(HEIGHT - 1));
|
||||
// Update position and clamp within screen boundaries
|
||||
position.x = std::clamp(position.x + dx, 0.0f, static_cast<float>(WIDTH - 1));
|
||||
position.y = std::clamp(position.y + dy, 0.0f, static_cast<float>(HEIGHT - 1));
|
||||
|
||||
#if DEBUG
|
||||
std::cout << "Walker Position: (" << position.x << ", " << position.y << ")\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pushes the walker away from a given (mouse) position.
|
||||
* @param mouseX X coordinate of the mouse.
|
||||
* @param mouseY Y coordinate of the mouse.
|
||||
* @param force The force applied to push the walker away.
|
||||
*/
|
||||
void pushAway(float mouseX, float mouseY, float force) {
|
||||
float adjustedMouseY = HEIGHT - mouseY; // Adjust for coordinate system
|
||||
|
||||
float deltaX = position.x - mouseX;
|
||||
float deltaY = position.y - adjustedMouseY;
|
||||
|
||||
float distance = std::sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
|
||||
// Only push if the mouse is close enough
|
||||
if (distance > 0.0f) {
|
||||
float unitX = deltaX / distance;
|
||||
float unitY = deltaY / distance;
|
||||
|
||||
// Apply dynamic push force
|
||||
position.x = std::clamp(position.x + unitX * force, 0.0f, static_cast<float>(WIDTH - 1));
|
||||
position.y = std::clamp(position.y + unitY * force, 0.0f, static_cast<float>(HEIGHT - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets the walker to the center of the screen.
|
||||
*/
|
||||
void resetPosition() {
|
||||
position = Vector2(WIDTH / 2.0f, HEIGHT / 2.0f);
|
||||
}
|
||||
};
|
||||
|
||||
class RandomWalkerWindow : public ReWindow::RWindow {
|
||||
/**
|
||||
* @brief Custom ReWindow window class that manages the random walker simulation.
|
||||
*/
|
||||
class RandomWalkerWindow : public ReWindow::OpenGLWindow {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor initializes the window, walker, and trail buffer.
|
||||
* @param title Window title
|
||||
* @param width Window width
|
||||
* @param height Window height
|
||||
*/
|
||||
RandomWalkerWindow(const std::string& title, int width, int height)
|
||||
: ReWindow::RWindow(title, width, height) {}
|
||||
: ReWindow::OpenGLWindow(title, width, height, 2, 1),
|
||||
walker(std::make_unique<Walker>()),
|
||||
trailBuffer{}, // Initialize trail buffer to white (1.0)
|
||||
pushForce(3.0f) // Default push force
|
||||
|
||||
{}
|
||||
|
||||
void OnOpen() override {
|
||||
if (!JGL::Init({WIDTH, HEIGHT}, 0, 0))
|
||||
exit(0);
|
||||
|
||||
this->render_target = new RenderTarget({WIDTH, HEIGHT}, Colors::White);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called every frame to update and render the walker with a fading trail.
|
||||
*/
|
||||
void OnRefresh(float elapsed) override {
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Clear with white
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLSwapBuffers();
|
||||
// Handle user inputs
|
||||
handleMouseInput();
|
||||
handleKeyboardInput();
|
||||
|
||||
// Move the walker
|
||||
walker->step();
|
||||
|
||||
JGL::Update({WIDTH, HEIGHT});
|
||||
J2D::Begin(render_target, true);
|
||||
// Update trail (fade effect)
|
||||
fadeTrail();
|
||||
// Render the updated trail
|
||||
drawTrail();
|
||||
// Update the trail buffer with the walkers current position
|
||||
plotWalker();
|
||||
J2D::End();
|
||||
|
||||
J2D::Begin(nullptr, true);
|
||||
J2D::DrawRenderTarget(render_target, {0, 0});
|
||||
J2D::DrawString(Colors::Black, "Framerate: " + std::to_string((int) (1.f / delta_time)), 0, 0, 1, 16);
|
||||
J2D::End();
|
||||
// Swap buffers to display the frame
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Walker> walker;
|
||||
std::vector<std::pair<Vector2, float>> trailBuffer{}; // Stores grayscale intensity of pixels (1.0 = white, 0.0 = black)
|
||||
RenderTarget* render_target = nullptr;
|
||||
|
||||
float pushForce; // Variable push force that can be adjusted in real time
|
||||
|
||||
/**
|
||||
* @brief Handles mouse input to push the walker away.
|
||||
*/
|
||||
void handleMouseInput() {
|
||||
auto mousePos = GetMouseCoordinates();
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Left)) {
|
||||
walker->pushAway(mousePos.x, mousePos.y, pushForce);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles keyboard input to reset the walker and adjust push force.
|
||||
*/
|
||||
void handleKeyboardInput() {
|
||||
if (IsKeyDown(Keys::Space)) {
|
||||
walker->resetPosition();
|
||||
}
|
||||
|
||||
if (IsKeyDown(Keys::Escape)) {
|
||||
Close();
|
||||
}
|
||||
|
||||
// Adjust push force using number keys 1-5
|
||||
if (IsKeyDown(Keys::One)) pushForce = 1.0f;
|
||||
if (IsKeyDown(Keys::Two)) pushForce = 2.0f;
|
||||
if (IsKeyDown(Keys::Three)) pushForce = 3.0f;
|
||||
if (IsKeyDown(Keys::Four)) pushForce = 4.0f;
|
||||
if (IsKeyDown(Keys::Five)) pushForce = 5.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies the fade effect to the trail buffer.
|
||||
*/
|
||||
void fadeTrail() {
|
||||
// Fade out existing trail points
|
||||
for (auto& trailPoint : trailBuffer)
|
||||
trailPoint.second = std::max(trailPoint.second - FADE_SPEED, 0.0f);
|
||||
|
||||
trailBuffer.emplace_back(walker->position, 1.0f);
|
||||
|
||||
// Limit trail length
|
||||
if (trailBuffer.size() > TRAIL_LENGTH)
|
||||
trailBuffer.erase(trailBuffer.begin());
|
||||
}
|
||||
|
||||
void drawTrail() {
|
||||
for (const auto& trailPoint : trailBuffer)
|
||||
J2D::DrawPoint({0, 0, 0, (uint8_t) (trailPoint.second * 255.0f)}, trailPoint.first, DOT_SIZE);
|
||||
}
|
||||
|
||||
void plotWalker() {
|
||||
J2D::DrawPoint(Colors::Black, walker->position, DOT_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
auto window = std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
|
||||
if (!window->Open())
|
||||
return -1;
|
||||
|
||||
std::unique_ptr<RandomWalkerWindow> window =
|
||||
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
|
||||
|
||||
window->SetRenderer(RenderingAPI::OPENGL);
|
||||
window->Open();
|
||||
// Uncomment this to make things go super fast.
|
||||
//window->SetVsyncEnabled(false);
|
||||
|
||||
while (!window->IsClosing()) {
|
||||
window->ManagedRefresh();
|
||||
|
20
test.cpp
20
test.cpp
@@ -1,32 +1,30 @@
|
||||
// simple test program to open a window with
|
||||
// a blue background.
|
||||
|
||||
#include <rewindow/types/window.h>
|
||||
#include <rewindow/logger/logger.h>
|
||||
#include <ReWindow/types/Window.h>
|
||||
#include <ReWindow/Logger.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
#define WIDTH 800
|
||||
#define HEIGHT 600
|
||||
|
||||
|
||||
class RandomWalkerWindow : public ReWindow::RWindow {
|
||||
class RandomWalkerWindow : public ReWindow::OpenGLWindow {
|
||||
public:
|
||||
RandomWalkerWindow(const std::string& title, int width, int height)
|
||||
: ReWindow::RWindow(title, width, height) {}
|
||||
: ReWindow::OpenGLWindow(title, width, height, 2, 1) {}
|
||||
|
||||
void OnRefresh(float elapsed) override {
|
||||
glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Clear with blue
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLSwapBuffers();
|
||||
//glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Clear with blue
|
||||
//glClear(GL_COLOR_BUFFER_BIT);
|
||||
SwapBuffers();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
||||
std::unique_ptr<RandomWalkerWindow> window =
|
||||
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
|
||||
|
||||
window->SetRenderer(RenderingAPI::OPENGL);
|
||||
std::unique_ptr<RandomWalkerWindow> window =
|
||||
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
|
||||
window->Open();
|
||||
|
||||
while (!window->IsClosing()) {
|
||||
|
Reference in New Issue
Block a user