-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExplosion.cc
143 lines (140 loc) · 6.07 KB
/
Explosion.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "Explosion.h"
Explosion::Explosion(bool isPolychromy, short xCenterCoordinate, short yCenterCoordinate, short explosionRadius, short explosionRadialSpeed, struct timespec currentTime)
{
this->isPolychromy = isPolychromy;
this->xCenterCoordinate = xCenterCoordinate;
this->yCenterCoordinate = yCenterCoordinate;
this->finalExplosionRadius = explosionRadius;
this->currentExplosionRadius = 0;
this->updateTimeStep.tv_sec = 0;
this->updateTimeStep.tv_nsec = 999999998 / explosionRadialSpeed;
this->updateTime.tv_sec = currentTime.tv_sec;
this->updateTime.tv_nsec = currentTime.tv_nsec;
}
void Explosion::printNextStep(struct timespec currentTime)
{
if ((currentTime.tv_sec * 1000000000 + currentTime.tv_nsec) >= (updateTime.tv_sec * 1000000000 + updateTime.tv_nsec)) //Условие отрисовки следующего шага взрыва.
{
short directionSwitch; //Отвечает за направление, в котором будет производиться печать (регулирует изменения координат).
short directionCounter; //Счетчик, переключающий directionSwitch через определенное число итераций цикла печати.
short yCoordinate; //Координата печатаемого символа по оси OY.
short xCoordinate; //Координата печатаемого символа по оси OX.
short yMaxCoordinate; //Максимальная координата по оси OY (печать по данной координате недопустима).
short xMaxCoordinate; //Максимальная координата по оси OX (печать по данной координате недопустима).
getmaxyx(stdscr, yMaxCoordinate, xMaxCoordinate); //Получение значений yMaxCoordinate и xMaxCoordinate.
if (currentExplosionRadius > 0) //Условие необходимости затирания прошлого контура взрыва.
{
short nRandomSymbolsAtPreviousStep = currentExplosionRadius * 4; //Необходимое количество случайных символов для отображения взрыва на прошлом шаге.
directionSwitch = 0;
directionCounter = 0;
yCoordinate = yCenterCoordinate;
xCoordinate = xCenterCoordinate - currentExplosionRadius;
for (short i = 0; i < nRandomSymbolsAtPreviousStep; i++)
{
if ((yCoordinate >= 0) && (xCoordinate >= 0) && (yCoordinate < yMaxCoordinate) && (xCoordinate < xMaxCoordinate))
{
mvaddch(yCoordinate, xCoordinate, ' ');
}
switch (directionSwitch)
{
case 0: //Направление положительное по оси OX и отрицательное по оси OY (Ось OY направлена вниз).
{
yCoordinate--;
xCoordinate++;
break;
}
case 1: //Направление положительное по осям OX и OY.
{
yCoordinate++;
xCoordinate++;
break;
}
case 2: //Направление положительное по оси OY и отрицательное по оси OX.
{
yCoordinate++;
xCoordinate--;
break;
}
case 3: //Направление отрицательное по осям OX и OY.
{
yCoordinate--;
xCoordinate--;
}
}
if (directionCounter == currentExplosionRadius - 1)
{
directionCounter = -1;
directionSwitch++;
}
directionCounter++;
}
}
currentExplosionRadius++; //Печать нового контура взрыва.
if (currentExplosionRadius > finalExplosionRadius) //Если радиус нового взрыва больше максимально допустимого - весь взрыв был отрисован и пора освободить от него память.
{
throw ExplosionException("The explosion has completed its task.");
}
short nRandomSymbolsAtThisStep = currentExplosionRadius * 4; //Необходимое количество случайных символов для отображения взрыва на данном шаге.
RandomSymbol* temp = nullptr;
directionSwitch = 0;
directionCounter = 0;
yCoordinate = yCenterCoordinate;
xCoordinate = xCenterCoordinate - currentExplosionRadius;
for (short i = 0; i < nRandomSymbolsAtThisStep; i++)
{
if ((yCoordinate >= 0) && (xCoordinate >= 0) && (yCoordinate < yMaxCoordinate) && (xCoordinate < xMaxCoordinate))
{
temp = new RandomSymbol(isPolychromy);
temp->printRandomSymbol(yCoordinate, xCoordinate);
delete temp;
temp = nullptr;
}
switch (directionSwitch)
{
case 0: //Направление положительное по оси OX и отрицательное по оси OY (Ось OY направлена вниз).
{
yCoordinate--;
xCoordinate++;
break;
}
case 1: //Направление положительное по осям OX и OY.
{
yCoordinate++;
xCoordinate++;
break;
}
case 2: //Направление положительное по оси OY и отрицательное по оси OX.
{
yCoordinate++;
xCoordinate--;
break;
}
case 3: //Направление отрицательное по осям OX и OY.
{
yCoordinate--;
xCoordinate--;
}
}
if (directionCounter == currentExplosionRadius - 1)
{
directionCounter = -1;
directionSwitch++;
}
directionCounter++;
}
if (updateTimeStep.tv_nsec + currentTime.tv_nsec > 999999998) //Перезапись времени обновления. Данное условие отвечает за корректную запись времени.
{
updateTime.tv_sec = currentTime.tv_sec + 1;
updateTime.tv_nsec = abs(updateTimeStep.tv_nsec + currentTime.tv_nsec - 1000000000);
}
else
{
updateTime.tv_sec = currentTime.tv_sec;
updateTime.tv_nsec = updateTimeStep.tv_nsec + currentTime.tv_nsec;
}
}
}
struct timespec Explosion::getUpdateTime()
{
return updateTime;
}