6 #include <QGraphicsScene>
7 #include <QGraphicsView>
10 SnowFlake::SnowFlake(QGraphicsScene *scene)
18 for (int a=0; a<6; a++)
20 lines.append(scene->addLine(0, -s6, 0, -size));
21 lines.last()->setRotation(a*60);
23 lines.append(scene->addLine(-s4, -size + s6, 0, -size + s3));
24 lines.last()->setRotation(a*60);
26 lines.append(scene->addLine( s4, -size + s6, 0, -size + s3));
27 lines.last()->setRotation(a*60);
31 foreach (QGraphicsLineItem *l, lines)
35 l->setParentItem(this);
37 dv=QPointF(qrand()%10/10.0-0.5, qrand()%10/10.0 +1);
38 da=qrand()%20 / 10.0 - 1;
41 SnowFlake::~SnowFlake()
43 //qDebug()<<"Destr. SnowFlake";
44 while(lines.isEmpty())
45 delete lines.takeFirst();
48 QRectF SnowFlake::boundingRect() const
50 return QRectF (-size, -size, size*2, size*2);
53 void SnowFlake::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
57 void SnowFlake::animate()
59 moveBy(dv.x() + dblow.x(), dv.y() + dblow.y());
60 setRotation(rotation() + da);
64 void SnowFlake::blow(const QPointF &v)
69 Winter::Winter(QGraphicsView *v)
75 test=view->scene()->addLine(
76 QLineF(viewRect.topLeft(), viewRect.bottomRight()),
86 animTimer = new QTimer;
87 connect (animTimer, SIGNAL (timeout()), this, SLOT (animate() ));
90 snowTimer = new QTimer;
91 connect (snowTimer, SIGNAL (timeout()), this, SLOT (makeSnow() ));
92 snowTimer->start(1000);
99 while (!fallingSnow.isEmpty())
100 delete fallingSnow.takeFirst();
101 while (!frozenSnow.isEmpty())
102 delete frozenSnow.takeFirst();
105 void Winter::updateView()
107 QPointF p0=view->mapToScene( QPoint(0,0));
108 QPointF p1=view->mapToScene( view->rect().width(), view->rect().height() );
109 viewRect=QRectF(p0,p1);
112 void Winter::setObstacles(QList <QRectF> obslist)
116 QList <SnowFlake*> unfreeze;
118 // Find frozen snowflakes, which are free again
122 while (i < frozenSnow.count())
124 p=frozenSnow.at(i)->pos();
128 while (j<obstacles.count() && !frozen)
131 if (obstacles.at(j).contains(p) )
137 unfreeze.append(frozenSnow.at(i));
138 frozenSnow.removeAt(i);
143 // Remove some flakes, if too many
144 while (fallingSnow.count() + unfreeze.count() > maxFalling + maxUnfreeze)
145 delete unfreeze.takeFirst();
147 while (!unfreeze.isEmpty())
150 unfreeze.first()->blow( QPointF(qrand()%10/10.0-0.5, qrand()%10/10.0 -5));
151 fallingSnow.append(unfreeze.takeFirst());
156 void Winter::animate()
159 //test->setLine(QLineF(viewRect.topLeft(), viewRect.bottomRight()));
164 while (i<fallingSnow.count())
166 p=fallingSnow.at(i)->pos();
170 while (j<obstacles.count() && cont)
172 if (obstacles.at(j).contains(p) && qrand()%(obstacles.count()+1) > obstacles.count()-1)
174 // Freeze snowflake on obstacle
175 // Probality is equale for obstacles or falling through
176 frozenSnow.append(fallingSnow.at(i));
177 fallingSnow.removeAt(i);
182 if (cont && p.y() > viewRect.y() + viewRect.height() + 20)
184 delete fallingSnow.takeAt(i);
187 // Let snowflake fall further
188 if (cont) fallingSnow.at(i)->animate();
193 void Winter::makeSnow()
195 //qDebug()<<"falling: "<<fallingSnow.count()<<" frozen: "<<frozenSnow.count();
196 if (fallingSnow.count() + frozenSnow.count() <maxFlakes)
198 if (fallingSnow.count() < maxFalling)
200 // Create more snowflakes
201 SnowFlake *snowflake;
202 for (int i=0; i<10; i++)
204 snowflake=new SnowFlake(view->scene());
205 snowflake->setPos( 0,0);
206 snowflake->setRotation(qrand()%60);
207 view->scene()->addItem(snowflake);
209 rand()%round_int(viewRect.width()) + viewRect.x(),
212 fallingSnow.append(snowflake);
217 // Remove some of the existing frozen flakes
218 for (int i=0; i<10; i++)
220 if (frozenSnow.count()>0)
222 int j=qrand()%frozenSnow.count();
223 delete frozenSnow.takeAt(j);