nsnake
Classic snake game for the terminal
Loading...
Searching...
No Matches
AnimationFire.cpp
1#include <Display/Animations/AnimationFire.hpp>
2#include <Engine/Graphics/Colors.hpp>
3#include <Engine/Helpers/Utils.hpp>
4
5static ColorPair red = Colors::pair("red", "default");
6static ColorPair redBold = Colors::pair("red", "default", true);
7static ColorPair white;
8static ColorPair yellow = Colors::pair("yellow", "default");
9static ColorPair yellowBold = Colors::pair("yellow", "default", true);
10
11// An ASCII gray scale :)
12// Characters will be accessed proportionally to the intensity
13// int gray_scale_size = 70;
14// char gray_scale[71] = ".\'`^\",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$ ";
15
16static int gray_scale_size = 12;
17static char gray_scale[13] = " .':-=+*#%@#";
18
19AnimationFire::AnimationFire(Window* window):
20 Animation(window),
21 particle(NULL)
22{ }
23AnimationFire::~AnimationFire()
24{
25 SAFE_DELETE(particle);
26}
27void AnimationFire::load()
28{
29 unsigned int width = window->getW();
30 unsigned int height = window->getH();
31
32 particle = new Array2D<ParticleFire>(width, height);
33
34 // Creating the cooling map
35 coolingMap = new Array2D<int>(width, height);
36
37 for (unsigned int i = 0; i < width; i++)
38 for (unsigned int j = 0; j < height; j++)
39 coolingMap->set(i, j, Utils::Random::between(INTENSITY_MIN,
40 INTENSITY_PERCENT(13)));
41
42 // Will smooth the cooling map a number of times
43 for (int n = 0; n < 10; n++)
44 for (unsigned int i = 1; i < width-1; i++)
45 for (unsigned int j = 1; j < height-1; j++)
46 coolingMap->set(i, j, (coolingMap->at(i-1, j) +
47 coolingMap->at(i+1, j) +
48 coolingMap->at(i, j+1) +
49 coolingMap->at(i, j-1)) / 4);
50
51 timer.start();
52}
53void AnimationFire::update()
54{
55 // Updating only at the right time!
56 if (timer.delta_ms() < 100)
57 return;
58
59 // How fast the fire cools down each frame
60 int cooling_ratio = Utils::Random::between(INTENSITY_PERCENT(3),
61 INTENSITY_PERCENT(12));
62
63 // Slim chance of a sudden burst or dim of the fire
64 bool burst = Utils::Random::booleanWithChance(0.10);
65 bool dim = Utils::Random::booleanWithChance(0.12);
66 if (burst) cooling_ratio = INTENSITY_PERCENT(1);
67 if (dim) cooling_ratio = INTENSITY_PERCENT(30);
68
69 // Spawning high-intensity flames on the bottom particles
70 for (unsigned int i = 0; i < (particle->width()); i++)
71 particle->set(i, particle->height() - 1, ParticleFire(Utils::Random::between(INTENSITY_PERCENT(90), INTENSITY_MAX)));
72
73 // Randomly adding Sparks - high-intensity flames little higher
74 for (unsigned int i = 0; i < (particle->width()); i++)
75 {
76 if (Utils::Random::booleanWithChance(2.31))
77 {
78 int height = particle->height() - Utils::Random::between(3, 6);
79
80 particle->set(i, height, ParticleFire(Utils::Random::between(INTENSITY_PERCENT(90), INTENSITY_MAX)));
81 }
82 }
83
84 // Making all particles climb up
85 for (unsigned int i = 0; i < (particle->width()); i++)
86 {
87 for (unsigned int j = 0; j < (particle->height()-1); j++)
88 {
89 // Cooling all particles based on the ones below
90 particle->set(i, j, ParticleFire(particle->at(i, j + 1).intensity - cooling_ratio));
91
92 // Cooling based on the cooling map
93 particle->set(i, j, ParticleFire(particle->at(i, j).intensity - coolingMap->at(i, j)));
94 }
95 }
96
97 timer.start();
98}
99void AnimationFire::draw()
100{
101 for (unsigned int i = 0; i < (particle->width()); i++)
102 {
103 for (unsigned int j = 0; j < (particle->height()); j++)
104 {
105 int c = ' ';
106 ColorPair p = white;
107 int s = particle->at(i, j).intensity;
108
109 if (s > INTENSITY_PERCENT(90))
110 p = white;
111
112 else if (s > INTENSITY_PERCENT(80))
113 p = yellowBold;
114
115 else if (s > INTENSITY_PERCENT(70))
116 p = yellowBold;
117
118 else if (s > INTENSITY_PERCENT(60))
119 p = yellow;
120
121 else if (s > INTENSITY_PERCENT(50))
122 p = redBold;
123
124 else if (s > INTENSITY_PERCENT(40))
125 p = redBold;
126
127 else if (s > INTENSITY_PERCENT(30))
128 p = red;
129
130 else if (s > INTENSITY_PERCENT(20))
131 p = red;
132
133 else
134 continue; // Too low intensity
135
136
137 if ((s > INTENSITY_MAX) || (s < INTENSITY_MIN))
138 continue;
139
140 else
141 c = gray_scale[(s - INTENSITY_MIN) * (gray_scale_size-1)/INTENSITY_MAX];
142
143 window->printChar(c, i, j, p);
144 }
145 }
146}
147
A single particle inside the whole fire.