Compare commits

19 Commits

Author SHA1 Message Date
f96a846202 small tweeks 2025-02-01 14:39:44 -05:00
442b397290 added Pop_OS! libvulkan-dev dependancy and info about obstacles 2025-02-01 12:57:55 -05:00
9f8224462b Added impervious obstacles 2025-02-01 12:54:28 -05:00
166bf96928 added framerate output. 2025-02-01 11:49:51 -05:00
cf1518a61b Updated to use JGL 2025-02-01 11:41:24 -05:00
583315193d Updated to use JGL 2025-02-01 11:40:21 -05:00
29c32f6d9a Updated to use JGL 2025-02-01 11:39:24 -05:00
4f6080a962 removed unused headers 2025-01-31 17:42:35 -05:00
ffb989cd19 Update README.md 2025-01-31 17:33:02 -05:00
f204dc5898 user controlled added variable pushForce
User can user 1, 2, 3, 4 or 5 key to change the force at which the walker is pushed away from the mouse pointer when the mouse button is pressed.
2025-01-31 17:31:40 -05:00
9b06da8ee1 Update README.md 2025-01-31 15:51:00 -05:00
28a2d42369 added user interaction information 2025-01-31 14:30:05 -05:00
0be005a877 added user interaction
mouse click to blow walker away from mouse
space to reset walker to middle of the window
esc to close application
2025-01-31 14:28:14 -05:00
27dd9b3639 added trail effect 2025-01-31 14:09:33 -05:00
07c970749f Update main.cpp
render random walker as dot and added hopefully helpful comments
2025-01-31 13:47:03 -05:00
ca55970ed9 Update main.cpp
changed to using smart pointer for window in main()
2025-01-31 13:29:42 -05:00
rich
9f4b8987c0 updated to make README look more like other Redacted project READMEs! 2025-01-13 17:07:32 -05:00
mathsDOTearth
a3d67ef18a Merge remote-tracking branch 'origin/ReWindow-Integration' 2025-01-13 21:58:20 +00:00
rich
01f2acca60 changed to use smart pointer for window handle 2025-01-13 10:24:35 -05:00
4 changed files with 269 additions and 46 deletions

View File

@@ -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)

View File

@@ -1,9 +1,44 @@
# 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.
There are now 4 red impervious obstacles to bump into.
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 libvulkan-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.

227
main.cpp
View File

@@ -1,53 +1,224 @@
// ReWalker
// A random walker that moves around the screen
// Written using Redacted ReWindow https://git.redacted.cc/Redacted/ReWindow
// A random walker that moves around the screen with a fading trail, mouse interaction, and a status bar.
// There are now obsticalse you cant walk through
// Updated to use the latest ReWindow API and JGL rendering.
// Written by Rich
// With help from (and thanks to) from Maxine, Josh and Bill
// 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
#define WIDTH 800
#define HEIGHT 600
#define DOT_SIZE 5
#define OBSTACLE_SIZE 50
struct Walker {
float x, y;
#define STATUS_BAR_HEIGHT 30 // Height of the status bar at the bottom
Walker() : x(WIDTH / 2.0f), y(HEIGHT / 2.0f) {}
#define FADE_SPEED 0.05f
constexpr unsigned int TRAIL_LENGTH = 20;
void step() {
float angle = static_cast<float>(rand()) / RAND_MAX * 360.0f;
angle = angle * M_PI / 180.0f;
float dx = std::cos(angle);
float dy = std::sin(angle);
// Enable debug mode
#define DEBUG 1
x = std::clamp(x + dx, 0.0f, static_cast<float>(WIDTH - 1));
y = std::clamp(y + dy, 0.0f, static_cast<float>(HEIGHT - 1));
/**
* @brief Represents an obstacle that the walker cannot pass through.
*/
struct Obstacle {
Vector2 position; // Top-left corner of the obstacle
Obstacle(float x, float y) : position(x, y) {}
/**
* @brief Checks if a given position is inside the obstacle.
*/
bool isColliding(const Vector2& pos) const {
return pos.x >= position.x && pos.x <= position.x + OBSTACLE_SIZE &&
pos.y >= position.y && pos.y <= position.y + OBSTACLE_SIZE;
}
};
class RandomWalkerWindow : public ReWindow::RWindow {
/**
* @brief Represents the walker that moves randomly.
*/
struct Walker {
Vector2 position;
Vector2 lastValidPosition;
Walker() : position(WIDTH / 2.0f, (HEIGHT - STATUS_BAR_HEIGHT) / 2.0f),
lastValidPosition(position) {}
/**
* @brief Moves the walker in a random direction.
*/
void step(const std::vector<Obstacle>& obstacles) {
float angle = static_cast<float>(rand()) / RAND_MAX * 360.0f;
angle = Math::Radians(angle);
float dx = std::cos(angle);
float dy = std::sin(angle);
// Store last valid position
lastValidPosition = position;
// Update position
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 - STATUS_BAR_HEIGHT - 1));
// Check for collisions
for (const auto& obstacle : obstacles) {
if (obstacle.isColliding(position)) {
position = lastValidPosition; // Revert movement if collision occurs
break;
}
}
}
/**
* @brief Pushes the walker away from the mouse pointer.
*/
void pushAway(float mouseX, float mouseY, float force, const std::vector<Obstacle>& obstacles) {
float deltaX = position.x - mouseX;
float deltaY = position.y - mouseY;
float distance = std::sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0.0f) {
float unitX = deltaX / distance;
float unitY = deltaY / distance;
lastValidPosition = position;
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 - STATUS_BAR_HEIGHT - 1));
// Prevent moving into obstacles
for (const auto& obstacle : obstacles) {
if (obstacle.isColliding(position)) {
position = lastValidPosition;
break;
}
}
}
}
/**
* @brief Resets the walker to the center of the screen.
*/
void resetPosition() {
position = Vector2(WIDTH / 2.0f, (HEIGHT - STATUS_BAR_HEIGHT) / 2.0f);
}
};
/**
* @brief Custom ReWindow window class that manages the walker simulation.
*/
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),
walker(std::make_unique<Walker>()),
pushForce(3.0f)
{
// Define four obstacles
obstacles.emplace_back(200, 150);
obstacles.emplace_back(500, 150);
obstacles.emplace_back(200, 400);
obstacles.emplace_back(500, 400);
}
void OnOpen() override {
if (!JGL::Init({WIDTH, HEIGHT}, 0, 0))
exit(0);
this->render_target = new RenderTarget({WIDTH, HEIGHT}, Colors::White);
}
void OnRefresh(float elapsed) override {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Clear with white
glClear(GL_COLOR_BUFFER_BIT);
GLSwapBuffers();
handleMouseInput();
handleKeyboardInput();
// Move walker
walker->step(obstacles);
JGL::Update({WIDTH, HEIGHT});
J2D::Begin(render_target, true);
fadeTrail();
drawTrail();
drawObstacles();
plotWalker();
J2D::End();
J2D::Begin(nullptr, true);
J2D::DrawRenderTarget(render_target, {0, 0});
J2D::End();
SwapBuffers();
}
private:
std::unique_ptr<Walker> walker;
std::vector<Obstacle> obstacles;
std::vector<std::pair<Vector2, float>> trailBuffer{};
RenderTarget* render_target = nullptr;
float pushForce;
void handleMouseInput() {
auto mousePos = GetMouseCoordinates();
if (IsMouseButtonDown(MouseButtons::Left)) {
walker->pushAway(mousePos.x, mousePos.y, pushForce, obstacles);
}
}
void handleKeyboardInput() {
if (IsKeyDown(Keys::Space)) {
walker->resetPosition();
}
if (IsKeyDown(Keys::Escape)) {
Close();
}
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;
}
void fadeTrail() {
for (auto& trailPoint : trailBuffer)
trailPoint.second = std::max(trailPoint.second - FADE_SPEED, 0.0f);
trailBuffer.emplace_back(walker->position, 1.0f);
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);
}
/**
* @brief Draws the four red obstacles.
*/
void drawObstacles() {
for (const auto& obstacle : obstacles) {
J2D::FillRect(Colors::Red, obstacle.position, {OBSTACLE_SIZE, OBSTACLE_SIZE});
}
}
};
int main() {
std::unique_ptr<RandomWalkerWindow> window =
std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
window->SetRenderer(RenderingAPI::OPENGL);
window->Open();
auto window = std::make_unique<RandomWalkerWindow>("Random Walker with Obstacles", WIDTH, HEIGHT);
if (!window->Open())
return -1;
while (!window->IsClosing()) {
window->ManagedRefresh();

View File

@@ -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()) {