# gcompris - guessnumber # # Copyright (C) 2005, 2008 Bruno Coudoin / Clement Coudoin # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # import gobject import goocanvas import gcompris import gcompris.utils import gcompris.skin import gcompris.admin import gcompris.bonus import gtk import gtk.gdk import random import pango from gcompris import gcompris_gettext as _ class Gcompris_guessnumber: """Tux hide a number, you must guess it""" def __init__(self, gcomprisBoard): self.gcomprisBoard = gcomprisBoard self.gcomprisBoard.disable_im_context = True # A text canvas item use to indicate it's over or lower self.indicator = None # The text entry for the number self.entry = None # The min and max value that must be found self.min = -1 self.max = -1 # These are used to let us restart only after the bonus is displayed. # When the bonus is displayed, it call us first with pause(1) and then with pause(0) self.board_paused = 0 self.gamewon = 0 self.stopped = True # Manage the helico move self.move_stepnum = 0 self.x = self.y = self.x_old = self.y_old = -1 self.moving = False self.action_start = 0 self.anim = None self.velocity = [] self.sw = self.sh = 1 self.move_tick = 30 self.num_moveticks = 20 self.rotation = 0 self.movestep_timer = 0 self.orig_x = 0 self.orig_y = gcompris.BOARD_HEIGHT/2 self.target_x = 640 self.target_y = self.orig_y self.helico_width = -1 self.helico_height = -1 def start(self): self.gcomprisBoard.level=1 self.gcomprisBoard.maxlevel=4 self.gcomprisBoard.sublevel=1 self.gcomprisBoard.number_of_sublevel=1 gcompris.bar_set(gcompris.BAR_LEVEL) gcompris.bar_set_level(self.gcomprisBoard) gcompris.bar_location(gcompris.BOARD_WIDTH - 160, -1, 0.7) gcompris.set_background(self.gcomprisBoard.canvas.get_root_item(), "guessnumber/cave.png") self.stopped = False self.display_game() def end(self): self.stopped = True # Remove the root item removes all the others inside it self.cleanup_game() def ok(self): pass def repeat(self): print("Gcompris_guessnumber repeat.") def key_press(self, keyval, commit_str, preedit_str): # Return True if you did process a key # Return False if you did not processed a key # (gtk need to send it to next widget) return False def pause(self, pause): self.board_paused = pause # Hack for widget that can't be covered by bonus and/or help if pause: self.entry.props.visibility = goocanvas.ITEM_INVISIBLE else: self.entry.props.visibility = goocanvas.ITEM_VISIBLE # When the bonus is displayed, it call us first with pause(1) and then with pause(0) # the game is won if(pause == 0 and self.gamewon): self.increment_level() self.gamewon = 0 self.cleanup_game() self.display_game() return def set_level(self, level): self.gcomprisBoard.level=level; self.gcomprisBoard.sublevel=1; # Set the level in the control bar gcompris.bar_set_level(self.gcomprisBoard); self.cleanup_game() self.display_game() # # End of Initialisation # --------------------- # # Code that increments the sublevel and level # And bail out if no more levels are available # return 1 if continue, 0 if bail out def increment_level(self): self.gcomprisBoard.sublevel += 1 if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel): # Try the next level self.gcomprisBoard.sublevel=1 self.gcomprisBoard.level += 1 gcompris.bar_set_level(self.gcomprisBoard) if(self.gcomprisBoard.level > self.gcomprisBoard.maxlevel): # the current board is finished : stay on the last level self.gcomprisBoard.level = self.gcomprisBoard.maxlevel return 1 # Display the board game def cleanup_game(self): self.gamewon = False if self.movestep_timer != 0: gtk.timeout_remove(self.movestep_timer) self.movestep_timer = 0 # Remove the root item removes all the others inside it self.rootitem.remove() # Display the board game def display_game(self): # Create our rootitem. We put each canvas item in it so at the end we # only have to kill it. The canvas deletes all the items it contains automaticaly. self.rootitem = goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item()) self.min = 1 self.max = 10 if(self.gcomprisBoard.level == 2): self.max = 100 elif(self.gcomprisBoard.level == 3): self.max = 500 elif(self.gcomprisBoard.level == 4): self.max = 1000 # Select the number to find self.solution = random.randint(self.min, self.max) text = _("Guess a number between %d and %d") %(self.min, self.max) goocanvas.Text( parent = self.rootitem, x=10.0, y=30.0, font=gcompris.skin.get_font("gcompris/subtitle"), text=(text), fill_color_rgba=0x1514c4ffL, ) self.indicator =goocanvas.Text( parent = self.rootitem, x=400.0, y=70.0, width = 700, font=gcompris.skin.get_font("gcompris/subtitle"), text=(""), fill_color_rgba=0xff0006ffL, anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER, ) text_item = self.entry_text() # # Display the helico # pixmap = gcompris.utils.load_pixmap("guessnumber/tuxhelico.png") self.helico_width = pixmap.get_width() self.helico_height = pixmap.get_height() self.orig_x = self.x_old = self.x = 20 self.y_old = self.y = self.orig_y self.anim = goocanvas.Image( parent = self.rootitem, pixbuf = pixmap, x = self.x, y = self.y, ) # The OK Button item = goocanvas.Svg(parent = self.rootitem, svg_handle = gcompris.skin.svg_get(), svg_id = "#OK" ) item.translate(item.get_bounds().x1 * -1 + gcompris.BOARD_WIDTH - (item.get_bounds().x2 - item.get_bounds().x1) - 30, item.get_bounds().y1 * -1 + 65) item.connect("button_press_event", self.ok_event, text_item) gcompris.utils.item_focus_init(item, None) def entry_text(self): self.entry = gtk.Entry() self.entry.modify_font(pango.FontDescription("sans bold 24")) text_color = gtk.gdk.color_parse("blue") text_color_selected = gtk.gdk.color_parse("green") self.entry.modify_text(gtk.STATE_NORMAL, text_color) self.entry.modify_text(gtk.STATE_SELECTED, text_color_selected) self.entry.set_max_length(4) self.entry.connect("activate", self.enter_callback) self.entry.connect("changed", self.enter_char_callback) self.entry.props.visibility = goocanvas.ITEM_VISIBLE self.widget = goocanvas.Widget( parent = self.rootitem, widget=self.entry, x=730, y=30, width=100, height=46, anchor=gtk.ANCHOR_CENTER, ) self.widget.raise_(None) #self.widget.grab_focus() self.entry.grab_focus() return self.entry def enter_char_callback(self, widget): text = widget.get_text() widget.set_text(text.decode('utf8').upper().encode('utf8')) def enter_callback(self, widget): text = widget.get_text() # Find a number game if str(self.solution) == text: self.indicator.props.text = "" self.gamewon = True gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.TUX) else: try: number = int(text) except: self.indicator.props.text = _("Please enter a number between %d and %d") %(self.min, self.max) widget.set_text('') return if number > self.max or number <= 0: self.indicator.props.text = _("Out of range") else: max_distance = max(self.max - self.solution, self.solution) distance_x = self.target_x - abs(self.solution - number) * float(self.target_x - self.orig_x) / max_distance distance_y = self.orig_y + float(((self.solution - number) * 170) / max_distance) if(number > self.solution): self.indicator.props.text=_("Too high") else: self.indicator.props.text = _("Too low") self.move(self.x_old, self.y_old, distance_x, distance_y) widget.set_text('') def move_step(self): if self.stopped: return if self.move_stepnum < self.num_moveticks-1: self.move_stepnum += 1 x = self.anim.get_property("x") + self.velocity[0]/self.num_moveticks y = self.anim.get_property("y") + self.velocity[1]/self.num_moveticks self.anim.props.x = x self.anim.props.y = y return True else: self.move_stepnum = 0 self.moving = False self.movestep_timer = 0 (self.x_old, self.y_old) = self.gcomprisBoard.canvas.\ convert_from_item_space(self.anim, self.x_old, self.y_old) self.anim.props.transform = None self.anim.props.x = self.x_old self.anim.props.y = self.y_old self.entry.set_editable(True) return False def move(self, x_old, y_old, x, y): if x == x_old and y == y_old: return self.entry.set_editable(False) if(x > x_old): self.rotation = 5 elif (x