00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "mouse.h"
00038
00039 #include "mouse.moc"
00040
00041 #include <QGraphicsScene>
00042 #include <QPainter>
00043 #include <QStyleOption>
00044
00045 #include <math.h>
00046
00047 static const double Pi = 3.14159265358979323846264338327950288419717;
00048 static double TwoPi = 2.0 * Pi;
00049
00050 static qreal normalizeAngle(qreal angle)
00051 {
00052 while (angle < 0)
00053 angle += TwoPi;
00054 while (angle > TwoPi)
00055 angle -= TwoPi;
00056 return angle;
00057 }
00058
00059 Mouse::Mouse()
00060 : angle(0), speed(0), mouseEyeDirection(0),
00061 color(qrand() % 256, qrand() % 256, qrand() % 256)
00062 {
00063 rotate(qrand() % (360 * 16));
00064 startTimer(1000 / 33);
00065 }
00066
00067 QRectF Mouse::boundingRect() const
00068 {
00069 qreal adjust = 0.5;
00070 return QRectF(-18 - adjust, -22 - adjust,
00071 36 + adjust, 60 + adjust);
00072 }
00073
00074 QPainterPath Mouse::shape() const
00075 {
00076 QPainterPath path;
00077 path.addRect(-10, -20, 20, 40);
00078 return path;
00079 }
00080
00081 void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
00082 {
00083
00084 painter->setBrush(color);
00085 painter->drawEllipse(-10, -20, 20, 40);
00086
00087
00088 painter->setBrush(Qt::white);
00089 painter->drawEllipse(-10, -17, 8, 8);
00090 painter->drawEllipse(2, -17, 8, 8);
00091
00092
00093 painter->setBrush(Qt::black);
00094 painter->drawEllipse(QRectF(-2, -22, 4, 4));
00095
00096
00097 painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4));
00098 painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4));
00099
00100
00101 painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red);
00102 painter->drawEllipse(-17, -12, 16, 16);
00103 painter->drawEllipse(1, -12, 16, 16);
00104
00105
00106 QPainterPath path(QPointF(0, 20));
00107 path.cubicTo(-5, 22, -5, 22, 0, 25);
00108 path.cubicTo(5, 27, 5, 32, 0, 30);
00109 path.cubicTo(-5, 32, -5, 42, 0, 35);
00110 painter->setBrush(Qt::NoBrush);
00111 painter->drawPath(path);
00112 }
00113
00114 void Mouse::timerEvent(QTimerEvent *)
00115 {
00116
00117 QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0));
00118 if (lineToCenter.length() > 150) {
00119 qreal angleToCenter = ::acos(lineToCenter.dx() / lineToCenter.length());
00120 if (lineToCenter.dy() < 0)
00121 angleToCenter = TwoPi - angleToCenter;
00122 angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2);
00123
00124 if (angleToCenter < Pi && angleToCenter > Pi / 4) {
00125
00126 angle += (angle < -Pi / 2) ? 0.25 : -0.25;
00127 } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) {
00128
00129 angle += (angle < Pi / 2) ? 0.25 : -0.25;
00130 }
00131 } else if (::sin(angle) < 0) {
00132 angle += 0.25;
00133 } else if (::sin(angle) > 0) {
00134 angle -= 0.25;
00135 }
00136
00137
00138 QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF()
00139 << mapToScene(0, 0)
00140 << mapToScene(-30, -50)
00141 << mapToScene(30, -50));
00142 foreach (QGraphicsItem *item, dangerMice) {
00143 if (item == this)
00144 continue;
00145
00146 QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0));
00147 qreal angleToMouse = ::acos(lineToMouse.dx() / lineToMouse.length());
00148 if (lineToMouse.dy() < 0)
00149 angleToMouse = TwoPi - angleToMouse;
00150 angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2);
00151
00152 if (angleToMouse >= 0 && angleToMouse < Pi / 2) {
00153
00154 angle += 0.5;
00155 } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) {
00156
00157 angle -= 0.5;
00158 }
00159 }
00160
00161
00162 if (dangerMice.size() > 1 && (qrand() % 10) == 0) {
00163 if (qrand() % 1)
00164 angle += (qrand() % 100) / 500.0;
00165 else
00166 angle -= (qrand() % 100) / 500.0;
00167 }
00168
00169 speed += (-50 + qrand() % 100) / 100.0;
00170
00171 qreal dx = ::sin(angle) * 10;
00172 mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5;
00173
00174 rotate(dx);
00175 setPos(mapToParent(0, -(3 + sin(speed) * 3)));
00176 }