#!/usr/bin/env python
# TQt tutorial 13.
import sys
import math
import random
from python_tqt . qt import *
class LCDRange ( TQWidget ) :
def __init__ ( self , s = None , parent = None , name = None ) :
TQWidget . __init__ ( self , parent , name )
lcd = TQLCDNumber ( 2 , self , ' lcd ' )
self . slider = TQSlider ( TQt . Horizontal , self , ' slider ' )
self . slider . setRange ( 0 , 99 )
self . slider . setValue ( 0 )
self . label = TQLabel ( ' ' , self , ' label ' )
self . label . setAlignment ( TQt . AlignCenter )
self . connect ( self . slider , SIGNAL ( ' valueChanged(int) ' ) , lcd , SLOT ( ' display(int) ' ) )
self . connect ( self . slider , SIGNAL ( ' valueChanged(int) ' ) , self , PYSIGNAL ( ' valueChanged(int) ' ) )
self . setFocusProxy ( self . slider )
l = TQVBoxLayout ( self )
l . addWidget ( lcd , 1 )
l . addWidget ( self . slider )
l . addWidget ( self . label )
if s is not None :
self . setText ( s )
def value ( self ) :
return self . slider . value ( )
def setValue ( self , value ) :
self . slider . setValue ( value )
def setRange ( self , minVal , maxVal ) :
if minVal < 0 or maxVal > 99 or minVal > maxVal :
raise ValueError , ' LCDRange.setRange(): invalid range '
self . slider . setRange ( minVal , maxVal )
def text ( self ) :
return self . label . text ( )
def setText ( self , s ) :
self . label . setText ( s )
class CannonField ( TQWidget ) :
def __init__ ( self , parent = None , name = None ) :
TQWidget . __init__ ( self , parent , name )
self . ang = 45
self . f = 0
self . timerCount = 0
self . autoShootTimer = TQTimer ( self , ' movement handler ' )
self . connect ( self . autoShootTimer , SIGNAL ( ' timeout() ' ) , self . moveShot )
self . shoot_ang = 0
self . shoot_f = 0
self . target = TQPoint ( 0 , 0 )
self . gameEnded = 0
self . setPalette ( TQPalette ( TQColor ( 250 , 250 , 200 ) ) )
self . barrelRect = TQRect ( 33 , - 4 , 15 , 8 )
self . newTarget ( )
def angle ( self ) :
return self . ang
def setAngle ( self , degrees ) :
if degrees < 5 :
degrees = 5
if degrees > 70 :
degrees = 70
if self . ang == degrees :
return
self . ang = degrees
self . repaint ( self . cannonRect ( ) , 0 )
self . emit ( PYSIGNAL ( ' angleChanged(int) ' ) , ( self . ang , ) )
def force ( self ) :
return self . f
def setForce ( self , newton ) :
if newton < 0 :
newton = 0
if self . f == newton :
return
self . f = newton
self . emit ( PYSIGNAL ( ' forceChanged(int) ' ) , ( self . f , ) )
def shoot ( self ) :
if self . isShooting ( ) :
return
self . timerCount = 0
self . shoot_ang = self . ang
self . shoot_f = self . f
self . autoShootTimer . start ( 50 )
self . emit ( PYSIGNAL ( ' canShoot(bool) ' ) , ( 0 , ) )
def newTarget ( self ) :
r = TQRegion ( self . targetRect ( ) )
self . target = TQPoint ( random . randint ( 200 , 390 ) , random . randint ( 10 , 265 ) )
self . repaint ( r . unite ( TQRegion ( self . targetRect ( ) ) ) )
def gameOver ( self ) :
return self . gameEnded
def setGameOver ( self ) :
if self . gameEnded :
return
if self . isShooting ( ) :
self . autoShootTime . stop ( )
self . gameEnded = 1
self . repaint ( )
def restartGame ( self ) :
if self . isShooting ( ) :
self . autoShootTime . stop ( )
self . gameEnded = 0
self . repaint ( )
self . emit ( PYSIGNAL ( ' canShoot(bool) ' ) , ( 1 , ) )
def moveShot ( self ) :
r = TQRegion ( self . shotRect ( ) )
self . timerCount = self . timerCount + 1
shotR = self . shotRect ( )
if shotR . intersects ( self . targetRect ( ) ) :
self . autoShootTimer . stop ( )
self . emit ( PYSIGNAL ( ' hit() ' ) , ( ) )
self . emit ( PYSIGNAL ( ' canShoot(bool) ' ) , ( 1 , ) )
elif shotR . x ( ) > self . width ( ) or shotR . y ( ) > self . height ( ) :
self . autoShootTimer . stop ( )
self . emit ( PYSIGNAL ( ' missed() ' ) , ( ) )
self . emit ( PYSIGNAL ( ' canShoot(bool) ' ) , ( 1 , ) )
else :
r = r . unite ( TQRegion ( shotR ) )
self . repaint ( r )
def paintEvent ( self , ev ) :
updateR = ev . rect ( )
p = TQPainter ( self )
if self . gameEnded :
p . setPen ( TQt . black )
p . setFont ( TQFont ( ' Courier ' , 48 , TQFont . Bold ) )
p . drawText ( self . rect ( ) , TQt . AlignCenter , ' Game Over ' )
if updateR . intersects ( self . cannonRect ( ) ) :
self . paintCannon ( p )
if self . isShooting ( ) and updateR . intersects ( self . shotRect ( ) ) :
self . paintShot ( p )
if not self . gameEnded and updateR . intersects ( self . targetRect ( ) ) :
self . paintTarget ( p )
def paintShot ( self , p ) :
p . setBrush ( TQt . black )
p . setPen ( TQt . NoPen )
p . drawRect ( self . shotRect ( ) )
def paintTarget ( self , p ) :
p . setBrush ( TQt . red )
p . setPen ( TQt . black )
p . drawRect ( self . targetRect ( ) )
def paintCannon ( self , p ) :
cr = self . cannonRect ( )
pix = TQPixmap ( cr . size ( ) )
pix . fill ( self , cr . topLeft ( ) )
tmp = TQPainter ( pix )
tmp . setBrush ( TQt . blue )
tmp . setPen ( TQt . NoPen )
tmp . translate ( 0 , pix . height ( ) - 1 )
tmp . drawPie ( TQRect ( - 35 , - 35 , 70 , 70 ) , 0 , 90 * 16 )
tmp . rotate ( - self . ang )
tmp . drawRect ( self . barrelRect )
tmp . end ( )
p . drawPixmap ( cr . topLeft ( ) , pix )
def cannonRect ( self ) :
r = TQRect ( 0 , 0 , 50 , 50 )
r . moveBottomLeft ( self . rect ( ) . bottomLeft ( ) )
return r
def shotRect ( self ) :
gravity = 4.0
time = self . timerCount / 4.0
velocity = self . shoot_f
radians = self . shoot_ang * 3.14159265 / 180
velx = velocity * math . cos ( radians )
vely = velocity * math . sin ( radians )
x0 = ( self . barrelRect . right ( ) + 5 ) * math . cos ( radians )
y0 = ( self . barrelRect . right ( ) + 5 ) * math . sin ( radians )
x = x0 + velx * time
y = y0 + vely * time - 0.5 * gravity * time * time
r = TQRect ( 0 , 0 , 6 , 6 )
r . moveCenter ( TQPoint ( x , self . height ( ) - 1 - y ) )
return r
def targetRect ( self ) :
r = TQRect ( 0 , 0 , 20 , 10 )
r . moveCenter ( TQPoint ( self . target . x ( ) , self . height ( ) - 1 - self . target . y ( ) ) )
return r
def isShooting ( self ) :
return self . autoShootTimer . isActive ( )
def sizePolicy ( self ) :
return TQSizePolicy ( TQSizePolicy . Expanding , TQSizePolicy . Expanding )
class GameBoard ( TQWidget ) :
def __init__ ( self , parent = None , name = None ) :
TQWidget . __init__ ( self , parent , name )
quit = TQPushButton ( ' &Quit ' , self , ' quit ' )
quit . setFont ( TQFont ( ' Times ' , 18 , TQFont . Bold ) )
self . connect ( quit , SIGNAL ( ' clicked() ' ) , tqApp , SLOT ( ' quit() ' ) )
self . angle = LCDRange ( ' ANGLE ' , self , ' angle ' )
self . angle . setRange ( 5 , 70 )
self . force = LCDRange ( ' FORCE ' , self , ' force ' )
self . force . setRange ( 10 , 50 )
self . cannonField = CannonField ( self , ' cannonField ' )
self . connect ( self . angle , PYSIGNAL ( ' valueChanged(int) ' ) , self . cannonField . setAngle )
self . connect ( self . cannonField , PYSIGNAL ( ' angleChanged(int) ' ) , self . angle . setValue )
self . connect ( self . force , PYSIGNAL ( ' valueChanged(int) ' ) , self . cannonField . setForce )
self . connect ( self . cannonField , PYSIGNAL ( ' forceChanged(int) ' ) , self . force . setValue )
self . connect ( self . cannonField , PYSIGNAL ( ' hit() ' ) , self . hit )
self . connect ( self . cannonField , PYSIGNAL ( ' missed() ' ) , self . missed )
self . shoot = TQPushButton ( ' &Shoot ' , self , ' shoot ' )
self . shoot . setFont ( TQFont ( ' Times ' , 18 , TQFont . Bold ) )
self . connect ( self . shoot , SIGNAL ( ' clicked() ' ) , self . fire )
self . connect ( self . cannonField , PYSIGNAL ( ' canShoot(bool) ' ) , self . shoot , SLOT ( ' setEnabled(bool) ' ) )
restart = TQPushButton ( ' &New Game ' , self , ' newgame ' )
restart . setFont ( TQFont ( ' Times ' , 18 , TQFont . Bold ) )
self . connect ( restart , SIGNAL ( ' clicked() ' ) , self . newGame )
self . hits = TQLCDNumber ( 2 , self , ' hits ' )
self . shotsLeft = TQLCDNumber ( 2 , self , ' shotsleft ' )
hitsL = TQLabel ( ' HITS ' , self , ' hitsLabel ' )
shotsLeftL = TQLabel ( ' SHOTS LEFT ' , self , ' shotsleftLabel ' )
grid = TQGridLayout ( self , 2 , 2 , 10 )
grid . addWidget ( quit , 0 , 0 )
grid . addWidget ( self . cannonField , 1 , 1 )
grid . setColStretch ( 1 , 10 )
leftBox = TQVBoxLayout ( )
grid . addLayout ( leftBox , 1 , 0 )
leftBox . addWidget ( self . angle )
leftBox . addWidget ( self . force )
topBox = TQHBoxLayout ( )
grid . addLayout ( topBox , 0 , 1 )
topBox . addWidget ( self . shoot )
topBox . addWidget ( self . hits )
topBox . addWidget ( hitsL )
topBox . addWidget ( self . shotsLeft )
topBox . addWidget ( shotsLeftL )
topBox . addStretch ( 1 )
topBox . addWidget ( restart )
self . angle . setValue ( 60 )
self . force . setValue ( 25 )
self . angle . setFocus ( )
self . newGame ( )
def fire ( self ) :
if self . cannonField . gameOver ( ) or self . cannonField . isShooting ( ) :
return
self . shotsLeft . display ( self . shotsLeft . intValue ( ) - 1 )
self . cannonField . shoot ( )
def hit ( self ) :
self . hits . display ( self . hits . intValue ( ) + 1 )
if self . shotsLeft . intValue ( ) == 0 :
self . cannonField . setGameOver ( )
else :
self . cannonField . newTarget ( )
def missed ( self ) :
if self . shotsLeft . intValue ( ) == 0 :
self . cannonField . setGameOver ( )
def newGame ( self ) :
self . shotsLeft . display ( 15 )
self . hits . display ( 0 )
self . cannonField . restartGame ( )
self . cannonField . newTarget ( )
TQApplication . setColorSpec ( TQApplication . CustomColor )
a = TQApplication ( sys . argv )
gb = GameBoard ( )
gb . setGeometry ( 100 , 100 , 500 , 355 )
a . setMainWidget ( gb )
gb . show ( )
a . exec_loop ( )