Back to index

gcompris  8.2.2
ballcatch.py
Go to the documentation of this file.
00001 # Ballcatch Board module
00002 import gobject
00003 import gnomecanvas
00004 import gcompris
00005 import gcompris.utils
00006 import gcompris.skin
00007 import gcompris.bonus
00008 import gtk
00009 import gtk.gdk
00010 from gettext import gettext as _
00011 
00012 # ----------------------------------------
00013 # Hit left shift and right shift together to send the ball straight
00014 
00015 class Gcompris_ballcatch:
00016   """catch the ball"""
00017 
00018 
00019   def __init__(self, gcomprisBoard):
00020     self.gcomprisBoard = gcomprisBoard
00021 
00022     self.gcomprisBoard.disable_im_context = True
00023 
00024     # These are used to let us restart only after the bonus is displayed.
00025     # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
00026     self.board_paused  = 0;
00027     self.gamewon       = 0;
00028 
00029     print("Gcompris_ballcatch __init__.")
00030 
00031 
00032   def start(self):
00033     self.gcomprisBoard.level=1
00034     self.gcomprisBoard.maxlevel=9
00035     self.gcomprisBoard.sublevel=1
00036     self.gcomprisBoard.number_of_sublevel=1
00037     gcompris.bar_set(gcompris.BAR_LEVEL)
00038     gcompris.set_background(self.gcomprisBoard.canvas.root(),
00039                             "images/beach.png")
00040     gcompris.bar_set_level(self.gcomprisBoard)
00041 
00042 
00043     self.ballinc    = 20        # Event loop timer for the ball move
00044     self.timer_diff = 0         # Store the time diff between left and right key
00045 
00046     # Create our rootitem. We put each canvas item in it so at the end we
00047     # only have to kill it. The canvas deletes all the items it contains automaticaly.
00048     self.rootitem = self.gcomprisBoard.canvas.root().add(
00049       gnomecanvas.CanvasGroup,
00050       x=0.0,
00051       y=0.0
00052       )
00053 
00054     # Tux
00055     self.lefthand = self.rootitem.add(
00056       gnomecanvas.CanvasPixbuf,
00057       pixbuf = gcompris.utils.load_pixmap("gcompris/misc/tux.png"),
00058       x=gcompris.BOARD_WIDTH/2 - 60,
00059       y=135.0
00060       )
00061 
00062     # Balloon
00063     self.balloon_item = self.rootitem.add(
00064       gnomecanvas.CanvasEllipse,
00065       x1=0.0,
00066       y1=0.0,
00067       x2=0.0,
00068       y2=0.0
00069       )
00070     self.init_balloon()
00071 
00072     # The Left Hand
00073     self.lefthand = self.rootitem.add(
00074       gnomecanvas.CanvasPixbuf,
00075       pixbuf = gcompris.utils.load_pixmap("gcompris/misc/hand.png"),
00076       x=gcompris.BOARD_WIDTH/2-150.0,
00077       y=gcompris.BOARD_HEIGHT - 150
00078       )
00079 
00080     # The Right Hand
00081     item = self.lefthand = self.rootitem.add(
00082       gnomecanvas.CanvasPixbuf,
00083       pixbuf = gcompris.utils.load_pixmap("gcompris/misc/hand.png"),
00084       x=gcompris.BOARD_WIDTH/2+100.0,
00085       y=gcompris.BOARD_HEIGHT - 150.0
00086       )
00087     bounds = self.get_bounds(item)
00088     (cx, cy) = ( (bounds[2]+bounds[0])/2 , (bounds[3]+bounds[1])/2)
00089     mat = ( -1, 0, 0, 1, 2*cx, 0)
00090     item.affine_relative(mat)
00091 
00092     # The Left Shift KEY
00093     self.leftkey = self.rootitem.add(
00094       gnomecanvas.CanvasPixbuf,
00095       pixbuf = gcompris.utils.load_pixmap("images/shift_key.png"),
00096       x=gcompris.BOARD_WIDTH/2-240.0,
00097       y=gcompris.BOARD_HEIGHT - 80
00098       )
00099 
00100     # The Right Shift KEY
00101     self.rightkey = self.rootitem.add(
00102       gnomecanvas.CanvasPixbuf,
00103       pixbuf = gcompris.utils.load_pixmap("images/shift_key.png"),
00104       x=gcompris.BOARD_WIDTH/2+100.0,
00105       y=gcompris.BOARD_HEIGHT - 80
00106       )
00107 
00108     # The basic tick for object moves
00109     self.timerinc = 1000
00110 
00111     self.left_continue  = True
00112     self.right_continue = True
00113 
00114     self.counter_left  = 0
00115     self.counter_right = 0
00116 
00117     self.timer_inc  = gtk.timeout_add(self.timerinc, self.timer_inc_display)
00118 
00119     print("Gcompris_ballcatch start.")
00120 
00121 
00122   def end(self):
00123 
00124     # Remove the root item removes all the others inside it
00125     self.rootitem.destroy()
00126 
00127     if self.timer_inc :
00128       gtk.timeout_remove(self.timer_inc)
00129 
00130 
00131   def ok(self):
00132     print("Gcompris_ballcatch ok.")
00133 
00134 
00135   def repeat(self):
00136     print("Gcompris_ballcatch repeat.")
00137 
00138 
00139   def config(self):
00140     print("Gcompris_ballcatch config.")
00141 
00142 
00143   def key_press(self, keyval, commit_str, preedit_str):
00144     print("Gcompris_ballcatch key press. %i" % keyval)
00145 
00146     if (keyval == gtk.keysyms.Shift_L):
00147       self.left_continue  = False
00148 
00149     if (keyval == gtk.keysyms.Shift_R):
00150       self.right_continue = False
00151 
00152     return False
00153 
00154   # Called by gcompris core
00155   def pause(self, pause):
00156 
00157     self.board_paused = pause
00158 
00159     # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
00160     # the game is won
00161     if(pause == 0):
00162       self.next_level()
00163       self.gamewon = 0
00164 
00165     return
00166 
00167 
00168   # Called by gcompris when the user click on the level icon
00169   def set_level(self, level):
00170     self.gcomprisBoard.level=level
00171     self.gcomprisBoard.sublevel=1
00172     self.next_level()
00173 
00174   # End of Initialisation
00175   # ---------------------
00176 
00177   def next_level(self):
00178 
00179     # Set the level in the control bar
00180     gcompris.bar_set_level(self.gcomprisBoard);
00181 
00182     self.init_balloon()
00183     self.left_continue  = True
00184     self.right_continue = True
00185     self.counter_left  = 0
00186     self.counter_right = 0
00187 
00188     if(self.gcomprisBoard.level == 1):
00189       self.timerinc = 900
00190     elif(self.gcomprisBoard.level == 2):
00191       self.timerinc = 350
00192     elif(self.gcomprisBoard.level == 3):
00193       self.timerinc = 300
00194     elif(self.gcomprisBoard.level == 4):
00195       self.timerinc = 200
00196     elif(self.gcomprisBoard.level == 5):
00197       self.timerinc = 150
00198     elif(self.gcomprisBoard.level == 6):
00199       self.timerinc = 100
00200     elif(self.gcomprisBoard.level == 7):
00201       self.timerinc = 60
00202     elif(self.gcomprisBoard.level == 8):
00203       self.timerinc = 30
00204     elif(self.gcomprisBoard.level == 9):
00205       self.timerinc = 15
00206 
00207     if(self.timerinc<1):
00208       self.timerinc = 1
00209 
00210     # Restart the timer
00211     self.timer_inc  = gtk.timeout_add(self.timerinc, self.timer_inc_display)
00212 
00213 
00214   def timer_inc_display(self):
00215 
00216     if(self.left_continue):
00217       self.counter_left += self.timer_inc
00218 
00219     if(self.right_continue):
00220       self.counter_right += self.timer_inc
00221 
00222     if(self.left_continue or self.right_continue):
00223       self.timer_inc  = gtk.timeout_add(self.timerinc, self.timer_inc_display)
00224     else:
00225       # Send the ball now
00226       self.timer_diff = self.counter_right/1000 - self.counter_left/1000
00227       # Make some adjustment so that it cannot be too or too far close from the target
00228       # In between, the calculated value stay proportional to the error.
00229       print self.timer_diff
00230       if(self.timer_diff < -6):
00231         self.timer_diff = -6
00232       elif(self.timer_diff > 6):
00233         self.timer_diff = 6
00234       elif(self.timer_diff > -1.5 and self.timer_diff < 0 ):
00235         self.timer_diff = -1.5
00236       elif(self.timer_diff < 1.5 and self.timer_diff > 0 ):
00237         self.timer_diff = 1.5
00238 
00239       self.timer_inc  = gtk.timeout_add(self.ballinc, self.ball_move)
00240 
00241   def ball_move(self):
00242 
00243     # The move simulation
00244     self.balloon_size -= 3
00245     self.balloon_x    += self.timer_diff
00246     self.balloon_y    -= 5
00247 
00248     if(self.balloon_width_units>1.0):
00249       self.balloon_width_units -= 0.5
00250 
00251     self.balloon_item.set(
00252       x1=self.balloon_x - self.balloon_size/2,
00253       y1=self.balloon_y - self.balloon_size/2,
00254       x2=self.balloon_x + self.balloon_size/2,
00255       y2=self.balloon_y + self.balloon_size/2,
00256       width_units=self.balloon_width_units
00257       )
00258 
00259     if(self.balloon_size>48):
00260       self.timer_inc  = gtk.timeout_add(self.ballinc, self.ball_move)
00261     else:
00262       # We are done with the ballon move
00263       if(self.counter_left == self.counter_right):
00264         # This is a win
00265         if (self.increment_level() == 1):
00266           self.gamewon = 1
00267           gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.TUX)
00268       else:
00269         # This is a loose
00270         self.gamewon = 0
00271         gcompris.bonus.display(gcompris.bonus.LOOSE, gcompris.bonus.TUX)
00272 
00273   def get_bounds(self, item):
00274     if gobject.type_name(item)=="GnomeCanvasPixbuf":
00275       x1=item.get_property("x")
00276       y1=item.get_property("y")
00277       x2=item.get_property("x")+item.get_property("width")
00278       y2=item.get_property("y")+item.get_property("height")
00279     return (min(x1,x2),min(y1,y2),max(x1,x2),max(y1,y2))
00280 
00281   def init_balloon(self):
00282     self.balloon_size = 160
00283     self.balloon_width_units = 5.0
00284     self.balloon_x    = gcompris.BOARD_WIDTH/2-20
00285     self.balloon_y    = gcompris.BOARD_HEIGHT - 130
00286 
00287     self.balloon_item.set(
00288       x1=self.balloon_x - self.balloon_size/2,
00289       y1=self.balloon_y - self.balloon_size/2,
00290       x2=self.balloon_x + self.balloon_size/2,
00291       y2=self.balloon_y + self.balloon_size/2,
00292       fill_color_rgba=0xFF1212FFL,
00293       outline_color_rgba=0x000000FFL,
00294       width_units=self.balloon_width_units
00295       )
00296 
00297   # Code that increments the sublevel and level
00298   # And bail out if no more levels are available
00299   # return 1 if continue, 0 if bail out
00300   def increment_level(self):
00301     self.gcomprisBoard.sublevel += 1
00302 
00303     if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
00304       # Try the next level
00305       self.gcomprisBoard.sublevel=1
00306       self.gcomprisBoard.level += 1
00307       if(self.gcomprisBoard.level>self.gcomprisBoard.maxlevel):
00308         # the current board is finished : bail out
00309         gcompris.bonus.board_finished(gcompris.bonus.FINISHED_RANDOM)
00310         return 0
00311 
00312     return 1
00313