1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
include Math
require 'Qt4'
class CannonField < Qt::Widget
signals 'angleChanged(int)', 'forceChanged(int)'
slots 'setAngle(int)', 'setForce(int)', 'shoot()', 'moveShot()'
def initialize(parent = nil)
super
@currentAngle = 45
@currentForce = 0
@timerCount = 0
@autoShootTimer = Qt::Timer.new( self )
connect( @autoShootTimer, SIGNAL('timeout()'),
self, SLOT('moveShot()') )
@shootAngle = 0
@shootForce = 0
setPalette( Qt::Palette.new( Qt::Color.new( 250, 250, 200) ) )
setAutoFillBackground(true)
@barrelRect = Qt::Rect.new(33, -4, 15, 8)
end
def setAngle( degrees )
if degrees < 5
degrees = 5
elsif degrees > 70
degrees = 70
end
if @currentAngle == degrees
return
end
@currentAngle = degrees
update( cannonRect() )
emit angleChanged( @currentAngle )
end
def setForce( newton )
if newton < 0
newton = 0
end
if @currentForce == newton
return
end
@currentForce = newton
emit forceChanged( @currentForce )
end
def shoot()
if @autoShootTimer.isActive()
return
end;
@timerCount = 0
@shootAngle = @currentAngle
@shootForce = @currentForce
@autoShootTimer.start( 5 )
end
def moveShot()
r = Qt::Region.new( shotRect() )
@timerCount += 1
shotR = shotRect()
if shotR.x() > width() || shotR.y() > height()
@autoShootTimer.stop()
else
r = r.unite( Qt::Region.new( shotR ) )
end
update( r )
end
def paintEvent( e )
p = Qt::Painter.new( self )
paintCannon( p )
if @autoShootTimer.isActive()
paintShot( p )
end
p.end()
end
def paintShot( p )
p.setPen( Qt::NoPen )
p.setBrush( Qt::Brush.new(Qt::black) )
p.drawRect( shotRect() )
end
def paintCannon(painter)
painter.setPen(Qt::NoPen)
painter.setBrush(Qt::Brush.new(Qt::blue))
painter.save()
painter.translate(0, height())
painter.drawPie( Qt::Rect.new(-35, -35, 70, 70), 0, 90*16 )
painter.rotate( - @currentAngle )
painter.drawRect( @barrelRect )
painter.restore()
end
def cannonRect()
r = Qt::Rect.new( 0, 0, 50, 50)
r.moveBottomLeft( rect().bottomLeft() )
return r
end
def shotRect()
gravity = 4.0
time = @timerCount / 40.0
velocity = @shootForce
radians = @shootAngle*3.14159265/180.0
velx = velocity*cos( radians )
vely = velocity*sin( radians )
x0 = ( @barrelRect.right() + 5.0 )*cos(radians)
y0 = ( @barrelRect.right() + 5.0 )*sin(radians)
x = x0 + velx*time
y = y0 + vely*time - 0.5*gravity*time*time
r = Qt::Rect.new( 0, 0, 6, 6 );
r.moveCenter( Qt::Point.new( x.round, height() - 1 - y.round ) )
return r
end
end
|