mouse.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the example classes of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://trolltech.com/products/qt/licenses/licensing/opensource/
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
00017 ** or contact the sales department at sales@trolltech.com.
00018 **
00019 ** In addition, as a special exception, Trolltech gives you certain
00020 ** additional rights. These rights are described in the Trolltech GPL
00021 ** Exception version 1.0, which can be found at
00022 ** http://www.trolltech.com/products/qt/gplexception/ and in the file
00023 ** GPL_EXCEPTION.txt in this package.
00024 **
00025 ** In addition, as a special exception, Trolltech, as the sole copyright
00026 ** holder for Qt Designer, grants users of the Qt/Eclipse Integration
00027 ** plug-in the right for the Qt/Eclipse Integration to link to
00028 ** functionality provided by Qt Designer and its related libraries.
00029 **
00030 ** Trolltech reserves all rights not expressly granted herein.
00031 **
00032 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00033 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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     // Body
00084     painter->setBrush(color);
00085     painter->drawEllipse(-10, -20, 20, 40);
00086 
00087     // Eyes
00088     painter->setBrush(Qt::white);
00089     painter->drawEllipse(-10, -17, 8, 8);
00090     painter->drawEllipse(2, -17, 8, 8);
00091 
00092     // Nose
00093     painter->setBrush(Qt::black);
00094     painter->drawEllipse(QRectF(-2, -22, 4, 4));
00095 
00096     // Pupils
00097     painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4));
00098     painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4));
00099 
00100     // Ears
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     // Tail
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     // Don't move too far away
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             // Rotate left
00126             angle += (angle < -Pi / 2) ? 0.25 : -0.25;
00127         } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) {
00128             // Rotate right
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     // Try not to crash with any other mice
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             // Rotate right
00154             angle += 0.5;
00155         } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) {
00156             // Rotate left
00157             angle -= 0.5;
00158         }
00159     }
00160 
00161     // Add some random movement
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 }


csm
Author(s): Andrea Censi
autogenerated on Fri May 17 2019 02:28:33