Merge branch 'master' of git://labs.trolltech.com/qtscriptgenerator
[qtscriptgenerator/amarok.git] / examples / CollidingMice.qs
bloba4d85cfa96b6d43d2013b6debf59e1ce7bb38161
1 /****************************************************************************
2 **
3 ** Copyright (C) 2008 Trolltech ASA. All rights reserved.
4 **
5 ** This file is part of the Qt Script Generator project on Trolltech Labs.
6 **
7 ** This file may be used under the terms of the GNU General Public
8 ** License version 2.0 as published by the Free Software Foundation
9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 ** this file.  Please review the following information to ensure GNU
11 ** General Public Licensing requirements will be met:
12 ** http://www.trolltech.com/products/qt/opensource.html
14 ** If you are unsure which license is appropriate for your use, please
15 ** review the following information:
16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 ** sales department at sales@trolltech.com.
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 ****************************************************************************/
24 function Mouse(parent) {
25     QGraphicsItem.call(this, parent);
26     this.angle = 0;
27     this.speed = 0;
28     this.mouseEyeDirection = 0;
30     var adjust = 0.5;
31     this._boundingRect = new QRectF(-20 - adjust, -22 - adjust,
32                                     40 + adjust, 83 + adjust);
33     this.boundingRect = function() { return this._boundingRect; };
35     this._shape = new QPainterPath();
36     this._shape.addRect(-10, -20, 20, 40);
37     this.shape = function() { return this._shape; }
39     this._brush = new QBrush(Qt.SolidPattern);
40     this._tail = new QPainterPath(new QPointF(0, 20));
41     this._tail.cubicTo(-5, 22, -5, 22, 0, 25);
42     this._tail.cubicTo(5, 27, 5, 32, 0, 30);
43     this._tail.cubicTo(-5, 32, -5, 42, 0, 35);
45     this._pupilRect1 = new QRectF(-8 + this.mouseEyeDirection, -17, 4, 4);
46     this._pupilRect2 = new QRectF(4 + this.mouseEyeDirection, -17, 4, 4);
48     this.color = new QColor(Math.random()*256, Math.random()*256,
49                             Math.random()*256);
50     this.rotate(Math.random()*360);
52     var timer = new QTimer(this);
53     timer.singleShot = false;
54     timer.timeout.connect(this, function() { this.move(); });
55     timer.start(1000 / 33);
58 Mouse.prototype = new QGraphicsItem();
60 Mouse.prototype.paint = function(painter, styleOptionGraphicsItem, widget) {
61     // Body
62     painter.setBrush(new QBrush(this.color));
63     painter.drawEllipse(-10, -20, 20, 40);
65     // Eyes
66     this._brush.setColor(Qt.white);
67     painter.setBrush(this._brush);
68     painter.drawEllipse(-10, -17, 8, 8);
69     painter.drawEllipse(2, -17, 8, 8);
71     // Nose
72     this._brush.setColor(Qt.black);
73     painter.setBrush(this._brush);
74     painter.drawEllipse(-2, -22, 4, 4);
76     // Pupils
77     painter.drawEllipse(this._pupilRect1);
78     painter.drawEllipse(this._pupilRect2);
80     // Ears
81     //    if (this.scene().collidingItems(this).length == 0) FIXME: const QGraphicsItem*
82     if (this.scene().items(this.pos()).length == 1)
83         this._brush.setColor(Qt.darkYellow);
84     else
85         this._brush.setColor(Qt.red);
86     painter.setBrush(this._brush);
88     painter.drawEllipse(-17, -12, 16, 16);
89     painter.drawEllipse(1, -12, 16, 16);
91     // Tail
92     painter.setBrush(Qt.NoBrush);
93     painter.drawPath(this._tail);
96 Mouse.prototype.move = function() {
97     // Don't move too far away
98     var lineToCenter = new QLineF(Mouse.origo, this.mapFromScene(0, 0));
99     if (lineToCenter.length() > 150) {
100         var angleToCenter = Math.acos(lineToCenter.dx()
101                                       / lineToCenter.length());
102         if (lineToCenter.dy() < 0)
103             angleToCenter = Mouse.TWO_PI - angleToCenter;
104         angleToCenter = Mouse.normalizeAngle((Math.PI - angleToCenter)
105                                               + Math.PI / 2);
107         if (angleToCenter < Math.PI && angleToCenter > Math.PI / 4) {
108             // Rotate left
109             this.angle += (this.angle < -Math.PI / 2) ? 0.25 : -0.25;
110         } else if (angleToCenter >= Math.PI
111                    && angleToCenter < (Math.PI + Math.PI / 2
112                                        + Math.PI / 4)) {
113             // Rotate right
114             this.angle += (this.angle < Math.PI / 2) ? 0.25 : -0.25;
115         }
116     } else if (Math.sin(this.angle) < 0) {
117         this.angle += 0.25;
118     } else if (Math.sin(this.angle) > 0) {
119         this.angle -= 0.25;
120     }
122     // Try not to crash with any other mice
124     var polygon = new QPolygonF(
125         [ this.mapToScene(0, 0),
126           this.mapToScene(-30, -50),
127           this.mapToScene(30, -50) ] );
129     var dangerMice = this.scene().items(polygon);
130     for (var i = 0; i < dangerMice.length; ++i) {
131         var item = dangerMice[i];
132         if (item == this)
133             continue;
135         var lineToMouse = new QLineF(Mouse.origo,
136                                      this.mapFromItem(item, 0, 0));
137         var angleToMouse = Math.acos(lineToMouse.dx()
138                                      / lineToMouse.length());
139         if (lineToMouse.dy() < 0)
140             angleToMouse = Mouse.TWO_PI - angleToMouse;
141         angleToMouse = Mouse.normalizeAngle((Math.PI - angleToMouse)
142                                       + Math.PI / 2);
144         if (angleToMouse >= 0 && angleToMouse < (Math.PI / 2)) {
145             // Rotate right
146             this.angle += 0.5;
147         } else if (angleToMouse <= Mouse.TWO_PI
148                    && angleToMouse > (Mouse.TWO_PI - Math.PI / 2)) {
149             // Rotate left
150             this.angle -= 0.5;
151         }
152     }
154     // Add some random movement
155     if (dangerMice.length < 1 && Math.random() < 0.1) {
156         if (Math.random() > 0.5)
157             this.angle += Math.random() / 5;
158         else
159             this.angle -= Math.random() / 5;
160     }
162     this.speed += (-50 + Math.random() * 100) / 100.0;
164     var dx = Math.sin(this.angle) * 10;
165     this.mouseEyeDirection = (Math.abs(dx / 5) < 1) ? 0 : dx / 5;
167     this.rotate(dx);
168     this.setPos(this.mapToParent(0, -(3 + Math.sin(this.speed) * 3)));
171 Mouse.normalizeAngle = function(angle) {
172     while (angle < 0)
173         angle += Mouse.TWO_PI;
174     while (angle > Mouse.TWO_PI)
175         angle -= Mouse.TWO_PI;
176     return angle;
179 Mouse.TWO_PI = Math.PI * 2;
180 Mouse.origo = new QPointF(0, 0);
184 function CollidingMice(parent) {
185     QWidget.call(this, parent);
186     var scene = new QGraphicsScene(this);
187     scene.setSceneRect(-300, -300, 600, 600);
188     scene.itemIndexMethod = QGraphicsScene.NoIndex;
190     for (var i = 0; i < CollidingMice.MOUSE_COUNT; ++i) {
191         var mouse = new Mouse(this);
192         mouse.setPos(Math.sin((i * 6.28) / CollidingMice.MOUSE_COUNT) * 200,
193                      Math.cos((i * 6.28) / CollidingMice.MOUSE_COUNT) * 200);
194         scene.addItem(mouse);
195     }
197     var view = new QGraphicsView(scene, this);
198     view.setRenderHint(QPainter.Antialiasing);
199     view.backgroundBrush = new QBrush(new QPixmap("images/cheese.png"));
200     view.cacheMode = new QGraphicsView.CacheMode(QGraphicsView.CacheBackground);
201     view.dragMode = QGraphicsView.ScrollHandDrag;
202     view.viewportUpdateMode = QGraphicsView.FullViewportUpdate;
204     var layout = new QGridLayout();
205     layout.addWidget(view, 0, 0);
206     this.setLayout(layout);
208     this.setWindowTitle("Colliding Mice");
209     this.resize(400, 300);
212 CollidingMice.prototype = new QWidget();
214 CollidingMice.MOUSE_COUNT = 7;
218 var collidingMice = new CollidingMice(null);
219 collidingMice.show();
220 QCoreApplication.exec();