Skip to content
Snippets Groups Projects
Commit 4bfa1b8f authored by bartvbl's avatar bartvbl
Browse files

Added lecture 15 handout

parent 1c4fa92d
No related branches found
No related tags found
No related merge requests found
#include <vector>
#include <random>
#include "AnimationWindow.h"
struct Point2D {
double x = 0;
double y = 0;
};
struct Direction2D {
double x = 0;
double y = 0;
};
constexpr double gravity = 0.1;
constexpr double explosionPower = 2.0;
struct Rocket {
std::vector<Point2D> particleLocations;
std::vector<Direction2D> particleDirections;
bool hasExploded = false;
bool hasEnded = false;
int fadeTimeRemaining = 1000;
TDT4102::Color colour;
Rocket() {}
Rocket(int particleCount, int fadeTime, Point2D start, Direction2D launchDirection, TDT4102::Color colour) :
fadeTimeRemaining(fadeTime),
colour(colour),
particleLocations(particleCount, start),
particleDirections(particleCount, launchDirection) {}
void update() {
if(hasExploded && fadeTimeRemaining == 0) {
hasEnded = true;
} else if(hasExploded) {
fadeTimeRemaining--;
} else if(particleDirections.at(0).y > 0 && !hasExploded) {
hasExploded = true;
std::random_device device;
std::default_random_engine engine(device());
std::uniform_real_distribution directionDist(0.0, M_PI * 2.0);
std::uniform_real_distribution powerDist(0.0, explosionPower * explosionPower);
for(unsigned int i = 0; i < particleLocations.size(); i++) {
// Choose a random direction and velocity for each particle in the rocket
double angle = directionDist(engine);
double power = powerDist(engine);
// This results in a more even spread of particles
power = sqrt(power);
// Using sine and cosine gives us a vector of length 1,
// which we multiply by the power
particleDirections.at(i).x = cos(angle) * power;
constexpr int bonusVerticalForce = 4;
particleDirections.at(i).y = sin(angle) * power - bonusVerticalForce;
}
}
if(!hasEnded) {
for(unsigned int i = 0; i < particleDirections.size(); i++) {
particleDirections.at(i).y += gravity;
}
for(unsigned int i = 0; i < particleLocations.size(); i++) {
particleLocations.at(i).x += particleDirections.at(i).x;
particleLocations.at(i).y += particleDirections.at(i).y;
}
if(hasExploded) {
if(colour.redChannel > 1) { colour.redChannel-=2; }
if(colour.greenChannel > 1) { colour.greenChannel-=2; }
if(colour.blueChannel > 1) { colour.blueChannel-=2; }
if(colour.redChannel < 2 && colour.greenChannel < 2 && colour.blueChannel < 2) {
hasEnded = true;
}
}
}
}
bool isComplete() {
return hasEnded;
}
void draw(TDT4102::AnimationWindow &window) {
for(unsigned int i = 0; i < particleLocations.size(); i++) {
Point2D location = particleLocations.at(i);
constexpr int particleWidthPixels = 2;
constexpr int particleHeightPixels = 2;
window.draw_rectangle({int(location.x), int(location.y)}, particleWidthPixels, particleHeightPixels, colour);
}
}
};
int main() {
constexpr int rocketCount = 300;
constexpr int particleCount = 500;
constexpr int defaultFadeTime = 250;
constexpr double minVerticalSpeed = 7.0;
constexpr double maxVerticalSpeed = 12.0;
TDT4102::AnimationWindow window;
std::vector<Rocket> rockets;
rockets.resize(rocketCount);
std::random_device device;
std::default_random_engine engine(device());
std::uniform_int_distribution xDist(0, window.width());
std::uniform_real_distribution speedDist(-minVerticalSpeed, -maxVerticalSpeed);
std::uniform_int_distribution colourChannelDist(0, 255);
for(unsigned int i = 0; i < rockets.size(); i++) {
TDT4102::Color randomColour(colourChannelDist(engine), colourChannelDist(engine), colourChannelDist(engine));
rockets.at(i) = Rocket(particleCount, defaultFadeTime, {(double)xDist(engine), (double) window.height()}, {0.0, speedDist(engine)}, randomColour);
}
while(!window.should_close()) {
window.draw_rectangle({0, 0}, window.width(), window.height(), TDT4102::Color::black);
for(unsigned int i = 0; i < rockets.size(); i++) {
if(!rockets.at(i).isComplete()) {
rockets.at(i).update();
rockets.at(i).draw(window);
} else {
TDT4102::Color randomColour(colourChannelDist(engine), colourChannelDist(engine), colourChannelDist(engine));
std::uniform_int_distribution xDist(0, window.width());
rockets.at(i) = Rocket(particleCount, defaultFadeTime, {(double)xDist(engine), (double) window.height()}, {0.0, speedDist(engine)}, randomColour);
}
}
constexpr int estimatedTextWidth = 1000;
constexpr int estimatedTextHeight = 200;
constexpr int fontSize = 96;
window.draw_text({window.width() / 2 - estimatedTextWidth / 2, window.height() / 2 - estimatedTextHeight / 2}, "Good luck on the exam!", TDT4102::Color::white, fontSize, TDT4102::Font::arial_bold);
window.next_frame();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment