source: trunk/tutorial/t11/cannon.cpp@ 81

Last change on this file since 81 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 3.3 KB
Line 
1/****************************************************************
2**
3** Implementation CannonField class, Qt tutorial 11
4**
5****************************************************************/
6
7#include "cannon.h"
8#include <qtimer.h>
9#include <qpainter.h>
10#include <qpixmap.h>
11
12#include <math.h>
13
14
15CannonField::CannonField( QWidget *parent, const char *name )
16 : QWidget( parent, name )
17{
18 ang = 45;
19 f = 0;
20 timerCount = 0;
21 autoShootTimer = new QTimer( this, "movement handler" );
22 connect( autoShootTimer, SIGNAL(timeout()),
23 this, SLOT(moveShot()) );
24 shoot_ang = 0;
25 shoot_f = 0;
26 setPalette( QPalette( QColor( 250, 250, 200) ) );
27}
28
29
30void CannonField::setAngle( int degrees )
31{
32 if ( degrees < 5 )
33 degrees = 5;
34 if ( degrees > 70 )
35 degrees = 70;
36 if ( ang == degrees )
37 return;
38 ang = degrees;
39 repaint( cannonRect(), FALSE );
40 emit angleChanged( ang );
41}
42
43
44void CannonField::setForce( int newton )
45{
46 if ( newton < 0 )
47 newton = 0;
48 if ( f == newton )
49 return;
50 f = newton;
51 emit forceChanged( f );
52}
53
54
55void CannonField::shoot()
56{
57 if ( autoShootTimer->isActive() )
58 return;
59 timerCount = 0;
60 shoot_ang = ang;
61 shoot_f = f;
62 autoShootTimer->start( 50 );
63}
64
65
66void CannonField::moveShot()
67{
68 QRegion r( shotRect() );
69 timerCount++;
70
71 QRect shotR = shotRect();
72
73 if ( shotR.x() > width() || shotR.y() > height() )
74 autoShootTimer->stop();
75 else
76 r = r.unite( QRegion( shotR ) );
77 repaint( r );
78}
79
80
81void CannonField::paintEvent( QPaintEvent *e )
82{
83 QRect updateR = e->rect();
84 QPainter p( this );
85
86 if ( updateR.intersects( cannonRect() ) )
87 paintCannon( &p );
88 if ( autoShootTimer->isActive() &&
89 updateR.intersects( shotRect() ) )
90 paintShot( &p );
91}
92
93
94void CannonField::paintShot( QPainter *p )
95{
96 p->setBrush( black );
97 p->setPen( NoPen );
98 p->drawRect( shotRect() );
99}
100
101
102const QRect barrelRect(33, -4, 15, 8);
103
104void CannonField::paintCannon( QPainter *p )
105{
106 QRect cr = cannonRect();
107 QPixmap pix( cr.size() );
108 pix.fill( this, cr.topLeft() );
109
110 QPainter tmp( &pix );
111 tmp.setBrush( blue );
112 tmp.setPen( NoPen );
113
114 tmp.translate( 0, pix.height() - 1 );
115 tmp.drawPie( QRect( -35,-35, 70, 70 ), 0, 90*16 );
116 tmp.rotate( -ang );
117 tmp.drawRect( barrelRect );
118 tmp.end();
119
120 p->drawPixmap( cr.topLeft(), pix );
121}
122
123
124QRect CannonField::cannonRect() const
125{
126 QRect r( 0, 0, 50, 50 );
127 r.moveBottomLeft( rect().bottomLeft() );
128 return r;
129}
130
131
132QRect CannonField::shotRect() const
133{
134 const double gravity = 4;
135
136 double time = timerCount / 4.0;
137 double velocity = shoot_f;
138 double radians = shoot_ang*3.14159265/180;
139
140 double velx = velocity*cos( radians );
141 double vely = velocity*sin( radians );
142 double x0 = ( barrelRect.right() + 5 )*cos(radians);
143 double y0 = ( barrelRect.right() + 5 )*sin(radians);
144 double x = x0 + velx*time;
145 double y = y0 + vely*time - 0.5*gravity*time*time;
146
147 QRect r = QRect( 0, 0, 6, 6 );
148 r.moveCenter( QPoint( qRound(x), height() - 1 - qRound(y) ) );
149 return r;
150}
151
152
153QSizePolicy CannonField::sizePolicy() const
154{
155 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
156}
Note: See TracBrowser for help on using the repository browser.