4 #include <QGraphicsScene>
5 #include <QGraphicsView>
7 #include <QRandomGenerator>
13 SnowFlake::SnowFlake(QGraphicsScene *scene, SnowType t)
17 size = QRandomGenerator::global()->bounded(10) + 3;
20 QRandomGenerator::global()->bounded(10) / 10.0 - 0.5,
21 QRandomGenerator::global()->bounded(10) / 10.0 + 1);
29 for (int a = 0; a < 6; a++) {
30 lines.append(scene->addLine(0, -s6, 0, -size));
31 lines.last()->setRotation(a * 60);
33 lines.append(scene->addLine(-s4, -size + s6, 0, -size + s3));
34 lines.last()->setRotation(a * 60);
36 lines.append(scene->addLine(s4, -size + s6, 0, -size + s3));
37 lines.last()->setRotation(a * 60);
40 foreach (QGraphicsLineItem *l, lines) {
43 l->setParentItem(this);
46 da = QRandomGenerator::global()->bounded(20) / 10.0 - 1;
48 setRotation(QRandomGenerator::global()->bounded(60));
51 disc = scene->addEllipse(0, 0, size, size, p);
52 disc->setParentItem(this);
53 disc->setBrush(Qt::white);
54 disc->setZValue(Z_SNOW);
57 disc = scene->addEllipse(0, 0, size, size * 1.5, p);
58 disc->setParentItem(this);
59 disc->setBrush(QColor(
60 QRandomGenerator::global()->bounded(100) + 150,
61 QRandomGenerator::global()->bounded(100) + 150,
62 QRandomGenerator::global()->bounded(100) + 150, 255));
63 disc->setZValue(Z_SNOW);
70 SnowFlake::~SnowFlake()
72 // qDebug()<<"Destr. SnowFlake";
75 while (lines.isEmpty())
76 delete lines.takeFirst();
89 QRectF SnowFlake::boundingRect() const
91 return QRectF(-size, -size, size * 2, size * 2);
94 void SnowFlake::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
98 void SnowFlake::animate()
100 moveBy(dv.x() + dblow.x(), dv.y() + dblow.y());
102 if (type == SnowFlake::Smilla)
103 setRotation(rotation() + da);
108 void SnowFlake::blow(const QPointF &v) { dblow = v; }
110 Winter::Winter(QGraphicsView *v)
116 test = view->scene()->addRect(
117 QRectF(viewRect.topLeft(), viewRect.bottomRight()),
121 type = SnowFlake::Egg;
124 case SnowFlake::Smilla:
141 animTimer = new QTimer;
142 connect(animTimer, SIGNAL(timeout()), this, SLOT(animate()));
143 animTimer->start(50);
145 snowTimer = new QTimer;
146 connect(snowTimer, SIGNAL(timeout()), this, SLOT(makeSnow()));
147 //snowTimer->setSingleShot(true);
156 while (!fallingSnow.isEmpty())
157 delete fallingSnow.takeFirst();
158 while (!frozenSnow.isEmpty())
159 delete frozenSnow.takeFirst();
162 void Winter::updateView()
164 QPointF topLeft = view->mapToScene(0, 0);
165 QPointF topRight = view->mapToScene(view->rect().width(), 0);
166 QPointF botLeft = view->mapToScene(0, view->rect().height());
168 view->mapToScene(view->rect().width(), view->rect().height());
173 topLeft.y() < topRight.y() ? p0.setY(topLeft.y()) : p0.setY(topRight.y());
174 topLeft.x() < topRight.x() ? p0.setX(topLeft.x()) : p0.setX(topRight.x());
176 botLeft.y() > botRight.y() ? p1.setY(botLeft.y()) : p1.setY(botRight.y());
177 botLeft.x() > botRight.x() ? p1.setX(botLeft.x()) : p1.setX(botRight.x());
179 viewRect = QRectF(p0, p1);
182 void Winter::setObstacles(QList<QRectF> obslist)
186 QList<SnowFlake *> unfreeze;
188 // Find frozen snowflakes, which are free again
192 while (i < frozenSnow.count()) {
193 p = frozenSnow.at(i)->pos();
197 while (j < obstacles.count() && !frozen)
200 if (obstacles.at(j).contains(p))
205 unfreeze.append(frozenSnow.at(i));
206 frozenSnow.removeAt(i);
212 // Remove some flakes, if too many
213 while (fallingSnow.count() + unfreeze.count() > maxFalling + maxUnfreeze)
214 delete unfreeze.takeFirst();
216 while (!unfreeze.isEmpty()) {
218 unfreeze.first()->blow(
220 QRandomGenerator::global()->bounded(10) / 10.0 - 0.5,
221 QRandomGenerator::global()->bounded(10) / 10.0 - 5));
222 fallingSnow.append(unfreeze.takeFirst());
226 void Winter::animate()
228 // test->setRect(QRectF(viewRect.topLeft(), viewRect.bottomRight()));
233 while (i < fallingSnow.count()) {
234 p = fallingSnow.at(i)->pos();
238 while (j < obstacles.count() && cont) {
239 if (obstacles.at(j).contains(p) &&
240 QRandomGenerator::global()->bounded(obstacles.count() + 1) > obstacles.count() - 1) {
241 // Freeze snowflake on obstacle
242 // Probality is equale for obstacles or falling through
243 frozenSnow.append(fallingSnow.at(i));
244 fallingSnow.removeAt(i);
249 if (cont && p.y() > viewRect.bottomRight().y() + 20)
252 delete fallingSnow.takeAt(i);
255 // Let snowflake fall further
257 fallingSnow.at(i)->animate();
262 void Winter::makeSnow()
264 // qDebug()<<"falling: "<<fallingSnow.count()<<" frozen:
265 // "<<frozenSnow.count();
266 if (fallingSnow.count() + frozenSnow.count() < maxFlakes) {
267 if (fallingSnow.count() < maxFalling) {
268 // Create more snowflakes
269 SnowFlake *snowflake;
270 for (int i = 0; i < 10; i++) {
271 snowflake = new SnowFlake(view->scene(), type);
272 view->scene()->addItem(snowflake);
273 snowflake->setPos(rand() % round_int(viewRect.width()) +
276 fallingSnow.append(snowflake);
281 // Remove some of the existing frozen flakes
282 for (int i = 0; i < 10; i++) {
283 if (frozenSnow.count() > 0) {
284 int j = QRandomGenerator::global()->bounded(frozenSnow.count());
285 delete frozenSnow.takeAt(j);
289 snowTimer->start(2000);