/** * @author Tyler Beckman (tyler_beckman@mines.edu) * @brief A program to simulate bubbles bouncing around the screen with random sizes, colors, * and speeds (with sound effects!). Bubbles can be created with left click and removed with * D. Program will exit if Esc or Q are pressed. * @version 1 * @date 2024-11-05 */ #include #include #include #include #include #include #include #include #include #include "Bubble.h" int main() { sf::RenderWindow window(sf::VideoMode(1280, 640), "Tyler Beckman A4"); window.setVerticalSyncEnabled(true); std::shared_ptr boingSound = std::make_shared(); if (!boingSound->openFromFile("data/boing.mp3")) { std::cerr << "Unable to load data/boing.mp3" << std::endl; return -1; } boingSound->setPitch(1.25); sf::Music popSound; if (!popSound.openFromFile("data/pop.mp3")) { std::cerr << "Unable to load data/pop.mp3" << std::endl; return -1; } sf::Clock clock; sf::Event event; std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count()); std::uniform_int_distribution colorDist(0, 255); std::uniform_int_distribution positionDist(100, 400); std::uniform_int_distribution radiusDist(10, 50); // numeric_limits::min() necessary to make real distribution functionally inclusive std::uniform_real_distribution speedDist(-0.1667, 0.1667 + std::numeric_limits::min()); std::vector bubbles; for (int i = 0; i < 5; i++) { bubbles.push_back( Bubble( positionDist(mt), positionDist(mt), speedDist(mt), speedDist(mt), radiusDist(mt), sf::Color( colorDist(mt), colorDist(mt), colorDist(mt) ), boingSound ) ); } while (window.isOpen()) { window.clear(); for (size_t i = 0; i < bubbles.size(); i++) { bubbles.at(i).draw(window); } window.display(); while (window.pollEvent(event)) { switch (event.type) { case sf::Event::Closed: window.close(); break; case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::Key::Escape || event.key.code == sf::Keyboard::Key::Q) { window.close(); } else if (event.key.code == sf::Keyboard::Key::D && bubbles.size() > 0) { popSound.play(); // pop_back segfaults on a 0-sized vector so the extra check is needed bubbles.pop_back(); } break; case sf::Event::MouseButtonPressed: if (event.mouseButton.button == sf::Mouse::Button::Left) { unsigned int radius = radiusDist(mt); bubbles.push_back( Bubble( // Subtracting radius from mouse button ensures the bubble is in the middle of the cursor event.mouseButton.x - radius, event.mouseButton.y - radius, speedDist(mt), speedDist(mt), radius, sf::Color( colorDist(mt), colorDist(mt), colorDist(mt) ), boingSound ) ); } break; default: break; } } if (clock.getElapsedTime().asSeconds() >= (1./60)) { clock.restart(); for (size_t i = 0; i < bubbles.size(); i++) { bubbles.at(i).updatePosition(window.getSize().x, window.getSize().y); } } } return 0; }