Back to index

gcompris  8.2.2
followline.py
Go to the documentation of this file.
00001 # Follow Line Board module
00002 import gobject
00003 import gnomecanvas
00004 import gcompris
00005 import gcompris.skin
00006 import gcompris.bonus
00007 import gcompris.utils
00008 import gtk
00009 import gtk.gdk
00010 import random
00011 import math
00012 from gettext import gettext as _
00013 
00014 # ----------------------------------------
00015 #
00016 
00017 class Gcompris_followline:
00018   """follow the line"""
00019 
00020 
00021   def __init__(self, gcomprisBoard):
00022     self.gcomprisBoard = gcomprisBoard
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     self.loosing_count = 0
00030 
00031     self.color_empty   = 0xcee871FFL
00032     self.color_full    = 0x1a24cbffL
00033     self.color_target  = 0xFF0000FFL
00034     self.color_border  = 0x101010FFL
00035 
00036     print("Gcompris_followline __init__.")
00037 
00038 
00039   def start(self):
00040     self.gcomprisBoard.level=1
00041     self.gcomprisBoard.maxlevel=9
00042     self.gcomprisBoard.sublevel=1
00043     self.gcomprisBoard.number_of_sublevel=1
00044     gcompris.bar_set(gcompris.BAR_LEVEL)
00045     self.background_item = gcompris.set_background(self.gcomprisBoard.canvas.root(),
00046                                                    "images/followline.png")
00047     self.background_item_connect_id = self.background_item.connect("event", self.loosing_item_event)
00048 
00049     gcompris.bar_set_level(self.gcomprisBoard)
00050 
00051     self.init_board()
00052 
00053     print("Gcompris_followline start.")
00054 
00055 
00056   def end(self):
00057 
00058     # Remove the root item removes all the others inside it
00059     self.cleanup()
00060 
00061     # Disconnect from the background item
00062     self.background_item.disconnect(self.background_item_connect_id)
00063 
00064   def ok(self):
00065     print("Gcompris_followline ok.")
00066 
00067 
00068   def repeat(self):
00069     print("Gcompris_followline repeat.")
00070 
00071 
00072   def config(self):
00073     print("Gcompris_followline config.")
00074 
00075 
00076   def key_press(self, keyval, commit_str, preedit_str):
00077     return False
00078 
00079 
00080   # Called by gcompris core
00081   def pause(self, pause):
00082 
00083     self.board_paused = pause
00084 
00085     # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
00086     # the game is won
00087     if(pause == 0):
00088       self.next_level()
00089       self.gamewon = 0
00090 
00091     return
00092 
00093 
00094   # Called by gcompris when the user click on the level icon
00095   def set_level(self, level):
00096     self.gcomprisBoard.level=level
00097     self.gcomprisBoard.sublevel=1
00098     self.next_level()
00099 
00100   # End of Initialisation
00101   # ---------------------
00102 
00103   def cleanup(self):
00104     # Remove the root item removes all the others inside it
00105     self.state = "Done"
00106 
00107     self.rootitem.destroy()
00108     self.lines_group.destroy()
00109     self.water_spot_group.destroy()
00110 
00111   def next_level(self):
00112 
00113     self.cleanup()
00114 
00115     # Set the level in the control bar
00116     gcompris.bar_set_level(self.gcomprisBoard);
00117 
00118     self.init_board()
00119 
00120 
00121 
00122   def init_board(self):
00123 
00124     self.state = "Ready"
00125 
00126     # Create our rootitem. We put each canvas item in it so at the end we
00127     # only have to kill it. The canvas deletes all the items it contains automaticaly.
00128     self.rootitem = self.gcomprisBoard.canvas.root().add(
00129       gnomecanvas.CanvasGroup,
00130       x=0.0,
00131       y=0.0
00132       )
00133 
00134     # Another group where we put each canvas line item in it
00135     self.lines_group = self.gcomprisBoard.canvas.root().add(
00136       gnomecanvas.CanvasGroup,
00137       x=0.0,
00138       y=0.0
00139       )
00140 
00141     start_x         = 40
00142     start_y         = gcompris.BOARD_HEIGHT/2
00143     stop_x          = gcompris.BOARD_WIDTH - 100
00144 
00145     # Line path (create several little line)
00146     min_boundary = 40
00147     y            = start_y
00148     line_width   = 45 - self.gcomprisBoard.level*2
00149     step         = (stop_x-start_x)/(30)
00150 
00151     frequency = 1 + int(self.gcomprisBoard.level/4)
00152 
00153     xpi = math.pi/2*frequency
00154     y   = start_y + math.cos(xpi)*(self.gcomprisBoard.level*10)
00155     for x in range(start_x, stop_x, step):
00156 
00157       xpi += (math.pi/2*frequency)/step
00158       y2 = start_y + math.cos(xpi)*(self.gcomprisBoard.level*10)
00159 
00160       # Check we stay within boundaries
00161       if(y2>=gcompris.BOARD_HEIGHT-min_boundary):
00162         y2=gcompris.BOARD_HEIGHT-min_boundary
00163       elif(y2<=min_boundary):
00164         y2=min_boundary
00165 
00166       item = self.lines_group.add(
00167         gnomecanvas.CanvasLine,
00168         points          =( x,
00169                            y,
00170                            x + step,
00171                            y2),
00172         fill_color_rgba = self.color_empty,
00173         width_units     = line_width,
00174         cap_style       = gtk.gdk.CAP_ROUND
00175         )
00176       item.connect("event", self.line_item_event)
00177 
00178       if x > start_x and x < stop_x-step:
00179         self.rootitem.add(
00180           gnomecanvas.CanvasLine,
00181           points          =( x,
00182                              y,
00183                              x + step,
00184                              y2),
00185           fill_color_rgba = self.color_border,
00186           width_units     = line_width + 20,
00187           cap_style       = gtk.gdk.CAP_ROUND
00188           )
00189 
00190       y = y2
00191 
00192     self.highlight_next_line()
00193 
00194     # Another group where we put each canvas line item in it
00195     self.water_spot_group = self.gcomprisBoard.canvas.root().add(
00196       gnomecanvas.CanvasGroup,
00197       x=0.0,
00198       y=0.0
00199       )
00200     # A water spot will be displayed when the user win
00201     self.water_spot = self.water_spot_group.add (
00202       gnomecanvas.CanvasPixbuf,
00203       pixbuf = gcompris.utils.load_pixmap("images/water_spot.png"),
00204       x=580,
00205       y=260,
00206       )
00207     self.water_spot.hide()
00208 
00209 
00210   # Code that increments the sublevel and level
00211   # And bail out if no more levels are available
00212   # return 1 if continue, 0 if bail out
00213   def increment_level(self):
00214     self.gcomprisBoard.sublevel += 1
00215 
00216     if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
00217       # Try the next level
00218       self.gcomprisBoard.sublevel=1
00219       self.gcomprisBoard.level += 1
00220       if(self.gcomprisBoard.level>self.gcomprisBoard.maxlevel):
00221         # the current board is finished : bail out
00222         gcompris.bonus.board_finished(gcompris.bonus.FINISHED_RANDOM)
00223         return 0
00224 
00225     return 1
00226 
00227   #
00228   # Highlight the next spot on the line
00229   #
00230   def highlight_next_line(self):
00231     for item in self.lines_group.item_list:
00232       if(item.get_data("gotit") != True):
00233         item.set(
00234           fill_color_rgba = self.color_target,
00235           )
00236         item.set_data("iamnext", True);
00237         return
00238 
00239   #
00240   # Highlight the previous spot on the line
00241   # Called on loose situation
00242   #
00243   def highlight_previous_line(self):
00244     previous_item = []
00245 
00246     for item in self.lines_group.item_list:
00247 
00248       if(item.get_data("iamnext") == True):
00249 
00250         if(previous_item):
00251           # Remove the target info for this item
00252           item.set_data("iamnext", False)
00253           item.set(
00254             fill_color_rgba = self.color_empty,
00255             )
00256 
00257           # Set the target info on the previous item
00258           previous_item.set(
00259             fill_color_rgba = self.color_target,
00260             )
00261           item.set_data("gotit", False)
00262           previous_item.set_data("iamnext", True);
00263 
00264         return
00265 
00266       previous_item = item
00267 
00268 
00269   def is_done(self):
00270     done = True
00271     for item in self.lines_group.item_list:
00272       if(item.get_data("gotit") != True):
00273         done = False
00274 
00275     if(done):
00276       # This is a win
00277       if (self.increment_level() == 1):
00278         self.state = "Done"
00279         self.gamewon = 1
00280         self.water_spot.raise_to_top()
00281         self.water_spot.show()
00282         gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.FLOWER)
00283 
00284     return done
00285 
00286   def loosing_item_event(self, widget, event=None):
00287     if(self.state == "Started"):
00288       self.loosing_count += 1
00289       if(self.loosing_count % 10):
00290         self.highlight_previous_line()
00291     return False
00292 
00293 
00294   def line_item_event(self, widget, event=None):
00295     if not self.board_paused and widget.get_data("iamnext") == True:
00296       # The first line touch means the game is started
00297       self.state = "Started"
00298       widget.set(
00299         fill_color_rgba = self.color_full,
00300         )
00301       widget.set_data("gotit", True);
00302       widget.set_data("iamnext", False);
00303       self.highlight_next_line()
00304       self.is_done()
00305 
00306     return False
00307