added user interaction

mouse click to blow walker away from mouse
space to reset walker to middle of the window
esc to close application
This commit is contained in:
2025-01-31 14:28:14 -05:00
parent 27dd9b3639
commit 0be005a877

View File

@@ -1,5 +1,6 @@
// ReWalker
// A random walker that moves around the screen with a fading trail.
// A random walker that moves around the screen with a fading trail and mouse interaction.
// Now with Spacebar reset functionality!
// Written using Redacted ReWindow https://git.redacted.cc/Redacted/ReWindow
// Written by Rich
// With help from (and thanks to) from Maxine, Josh and Bill
@@ -19,7 +20,10 @@
#define DOT_SIZE 5
// Define fading speed (higher = faster fading, range: 0.001 - 0.2)
#define FADE_SPEED 0.01f
#define FADE_SPEED 0.05f
// Define how strong the push effect is when the mouse is clicked
#define PUSH_FORCE 3.0f
// Enable debug mode (set to 0 to disable debug output)
#define DEBUG 0
@@ -41,8 +45,8 @@ struct Walker {
void step() {
float angle = static_cast<float>(rand()) / RAND_MAX * 360.0f;
angle = angle * M_PI / 180.0f; // Convert degrees to radians
float dx = std::cos(angle); // Calculate movement in X direction
float dy = std::sin(angle); // Calculate movement in Y direction
float dx = std::cos(angle);
float dy = std::sin(angle);
// Update position and clamp within screen boundaries
x = std::clamp(x + dx, 0.0f, static_cast<float>(WIDTH - 1));
@@ -52,6 +56,38 @@ struct Walker {
std::cout << "Walker Position: (" << x << ", " << 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.
*/
void pushAway(float mouseX, float mouseY) {
float adjustedMouseY = HEIGHT - mouseY; // Adjust for coordinate system
float deltaX = x - mouseX;
float deltaY = 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 push force
x = std::clamp(x + unitX * PUSH_FORCE, 0.0f, static_cast<float>(WIDTH - 1));
y = std::clamp(y + unitY * PUSH_FORCE, 0.0f, static_cast<float>(HEIGHT - 1));
}
}
/**
* @brief Resets the walker to the center of the screen.
*/
void resetPosition() {
x = WIDTH / 2.0f;
y = HEIGHT / 2.0f;
}
};
/**
@@ -89,6 +125,10 @@ public:
// Clear the OpenGL buffer (not the trail buffer)
glClear(GL_COLOR_BUFFER_BIT);
// Handle user inputs
handleMouseInput();
handleKeyboardInput();
// Update trail (fade effect)
fadeTrail();
@@ -109,9 +149,33 @@ private:
std::unique_ptr<Walker> walker;
std::vector<float> trailBuffer; // Stores grayscale intensity of pixels (1.0 = white, 0.0 = black)
/**
* @brief Handles mouse input to push the walker away.
*/
void handleMouseInput() {
auto mousePos = GetMouseCoordinates();
if (IsMouseButtonDown(MouseButtons::Left)) {
walker->pushAway(mousePos.x, mousePos.y);
}
}
/**
* @brief Handles keyboard input to reset the walker.
*/
void handleKeyboardInput() {
if (IsKeyDown(Keys::Space)) {
walker->resetPosition();
}
// Close the window and quit if Escape is pressed
if (IsKeyDown(Keys::Escape)) {
Close(); // This will break the main event loop in main()
}
}
/**
* @brief Applies the fade effect to the trail buffer.
* Each pixel brightness gradually increases toward 1.0 (white).
*/
void fadeTrail() {
for (auto& pixel : trailBuffer) {
@@ -120,7 +184,7 @@ private:
}
/**
* @brief Plots the walker current position as a black dot in the trail buffer.
* @brief Plots the walkers current position as a black dot in the trail buffer.
*/
void plotWalker() {
int centerX = static_cast<int>(walker->x);
@@ -143,13 +207,10 @@ private:
* @brief Renders the trail buffer to the screen using OpenGL.
*/
void drawTrail() {
// Convert float values (0.0-1.0) to grayscale (0-255) for rendering
std::vector<uint8_t> grayscale(WIDTH * HEIGHT);
for (size_t i = 0; i < trailBuffer.size(); ++i) {
grayscale[i] = static_cast<uint8_t>(trailBuffer[i] * 255.0f);
}
// Render grayscale buffer
glDrawPixels(WIDTH, HEIGHT, GL_LUMINANCE, GL_UNSIGNED_BYTE, grayscale.data());
}
};
@@ -158,16 +219,10 @@ private:
* @brief Main function that creates and runs the ReWindow application.
*/
int main() {
// Create the window using a smart pointer
auto window = std::make_unique<RandomWalkerWindow>("Random Walker with ReWindow", WIDTH, HEIGHT);
// Set the rendering API to OpenGL
window->SetRenderer(RenderingAPI::OPENGL);
// Open the window (this triggers OnOpen())
window->Open();
// Main event loop: Refreshes the window until it is closed
while (!window->IsClosing()) {
window->ManagedRefresh();
}