Last active
November 26, 2017 21:03
-
-
Save Sam-Belliveau/edd8558d057495cdf2ed7cf0994514a2 to your computer and use it in GitHub Desktop.
You need sfml to run this. Change line 25 to change particals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
CONTROLS: | |
Up - Move Up | |
Down - Move Down | |
Left - Move Left | |
Right - Move Right | |
W - Zoom In | |
S - Zoom Out | |
Left Click - Attract | |
Right Click - Expand | |
*/ | |
/* Include */ | |
#include <SFML/Graphics.hpp> // For making art | |
#include <cmath> // abs, sqrt, fmaxf | |
#include <vector> // FOR VECTORS | |
#include <omp.h> | |
/* VARS */ | |
// Amount of particals | |
const float amount = 1000000; | |
// Speed of actions | |
const float force = 512; | |
const float speed = 512; | |
const float zoomSpeed = 1; | |
// Minimums | |
const float minZoom = 0.0625; | |
const float minDis = 0.5; | |
// Window | |
const int width = 1280; | |
const int height = 720; | |
// Halfs (for cam) | |
const float widthHalf = width / 2; | |
const float heightHalf = height / 2; | |
const float sqrtHalf = sqrt(amount) / 2; | |
// Mouse States | |
enum mousePosition { none, away, closer }; | |
// Camera data | |
struct camData | |
{ | |
sf::Vector2f offSet = sf::Vector2f(0, 0); | |
float zoom = 1; | |
}; camData cam; | |
// Vel and Pos of a partical | |
struct particalData | |
{ | |
sf::Vector2f pos = sf::Vector2f(0, 0); | |
sf::Vector2f vel = sf::Vector2f(0, 0); | |
}; std::vector<particalData> particals; | |
// What you draw too | |
sf::VertexArray drawBuffer = sf::VertexArray(sf::Points, amount); | |
// The Window | |
sf::RenderWindow app(sf::VideoMode(width, height), "Particals", sf::Style::Close); | |
/* METHODS */ | |
void reset() | |
{ | |
// Reset Camera | |
cam.offSet = sf::Vector2f(sqrtHalf - widthHalf, sqrtHalf - heightHalf); | |
cam.zoom = 1; | |
// Clear Particals | |
particals.clear(); | |
for (unsigned long i = 0; i < amount; i++) | |
{ | |
particalData temp; | |
// Set Position In a Square | |
temp.pos.x = (float)(i % (long)sqrt(amount)); | |
temp.pos.y = (float)((i - (i % (long)sqrt(amount))) / sqrt(amount)); | |
// COLORS!! | |
drawBuffer[i].color = sf::Color((temp.pos.x * 255.f) / sqrt(amount), (temp.pos.y * 255.f) / sqrt(amount), 255.f - ((temp.pos.x * 255.f) / sqrt(amount))); | |
// Allocate one by one to prevent overflow | |
particals.push_back(temp); | |
} | |
} | |
void draw(mousePosition mouse, sf::Vector2i &mousePosition, float fps) | |
{ | |
if (mouse == mousePosition::none) // mouse up | |
{ | |
#pragma omp parallel for | |
for (unsigned long i = 0; i < amount; i++) | |
{ | |
// move partical | |
particals[i].pos.x += particals[i].vel.x / fps; | |
particals[i].pos.y += particals[i].vel.y / fps; | |
// show partical based on camera | |
drawBuffer[i].position.x = (particals[i].pos.x - cam.offSet.x) / cam.zoom; | |
drawBuffer[i].position.y = (particals[i].pos.y - cam.offSet.y) / cam.zoom; | |
} | |
} else | |
{ | |
if (mouse == mousePosition::closer) | |
{ | |
#pragma omp parallel for | |
for (unsigned long i = 0; i < amount; i++) | |
{ | |
// Calculate mouse with camera stuff | |
const float mouseX = (float)mousePosition.x * cam.zoom + cam.offSet.x; | |
const float mouseY = (float)mousePosition.y * cam.zoom + cam.offSet.y; | |
// So access is faster | |
const float posX = particals[i].pos.x; | |
const float posY = particals[i].pos.y; | |
// Since we use abs() we half to find what side the mouse is on | |
const bool sideX = posX > mouseX; | |
const bool sideY = posY > mouseY; | |
// Distance of x and y | |
const float disX = abs(posX - mouseX); | |
const float disY = abs(posY - mouseY); | |
// Get a greak guy to use a ruler | |
const float dis = sqrt((disX*disX) + (disY*disY)); | |
// find ratio AKA direction | |
const float rat = ((disX * cam.zoom * force) / (disX + disY)) / dis; | |
const float invertRat = ((cam.zoom * force) / dis) - rat; | |
// if the mouse is right click, flip distance and make it go away | |
// MAGIC | |
// move the vel with formula | |
if (sideX) { particals[i].vel.x -= rat; } | |
else { particals[i].vel.x += rat; } | |
if (sideY) { particals[i].vel.y -= invertRat; } | |
else { particals[i].vel.y += invertRat; } | |
// actually update partical | |
particals[i].pos.x += particals[i].vel.x / fps; | |
particals[i].pos.y += particals[i].vel.y / fps; | |
// move the drawn partical | |
drawBuffer[i].position.x = (particals[i].pos.x - cam.offSet.x) / cam.zoom; | |
drawBuffer[i].position.y = (particals[i].pos.y - cam.offSet.y) / cam.zoom; | |
} | |
} else | |
{ | |
#pragma omp parallel for | |
for (unsigned long i = 0; i < amount; i++) | |
{ | |
// Calculate mouse with camera stuff | |
const float mouseX = (float)mousePosition.x * cam.zoom + cam.offSet.x; | |
const float mouseY = (float)mousePosition.y * cam.zoom + cam.offSet.y; | |
// So access is faster | |
const float posX = particals[i].pos.x; | |
const float posY = particals[i].pos.y; | |
// Since we use abs() we half to find what side the mouse is on | |
const bool sideX = posX > mouseX; | |
const bool sideY = posY > mouseY; | |
// Distance of x and y | |
const float disX = abs(posX - mouseX); | |
const float disY = abs(posY - mouseY); | |
// Get a greak guy to use a ruler | |
const float dis = sqrt((disX*disX) + (disY*disY)); | |
// find ratio AKA direction | |
const float rat = ((disX * cam.zoom * force) / (disX + disY)) / dis; | |
const float invertRat = ((cam.zoom * force) / dis) - rat; | |
// if the mouse is right click, flip distance and make it go away | |
// MAGIC | |
// move the vel with formula | |
if (sideX) { particals[i].vel.x += rat; } | |
else { particals[i].vel.x -= rat; } | |
if (sideY) { particals[i].vel.y += invertRat; } | |
else { particals[i].vel.y -= invertRat; } | |
// actually update partical | |
particals[i].pos.x += particals[i].vel.x / fps; | |
particals[i].pos.y += particals[i].vel.y / fps; | |
// move the drawn partical | |
drawBuffer[i].position.x = (particals[i].pos.x - cam.offSet.x) / cam.zoom; | |
drawBuffer[i].position.y = (particals[i].pos.y - cam.offSet.y) / cam.zoom; | |
} | |
} | |
} | |
app.draw(drawBuffer); // TAKE A GUESS | |
} | |
int main() | |
{ | |
sf::ContextSettings settings; | |
settings.antialiasingLevel = 16; | |
app.create(sf::VideoMode(width, height), "Particals", sf::Style::Close, settings); | |
reset(); | |
// FPS STUFF YAY | |
// MAKES STUFF CONSISTANT | |
sf::Clock clock; | |
float currentTime = clock.restart().asSeconds(); | |
float fps = 1.f / currentTime; | |
while (app.isOpen()) | |
{ | |
// Process events | |
sf::Event event; | |
while (app.pollEvent(event)) | |
{ | |
// Close window : exit | |
if (event.type == sf::Event::Closed) | |
app.close(); | |
} | |
// Controls | |
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) | |
{ | |
reset(); | |
} if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) | |
{ | |
cam.offSet.y -= (speed*cam.zoom) / fps; | |
} if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) | |
{ | |
cam.offSet.y += (speed*cam.zoom) / fps; | |
} if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) | |
{ | |
cam.offSet.x -= (speed*cam.zoom) / fps; | |
} if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) | |
{ | |
cam.offSet.x += (speed*cam.zoom) / fps; | |
} if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) | |
{ | |
if (cam.zoom > minZoom) | |
{ | |
cam.zoom /= 1.f + zoomSpeed / fps; | |
} | |
} if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) | |
{ | |
cam.zoom *= 1.f + zoomSpeed / fps; | |
} | |
// Clear screen | |
app.clear(); | |
// Move Particals | |
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) | |
{ | |
draw(mousePosition::closer, sf::Mouse::getPosition(app), fps); | |
} else if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) | |
{ | |
draw(mousePosition::away, sf::Mouse::getPosition(app), fps); | |
} else | |
{ | |
draw(mousePosition::none, sf::Vector2i(), fps); | |
} | |
// Update the window | |
app.display(); | |
currentTime = clock.restart().asSeconds(); | |
fps = 1.f / currentTime; | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
SICK