127 lines
4.3 KiB
C++
127 lines
4.3 KiB
C++
/**
|
|
* @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 <chrono>
|
|
#include <iostream>
|
|
#include <limits>
|
|
#include <random>
|
|
|
|
#include <SFML/Audio.hpp>
|
|
#include <SFML/Graphics.hpp>
|
|
#include <SFML/System/Clock.hpp>
|
|
#include <SFML/Window/Event.hpp>
|
|
#include <SFML/Window/Keyboard.hpp>
|
|
|
|
#include "Bubble.h"
|
|
|
|
int main() {
|
|
sf::RenderWindow window(sf::VideoMode(1280, 640), "Tyler Beckman A4");
|
|
window.setVerticalSyncEnabled(true);
|
|
|
|
std::shared_ptr<sf::Music> boingSound = std::make_shared<sf::Music>();
|
|
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<unsigned int> colorDist(0, 255);
|
|
std::uniform_int_distribution<unsigned int> positionDist(100, 400);
|
|
std::uniform_int_distribution<unsigned int> radiusDist(10, 50);
|
|
// numeric_limits::min() necessary to make real distribution functionally inclusive
|
|
std::uniform_real_distribution<double> speedDist(-0.1667, 0.1667 + std::numeric_limits<double>::min());
|
|
|
|
std::vector<Bubble> 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;
|
|
}
|