A4/main.cpp
2024-11-06 16:59:40 -07:00

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;
}