def _setup_workspace(self): ''' Add the bones. ''' self._width = Gdk.Screen.width() self._height = int(Gdk.Screen.height() - (GRID_CELL_SIZE * 2)) self._scale = self._height * 1.0 / BONE_HEIGHT self._bone_width = int(BONE_WIDTH * self._scale) self._bone_height = int(BONE_HEIGHT * self._scale) # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) self._bone_index = Sprite( self._sprites, 0, 0, _load_svg_from_file( os.path.join(self._bone_path, 'bones-index.svg'), self._bone_width, self._bone_height)) self._max_bones = int(self._width / self._bone_width) - 1 self._blank_image = _load_svg_from_file( os.path.join(self._bone_path, 'blank-bone.svg'), self._bone_width, self._bone_height) for bones in range(self._max_bones): self._bones.append( Sprite(self._sprites, bones * self._bone_width, 0, self._blank_image)) circle_image = _load_svg_from_file( os.path.join(self._bone_path, 'circle.svg'), int(self._scale * 45), int(self._scale * 45)) self._circles[0] = Sprite(self._sprites, 0, -100, circle_image) self._circles[1] = Sprite(self._sprites, 0, -100, circle_image) oval_image = _load_svg_from_file( os.path.join(self._bone_path, 'oval.svg'), int(self._scale * 129), int(self._scale * 92)) for bones in range(self._max_bones - 1): self._ovals.append(Sprite(self._sprites, 0, -100, oval_image))
def __init__(self, game): Sprite.__init__(self, game) self.images_left = [ PhotoImage(file="images/figure-L1.gif"), PhotoImage(file="images/figure-L2.gif"), PhotoImage(file="images/figure-L3.gif") ] self.images_right = [ PhotoImage(file="images/figure-R1.gif"), PhotoImage(file="images/figure-R2.gif"), PhotoImage(file="images/figure-R3.gif") ] self.image = game.canvas.create_image(self.INITIAL_STICKMAN_X, self.INITIAL_STICKMAN_Y, image=self.images_left[0], anchor='nw') self.x = -0.5 self.y = 0 self.current_image = 0 self.current_image_add = 1 self.jump_count = 0 self.last_time = time.time() self.coordinates = stickmanutils.Coords() game.canvas.bind_all('<KeyPress-Left>', self.turn_left) game.canvas.bind_all('<KeyPress-Right>', self.turn_right) game.canvas.bind_all('<space>', self.jump)
def create_toolbar_background(sprite_list, width): # Create the toolbar background for the selectors spr = Sprite(sprite_list, 0, 0, svg_str_to_pixbuf(SVG().toolbar(2 * width, ICON_SIZE))) spr.type = 'toolbar' spr.set_layer(CATEGORY_LAYER) return spr
def configure_cb(self, event): self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - GRID_CELL_SIZE self._scale = Gdk.Screen.height() / 900.0 # We need to resize the backgrounds width, height = self._calc_background_size() for bg in list(self._backgrounds.keys()): if bg == 'custom': path = self._custom_dsobject.file_path pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( path, width, height) else: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( os.path.join(self._path, 'images', bg), width, height) if Gdk.Screen.height() > Gdk.Screen.width(): pixbuf = self._crop_to_portrait(pixbuf) self._backgrounds[bg] = pixbuf self._background = Sprite(self._sprites, 0, 0, self._backgrounds[self._current_bg]) self._background.set_layer(-100) self._background.type = 'background' # and resize and reposition the bars self.bar.resize_all() self.bar.show_bar(2) self._current_bar = self.bar.get_bar(2) # Calculate a new accerlation based on screen height. self._ddy = (6.67 * self._height) / (STEPS * STEPS) self._guess_orientation()
def __init__(self, game): self.grid = [0, 1, 2, 3, 4, 5, 6, 7, 8] self.card_table = [] self.mask_table = [] # Stuff to keep around for the graphics self.w = int(game.width) self.h = int(game.height) self.d = int(game.card_dim * game.scale) self.s = game.scale # Initialize the cards i = 0 # i is used as a label on the sprite for c in CARD_DEFS: x, y = self.i_to_xy(i) self.card_table.append(Card(game, c, i, x, y)) i += 1 # Initialize the masks (We need up to 6 of each one.) for i in range(4): bitmap = load_image(os.path.join(game.path, 'mask%dh.svg' % (i)), 120 * game.scale, 48 * game.scale) for j in range(6): x, y = self.mh_to_xy(j) self.mask_table.append(Sprite(game.sprites, x, y, bitmap)) bitmap = load_image(os.path.join(game.path, 'mask%dv.svg' % (i)), 48 * game.scale, 120 * game.scale) for j in range(6): x, y = self.mv_to_xy(j) self.mask_table.append(Sprite(game.sprites, x, y, bitmap)) self.hide_masks()
def __init__(self, sprites, path, name, x, y, w, h, svg_engine=None, function=None): if svg_engine is None: self.spr = Sprite(sprites, x, y, file_to_pixbuf(path, name, w, h)) else: self.spr = Sprite(sprites, x, y, svg_str_to_pixbuf(svg_engine().svg)) self.tab_dx = [0, SWIDTH - TABWIDTH] self.tab_dy = [2 * SHEIGHT, 2 * SHEIGHT] self.tabs = [] self.tabs.append( Tab(sprites, path, 'tab', x + self.tab_dx[0], y + self.tab_dy[0], TABWIDTH, SHEIGHT)) self.tabs.append( Tab(sprites, path, 'tab', x + self.tab_dx[1], y + self.tab_dy[1], TABWIDTH, SHEIGHT)) self.calculate = function self.name = name
def __init__(self, parent): super().__init__(parent) # Location music pygame.mixer_music.load("assets/audio/chooseYourSeeds.mp3") pygame.mixer_music.play(loops=-1) self.bg = Sprite( 0, 0, image=pygame.image.load("assets/misc/bg.png").convert()) # At the begging camera moves to the right side of background self.move_times = (self.bg.image.get_width() - c.sizes["win"][0]) / 5 # Card choices self.plant_choice_widget = PlantChoiceMenu( # Contains all working plants [ PotatoMine, Sunflower, SnowPea, CherryBomb, Chomper, Repeater, WallNut, PeaShooter ]) # Menu which usually displays suns and chosen cards # New cards added here self.top_menu = TopMenu(pos=0) # Sounds and images for pre-game state self.ready_set_plant = pygame.mixer.Sound( "assets/audio/readysetplant.wav") self.ready_set_plant_images = [ pygame.image.load("assets/misc/StartReady.png").convert_alpha(), pygame.image.load("assets/misc/StartSet.png").convert_alpha(), pygame.image.load("assets/misc/StartPlant.png").convert_alpha(), ] self.counter = 0
def __init__(self, cards): self.frame = Sprite( 0, c.sizes["topmenu"][1], image=pygame.image.load( "assets/misc/chooseYourPlants.png").convert_alpha(), size=c.sizes["choose"]) self.button_images = list( map(lambda i: pygame.transform.smoothscale(i, c.sizes["letsRock"]), [ pygame.image.load( "assets/misc/letsRock.png").convert_alpha(), pygame.image.load( "assets/misc/letsRockHighlight.png").convert_alpha() ])) self.button = Sprite(158, 568, image=self.button_images[0]) self.cards = pygame.sprite.Group() self.x = c.pads["choose"][0] self.starting_x = self.x y = c.pads["choose"][1] _c = 0 for card in cards: _c += 1 image = pygame.image.load( f"assets/cards/card{card.__name__}.png").convert() s = Card(self.x, card, image=image, size=c.sizes["card"], y=y) self.cards.add(s) self.x += c.sizes["card"][0] + 2 if _c % 7 == 0: self.x = self.starting_x y += c.sizes["card"][1] + 5
def create(self, string, attributes=None, sprites=None, file_path=None): if attributes is None: if self.spr is None: self.spr = Sprite(sprites, 0, 0, svg_str_to_pixbuf(string)) else: self.spr.set_image(svg_str_to_pixbuf(string)) self.index = None else: self.shape = attributes[0] self.color = attributes[1] self.num = attributes[2] self.fill = attributes[3] self.index = self.shape * COLORS * NUMBER * FILLS + \ self.color * NUMBER * FILLS + \ self.num * FILLS + \ self.fill if self.spr is None: self.spr = Sprite(sprites, 0, 0, svg_str_to_pixbuf(string)) else: self.spr.set_image(svg_str_to_pixbuf(string)) if file_path is not None: self.spr.set_image(load_image(file_path, self._scale), i=1, dx=int(self._scale * CARD_WIDTH * .125), dy=int(self._scale * CARD_HEIGHT * .125)) self.spr.set_label_attributes(self._scale * 24) self.spr.set_label('')
def __init__(self, cards: list = None, pos: int = 100): if cards is None: cards = [] # TODO добавить остальные цифры # Digits for sun display self.digits = { str(n): pygame.image.load(f"assets/misc/{n}.png").convert_alpha() for n in range(10) } # Main frame self.frame = Sprite( pos, 0, image=pygame.image.load("assets/misc/topmenu.png").convert_alpha(), size=c.sizes["topmenu"]) # Positions cards self.cards = pygame.sprite.Group() self.x = c.pads["sun"][0] + (c.pads["menubar"][0] if self.get_preparing() else 0) self.starting_x = self.x for card in cards: image = pygame.image.load( f"assets/cards/card{card.__name__}.png").convert() s = Card(self.x, card, image=image, size=c.sizes["card"]) self.cards.add(s) self.x += c.sizes["card"][0] + c.pads["cards"] self.shovel = Shovel(c.sizes["topmenu"][0] + c.pads["menubar"][0], 0)
def word_card_append(self, card_list, pixbuf, i=-1): if i == -1: card_list.append(Sprite(self._sprites, 10, 10, pixbuf)) else: card_list[i] = Sprite(self._sprites, 10, 10, pixbuf) card_list[i].set_label_attributes(36) card_list[i].set_margins(10, 0, 10, 0) card_list[i].hide()
def __init__(self, turtle_window, n): '''This class handles the display of palette selectors (Only relevant to GNOME version and very old versions of Sugar). ''' self.shapes = [] self.spr = None self._turtle_window = turtle_window self._index = n if not n < len(palette_names): # Shouldn't happen, but hey... debug_output('palette index %d is out of range' % n, self._turtle_window.running_sugar) self._name = 'extras' else: self._name = palette_names[n] icon_pathname = None for path in self._turtle_window.icon_paths: if os.path.exists(os.path.join(path, '%soff.svg' % (self._name))): icon_pathname = os.path.join(path, '%soff.svg' % (self._name)) break if icon_pathname is not None: off_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname)) else: off_shape = svg_str_to_pixbuf( svg_from_file( os.path.join(self._turtle_window.icon_paths[0], 'extrasoff.svg'))) error_output('Unable to open %soff.svg' % (self._name), self._turtle_window.running_sugar) icon_pathname = None for path in self._turtle_window.icon_paths: if os.path.exists(os.path.join(path, '%son.svg' % (self._name))): icon_pathname = os.path.join(path, '%son.svg' % (self._name)) break if icon_pathname is not None: on_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname)) else: on_shape = svg_str_to_pixbuf( svg_from_file( os.path.join(self._turtle_window.icon_paths[0], 'extrason.svg'))) error_output('Unable to open %son.svg' % (self._name), self._turtle_window.running_sugar) self.shapes.append(off_shape) self.shapes.append(on_shape) x = int(ICON_SIZE * self._index) self.spr = Sprite(self._turtle_window.sprite_list, x, 0, off_shape) self.spr.type = 'selector' self.spr.name = self._name self.set_layer()
def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']): self._activity = parent self._colors = colors self._canvas = canvas parent.show_all() self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) self._canvas.connect("draw", self.__draw_cb) self._canvas.connect("button-press-event", self._button_press_cb) self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - (GRID_CELL_SIZE * 1.5) self._scale = self._height / (14.0 * DOT_SIZE * 1.2) self._dot_size = int(DOT_SIZE * self._scale) self._turtle_offset = 0 self._space = int(self._dot_size / 5.) self._orientation = 0 self.level = 0 self.custom_strategy = None self.strategies = [ BEGINNER_STRATEGY, INTERMEDIATE_STRATEGY, EXPERT_STRATEGY, self.custom_strategy ] self.strategy = self.strategies[self.level] self._timeout_id = None # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) self._dots = [] for y in range(THIRTEEN): for x in range(THIRTEEN): xoffset = int((self._width - THIRTEEN * (self._dot_size + \ self._space) - self._space) / 2.) if y % 2 == 1: xoffset += int((self._dot_size + self._space) / 2.) if x == 0 or y == 0 or x == THIRTEEN - 1 or y == THIRTEEN - 1: self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), y * (self._dot_size + self._space), self._new_dot('#B0B0B0'))) else: self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), y * (self._dot_size + self._space), self._new_dot(self._colors[FILL]))) self._dots[-1].type = False # not set # Put a turtle at the center of the screen... self._turtle_images = [] self._rotate_turtle(self._new_turtle()) self._turtle = Sprite(self._sprites, 0, 0, self._turtle_images[0]) self._move_turtle(self._dots[int(THIRTEEN * THIRTEEN / 2)].get_xy()) # ...and initialize. self._all_clear()
def draw_rods_and_beads(self, x, y): """ Draw the rods and beads """ _white = _svg_header(BWIDTH, BHEIGHT, self.abacus.scale) +\ _svg_bead("#ffffff", "#000000") +\ _svg_footer() _yellow1 = _svg_header(BWIDTH, BHEIGHT, self.abacus.scale) +\ _svg_bead("#ffffcc", "#000000") +\ _svg_footer() _yellow2 = _svg_header(BWIDTH, BHEIGHT, self.abacus.scale) +\ _svg_bead("#ffff88", "#000000") +\ _svg_footer() _yellow3 = _svg_header(BWIDTH, BHEIGHT, self.abacus.scale) +\ _svg_bead("#ffff00", "#000000") +\ _svg_footer() self.colors = [_svg_str_to_pixbuf(_white), _svg_str_to_pixbuf(_yellow1), _svg_str_to_pixbuf(_yellow2), _svg_str_to_pixbuf(_yellow3)] dx = (BWIDTH+BOFFSET)*self.abacus.scale bo = (BWIDTH-BOFFSET)*self.abacus.scale/4 ro = (BWIDTH+5)*self.abacus.scale/2 for i in range(self.num_rods): _rod = _svg_header(10, self.frame_height-(FSTROKE*2), self.abacus.scale) +\ _svg_rect(10, self.frame_height-(FSTROKE*2), 0, 0, 0, 0, ROD_COLORS[i%len(ROD_COLORS)], "#404040") +\ _svg_footer() self.rods.append(Sprite(self.abacus.sprites, x+i*dx+ro, y, _svg_str_to_pixbuf(_rod))) for b in range(self.top_beads): self.beads.append(Bead(Sprite(self.abacus.sprites, x+i*dx+bo, y+b*BHEIGHT*self.abacus.scale, self.colors[0]), 2*BHEIGHT*self.abacus.scale, self.top_factor*(pow(self.base, self.num_rods-i-1)))) for b in range(self.bot_beads): if self.top_beads > 0: self.beads.append(Bead(Sprite(self.abacus.sprites, x+i*dx+bo, y+(self.top_beads+5+b)*\ BHEIGHT*self.abacus.scale, self.colors[0]), 2*BHEIGHT*self.abacus.scale, pow(self.base,self.num_rods-i-1))) else: self.beads.append(Bead(Sprite(self.abacus.sprites, x+i*dx+bo, y+(2+b)*BHEIGHT\ *self.abacus.scale, self.colors[0]), 2*BHEIGHT*self.abacus.scale, pow(self.base,self.num_rods-i-1))) for rod in self.rods: rod.type = "frame"
def _create_results_sprites(self): x = 0 y = self.sy(GY[self.i]) self._success = Sprite(self._sprites, x, y, self._parent.good_job_pixbuf()) self._success.hide() self._failure = Sprite(self._sprites, x, y, self._parent.try_again_pixbuf()) self._failure.hide()
class Slide(Stator): """ Create a sprite for a slide """ def __init__(self, sprites, path, name, x, y, w, h, svg_engine=None, function=None): if svg_engine is None: self.spr = Sprite(sprites, x, y, file_to_pixbuf(path, name, w, h)) else: self.spr = Sprite(sprites, x, y, svg_str_to_pixbuf(svg_engine().svg)) self.tab_dx = [0, SWIDTH - TABWIDTH] self.tab_dy = [2 * SHEIGHT, 2 * SHEIGHT] self.tabs = [] self.tabs.append(Tab(sprites, path, 'tab', x + self.tab_dx[0], y + self.tab_dy[0], TABWIDTH, SHEIGHT)) self.tabs.append(Tab(sprites, path, 'tab', x + self.tab_dx[1], y + self.tab_dy[1], TABWIDTH, SHEIGHT)) self.calculate = function self.name = name def add_textview(self, textview, i=0): self.tabs[i].textview = textview self.tabs[i].textbuffer = textview.get_buffer() def set_fixed(self, fixed): for tab in self.tabs: tab.fixed = fixed def match(self, sprite): if sprite == self.spr or sprite == self.tabs[0].spr or \ sprite == self.tabs[1].spr: return True return False def draw(self, layer=1000): self.spr.set_layer(layer) self.spr.draw() for tab in self.tabs: tab.draw() def move(self, dx, dy): self.spr.move((dx, dy)) for i, tab in enumerate(self.tabs): tab.move(dx + self.tab_dx[i], dy + self.tab_dy[i]) def move_relative(self, dx, dy): self.spr.move_relative((dx, dy)) for i, tab in enumerate(self.tabs): tab.move_relative(dx, dy) def hide(self): self.spr.hide() for tab in self.tabs: tab.hide() def label(self, label, i=0): self.tabs[i].label(label)
def __init__(self, sprites, path, name, x, y, w, h): self.spr = Sprite(sprites, x, y, file_to_pixbuf(path, name, w, h)) self.spr.label = "1.0" self.spr.type = name self.name = name self.width = w self.textview = None self.textbuffer = None self.fixed = None self.textview_y_offset = 0
def __init__(self, sprites, path, card_dim, scale, c, x, y, shape='circle'): """ Load a card from a precomputed SVG. """ self.images = [] self.orientation = 0 if shape == 'triangle': file = "%s/triangle-r0-%d.svg" % (path, c) self.increment = 60 elif shape == 'hexagon': file = "%s/hexagon-r0-%d.svg" % (path, c) self.increment = 120 else: file = "%s/card-%d.svg" % (path, c) self.increment = 90 self.images.append(load_image(file, card_dim * scale, card_dim * scale)) if shape == 'triangle': file = "%s/triangle-r60-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r120-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r180-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r240-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r300-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) elif shape == 'hexagon': file = "%s/hexagon-r120-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) file = "%s/hexagon-r240-%d.svg" % (path, c) self.images.append( load_image(file, card_dim * scale, card_dim * scale)) else: for r in range(3): self.images.append(self.images[r].rotate_simple(90)) # create sprite from svg file self.spr = Sprite(sprites, x, y, self.images[0])
def __init__(self, turtles, turtle_name, turtle_colors=None): ''' The turtle is not a block, just a sprite with an orientation ''' self.spr = None self.label_block = None self._turtles = turtles self._shapes = [] self._custom_shapes = False self._name = turtle_name self._hidden = False self._remote = False self._x = 0.0 self._y = 0.0 self._heading = 0.0 self._half_width = 0 self._half_height = 0 self._drag_radius = None self._pen_shade = 50 self._pen_color = 0 self._pen_gray = 100 if self._turtles.turtle_window.coord_scale == 1: self._pen_size = 5 else: self._pen_size = 1 self._pen_state = True self._pen_fill = False self._poly_points = [] self._prep_shapes(turtle_name, self._turtles, turtle_colors) # Create a sprite for the turtle in interactive mode. if turtles.sprite_list is not None: self.spr = Sprite(self._turtles.sprite_list, 0, 0, self._shapes[0]) self._calculate_sizes() # Choose a random angle from which to attach the turtle # label to be used when sharing. angle = uniform(0, pi * 4 / 3.0) # 240 degrees width = self._shapes[0].get_width() radius = width * 0.67 # Restrict the angle to the sides: 30-150; 210-330 if angle > pi * 2 / 3.0: angle += pi / 2.0 # + 90 self.label_xy = [ int(radius * sin(angle)), int(radius * cos(angle) + width / 2.0) ] else: angle += pi / 6.0 # + 30 self.label_xy = [ int(radius * sin(angle) + width / 2.0), int(radius * cos(angle) + width / 2.0) ] self._turtles.add_to_dict(turtle_name, self)
def highlight_graphic(sprites, scale=1.0): return [ Sprite(sprites, -100, 0, svg_str_to_pixbuf(generate_corners(0, 0.125 * scale))), Sprite(sprites, -100, 0, svg_str_to_pixbuf(generate_corners(1, 0.125 * scale))), Sprite(sprites, -100, 0, svg_str_to_pixbuf(generate_corners(2, 0.125 * scale))), Sprite(sprites, -100, 0, svg_str_to_pixbuf(generate_corners(3, 0.125 * scale))) ]
def __init__(self, sprites, path, name, x, y, w, h, svg_engine=None, calculate=None, result=None): if svg_engine is None: self.spr = Sprite(sprites, x, y, file_to_pixbuf(path, name, w, h)) else: self.spr = Sprite(sprites, x, y, svg_str_to_pixbuf(svg_engine().svg)) self.spr.type = name self.name = name self.calculate = calculate self.result = result
def __init__(self, x, y): Sprite.__init__(self, x, y) if type(self).__name__ == "Platform": self.init_image(fixed_platform) rnd = random.randint(-100, 100) if rnd >= 50: self.spring = Spring( self.x + random.randint(-int(platform_width / 2 - 10), int(platform_width / 2) - 10), self.y - 10) else: self.spring = None
def __init__(self, sprites, svg, svgs, tile_type='tile', number=0): self.spr = Sprite(sprites, 0, 0, svg_str_to_pixbuf(svg)) self.highlight = [self.spr.images[0]] for s in svgs: self.highlight.append(svg_str_to_pixbuf(s)) self.paths = [] # [[N, E, S, W], [N, E, S, W]] self.shape = None self.orientation = 0 self.type = tile_type self.number = number self.value = 1 self.spr.set_label_color('#FF0000')
def _make_mark(self): ''' Make a mark to show the fraction position on the bar. ''' mark = svg_header(self._ball_size / 2., BAR_HEIGHT * self._scale + 4, 1.0) mark += svg_rect(self._ball_size / 2., BAR_HEIGHT * self._scale + 4, 0, 0, 0, 0, '#FF0000', '#FF0000') mark += svg_rect(1, BAR_HEIGHT * self._scale + 4, 0, 0, self._ball_size / 4., 0, '#000000', '#000000') mark += svg_footer() self.mark = Sprite(self._sprites, 0, self._height, # hide off bottom of screen svg_str_to_pixbuf(mark)) self.mark.set_layer(1)
def __init__(self, username, size=(1200,800)): pygame.init() self.size = size self.screen = pygame.display.set_mode(size ) pygame.display.set_caption("GrandTheftSchema2") pygame.mouse.set_visible(1) pygame.key.set_repeat(1, 1) self.renderitems=[] self.renderimages=[] self.renderlock = threading.Semaphore() self.clock = pygame.time.Clock() self.userpos = None self.username = username self.CACHEMODE = False self.font = pygame.font.Font("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12) self.querybg = Sprite('images/querybg.png',(800,200), True) self.forkme = Sprite('images/forkme.png',(298,298), True) self.GTS_OVERVIEW = Sprite('images/GTS_OVERVIEW.png',self.size, False) self._overviewmap = None self._overviewboundslower=None self._overviewboundsupper=None self._overviewsize=None self.lastactivity = time.time() self.kreis = Sprite('images/kreis.png',(20,20), True) self.activelogo = Sprite('images/phant.png',(20,20), True) self.activelogo.xpos=0 #rasterm = rastermap.rastermap() self.rastermap = rastermap.rastermap() self.envpool = [] for x in range(0,multiprocessing.cpu_count()-1): a = environmenter(self.rastermap) self.envpool.append( a ) a.start() self.initBoundingBox() self.objectmanager = objectmanager() self.objectpuller = objectpuller(None,self.objectmanager, username ) self.objectpuller.start() self.rastermap.setZoom(1) self.ticker=ticker() self.ticker.start() self.lastcontrolledobject = None
def _create_number_sprites(self): for i in range(5): self._numbers.append([]) self._glownumbers.append([]) for j in range(5): if self.i == 0: x = self.sx( NX[self.i]) + i * (self.ss(NS[self.i] + NO[self.i])) y = self.sy(NY[self.i]) else: x = self.sx(NX[self.i]) y = self.sy( NY[self.i]) + i * (self.ss(NS[self.i] + NO[self.i])) number = Sprite( self._sprites, x, y, self._parent.number_pixbuf(self.ss(NS[self.i]), j + 1, self._parent.sugarcolors[1])) number.type = 'number' number.name = '%d,%d' % (i, j) self._numbers[i].append(number) number = Sprite( self._sprites, x, y, self._parent.number_pixbuf(self.ss(NS[self.i]), j + 1, '#FFFFFF')) number.type = 'number' number.name = '%d,%d' % (i, j) self._glownumbers[i].append(number)
class Stator(): """ Create a sprite for a stator """ def __init__(self, sprites, path, name, x, y, w, h, svg_engine=None, calculate=None, result=None): if svg_engine is None: self.spr = Sprite(sprites, x, y, file_to_pixbuf(path, name, w, h)) else: self.spr = Sprite(sprites, x, y, svg_str_to_pixbuf(svg_engine().svg)) self.spr.type = name self.name = name self.calculate = calculate self.result = result def draw(self, layer=1000): self.spr.set_layer(layer) def match(self, sprite): if self.spr == sprite: return True return False def move(self, dx, dy): self.spr.move((dx, dy)) def move_relative(self, dx, dy): self.spr.move_relative((dx, dy)) def hide(self): self.spr.hide()
def make_labels(self): ''' Label the bar ''' num = svg_header(BAR_HEIGHT * self.scale, BAR_HEIGHT * self.scale, 1.0) + \ svg_rect(BAR_HEIGHT * self.scale, BAR_HEIGHT * self.scale, 0, 0, 0, 0, 'none', 'none') + \ svg_footer() self.left = Sprite(self.sprites, int(self.ball_size / 4), self.bar_y(), svg_str_to_pixbuf(num)) self.left.set_label(_('0')) self.right = Sprite(self.sprites, self.screen_width - int(self.ball_size / 2), self.bar_y(), svg_str_to_pixbuf(num)) self.right.set_label(_('1'))
def __init__(self, game, c, i, x, y): self.north = c[0] self.east = c[1] self.south = c[2] self.west = c[3] self.orientation = 0 self.images = [] self.images.append( load_image(os.path.join(game.path, 'card%d.svg' % (i)), game.card_dim * game.scale, game.card_dim * game.scale)) for j in range(3): self.images.append(self.images[j].rotate_simple(90)) # create sprite from svg file self.spr = Sprite(game.sprites, x, y, self.images[0]) self.spr.set_label(i)
def __init__(self, sprites, path, name, x, y, w, h, svg_engine=None, function=None): if svg_engine is None: self.spr = Sprite(sprites, x, y, file_to_pixbuf(path, name, w, h)) else: self.spr = Sprite(sprites, x, y, svg_str_to_pixbuf(svg_engine().svg)) self.tab_dx = [0, SWIDTH - TABWIDTH] self.tab_dy = [2 * SHEIGHT, 2 * SHEIGHT] self.tabs = [] self.tabs.append(Tab(sprites, path, 'tab', x + self.tab_dx[0], y + self.tab_dy[0], TABWIDTH, SHEIGHT)) self.tabs.append(Tab(sprites, path, 'tab', x + self.tab_dx[1], y + self.tab_dy[1], TABWIDTH, SHEIGHT)) self.calculate = function self.name = name
def _make_background(self, x, y, w, h, regenerate=False): ''' Make the background sprite for the palette. ''' orientation = self._turtle_window.orientation if regenerate and not self.backgrounds[orientation] is None: self.backgrounds[orientation].hide() self.backgrounds[orientation] = None if self.backgrounds[orientation] is None: svg = SVG() self.backgrounds[orientation] = \ Sprite(self._turtle_window.sprite_list, x, y, svg_str_to_pixbuf(svg.palette(w, h))) self.backgrounds[orientation].save_xy = (x, y) self._float_palette(self.backgrounds[orientation]) if orientation == 0 and w > self._turtle_window.width: self.backgrounds[orientation].type = \ 'category-shift-horizontal' elif orientation == 1 and \ h > self._turtle_window.height - ICON_SIZE: self.backgrounds[orientation].type = \ 'category-shift-vertical' else: self.backgrounds[orientation].type = 'category' '''
def __init__(self, turtles, turtle_name, turtle_colors=None): #print 'class Turtle taturtle.py: def __init__' ''' The turtle is not a block, just a sprite with an orientation ''' self.spr = None self.label_block = None self._turtles = turtles self._shapes = [] self._custom_shapes = False self._name = turtle_name self._hidden = False self._remote = False self._x = 0.0 self._y = 0.0 self._3Dz = 0.0 self._3Dx = 0.0 self._3Dy = 0.0 self._heading = 0.0 self._roll = 0.0 self._pitch = 0.0 self._direction = [0.0, 1.0, 0.0] self._points = [[0., 0., 0.]] self._points_penstate = [1] self._half_width = 0 self._half_height = 0 self._drag_radius = None self._pen_shade = 50 self._pen_color = 0 self._pen_gray = 100 if self._turtles.turtle_window.coord_scale == 1: self._pen_size = 5 else: self._pen_size = 1 self._pen_state = True self._pen_fill = False self._poly_points = [] self._prep_shapes(turtle_name, self._turtles, turtle_colors) # Create a sprite for the turtle in interactive mode. if turtles.sprite_list is not None: self.spr = Sprite(self._turtles.sprite_list, 0, 0, self._shapes[0]) self._calculate_sizes() # Choose a random angle from which to attach the turtle # label to be used when sharing. angle = uniform(0, pi * 4 / 3.0) # 240 degrees width = self._shapes[0].get_width() radius = width * 0.67 # Restrict the angle to the sides: 30-150; 210-330 if angle > pi * 2 / 3.0: angle += pi / 2.0 # + 90 self.label_xy = [int(radius * sin(angle)), int(radius * cos(angle) + width / 2.0)] else: angle += pi / 6.0 # + 30 self.label_xy = [int(radius * sin(angle) + width / 2.0), int(radius * cos(angle) + width / 2.0)] self._turtles.add_to_dict(turtle_name, self)
def _generate_grid(self): ''' Make a new set of dots for a grid of size edge ''' i = 0 for y in range(self._edge): for x in range(self._edge): xoffset = int((self._width - self._edge * self._dot_size - (self._edge - 1) * self._space) / 2.) yoffset = int((self._height - self._edge * self._dot_size - (self._edge - 1) * self._space) / 2.) if i < len(self._dots): self._dots[i].move( (xoffset + x * (self._dot_size + self._space), yoffset + y * (self._dot_size + self._space))) else: self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), yoffset + y * (self._dot_size + self._space), self._new_dot(self._colors[0]))) self._dots[i].type = 0 self._dots[-1].set_label_attributes(40) i += 1 # and initialize a few variables we'll need. self._all_clear()
def _generate_spiral(self): ''' Make a new set of dots for a sprial ''' for z in range(4): for i in range(len(colors)): if self._zones[i] == z: self._dots.append( Sprite(self._sprites, self._xy[0], self._xy[1], self._new_dot(colors[i]))) self._dots[-1].type = i self._calc_next_dot_position() if self._xo_man is None: x = 510 * self._scale y = 280 * self._scale self._xo_man = Sprite(self._sprites, x, y, self._new_xo_man(self.colors)) self._xo_man.type = None
def configure_cb(self, event): self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - GRID_CELL_SIZE self._scale = Gdk.Screen.height() / 900.0 # We need to resize the backgrounds width, height = self._calc_background_size() for bg in self._backgrounds.keys(): if bg == 'custom': path = self._custom_dsobject.file_path pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( path, width, height) else: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( os.path.join(self._path, 'images', bg), width, height) if Gdk.Screen.height() > Gdk.Screen.width(): pixbuf = self._crop_to_portrait(pixbuf) self._backgrounds[bg] = pixbuf self._background = Sprite(self._sprites, 0, 0, self._backgrounds[self._current_bg]) self._background.set_layer(-100) self._background.type = 'background' # and resize and reposition the bars self.bar.resize_all() self.bar.show_bar(2) self._current_bar = self.bar.get_bar(2) # Calculate a new accerlation based on screen height. self._ddy = (6.67 * self._height) / (STEPS * STEPS) self._guess_orientation()
def _make_wedge_bar(self, nsegments): ''' Create a wedged-shaped bar with n segments ''' s = 3.5 # add provision for stroke width svg = svg_header(self._width, BAR_HEIGHT * self._scale + s, 1.0) dx = self._width / float(nsegments) dy = (BAR_HEIGHT * self._scale) / float(nsegments) for i in range(int(nsegments) // 2): svg += svg_wedge(dx, BAR_HEIGHT * self._scale + s, i * 2 * dx + s, i * 2 * dy + s, (i * 2 + 1) * dy + s, '#000000', '#FFFFFF') svg += svg_wedge(dx, BAR_HEIGHT * self._scale + s, (i * 2 + 1) * dx + s, (i * 2 + 1) * dy + s, (i * 2 + 2) * dy + s, '#000000', '#FFFFFF') if int(nsegments) % 2 == 1: # odd svg += svg_wedge(dx, BAR_HEIGHT * self._scale + s, (i * 2 + 2) * dx + s, (i * 2 + 2) * dy + s, BAR_HEIGHT * self._scale + s, '#000000', '#FFFFFF') svg += svg_footer() self.bars[nsegments] = Sprite(self._sprites, 0, 0, svg_str_to_pixbuf(svg)) self.bars[nsegments].set_layer(2) self.bars[nsegments].set_label_attributes(18, horiz_align="left", i=0) self.bars[nsegments].set_label_attributes(18, horiz_align="right", i=1) self.bars[nsegments].set_label_color('black', i=0) self.bars[nsegments].set_label_color('white', i=1) self.bars[nsegments].set_label(' 0', i=0) self.bars[nsegments].set_label('1 ', i=1) self.bars[nsegments].move( (0, self._height - BAR_HEIGHT * self._scale))
class Card: # Spade = 1,-1 # Heart = 2,-2 # Club = 3,-3 # Diamond = 4,-4 def __init__(self, game, c, i, x, y): self.north = c[0] self.east = c[1] self.south = c[2] self.west = c[3] self.orientation = 0 self.images = [] self.images.append(load_image( os.path.join(game.path, 'card%d.svg' % (i)), game.card_dim * game.scale, game.card_dim * game.scale)) for j in range(3): self.images.append(self.images[j].rotate_simple(90)) # create sprite from svg file self.spr = Sprite(game.sprites, x, y, self.images[0]) self.spr.set_label(i) def reset_image(self, game, i): while self.orientation != 0: self.rotate_ccw() def set_orientation(self, r, rotate_spr=True): while r != self.orientation: self.rotate_ccw(rotate_spr) def rotate_ccw(self, rotate_spr=True): # print "rotating card " + str(self.spr.label) tmp = self.north self.north = self.east self.east = self.south self.south = self.west self.west = tmp self.orientation += 90 if self.orientation == 360: self.orientation = 0 if rotate_spr is True: self.spr.set_shape(self.images[int(self.orientation / 90)]) def print_card(self): print "(" + str(self.north) + "," + str(self.east) + \ "," + str(self.south) + "," + str(self.west) + \ ") " + str(self.rotate) + "ccw" + \ " x:" + str(self.spr.x) + " y:" + str(self.spr.y)
def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']): self._activity = parent self._colors = colors self._canvas = canvas parent.show_all() self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) self._canvas.connect("draw", self.__draw_cb) self._canvas.connect("button-press-event", self._button_press_cb) self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - (GRID_CELL_SIZE * 1.5) self._scale = self._height / (14.0 * DOT_SIZE * 1.2) self._dot_size = int(DOT_SIZE * self._scale) self._turtle_offset = 0 self._space = int(self._dot_size / 5.) self._orientation = 0 self.level = 0 self.custom_strategy = None self.strategies = [BEGINNER_STRATEGY, INTERMEDIATE_STRATEGY, EXPERT_STRATEGY, self.custom_strategy] self.strategy = self.strategies[self.level] self._timeout_id = None # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) self._dots = [] for y in range(THIRTEEN): for x in range(THIRTEEN): xoffset = int((self._width - THIRTEEN * (self._dot_size + \ self._space) - self._space) / 2.) if y % 2 == 1: xoffset += int((self._dot_size + self._space) / 2.) if x == 0 or y == 0 or x == THIRTEEN - 1 or y == THIRTEEN - 1: self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), y * (self._dot_size + self._space), self._new_dot('#B0B0B0'))) else: self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), y * (self._dot_size + self._space), self._new_dot(self._colors[FILL]))) self._dots[-1].type = False # not set # Put a turtle at the center of the screen... self._turtle_images = [] self._rotate_turtle(self._new_turtle()) self._turtle = Sprite(self._sprites, 0, 0, self._turtle_images[0]) self._move_turtle(self._dots[int(THIRTEEN * THIRTEEN / 2)].get_xy()) # ...and initialize. self._all_clear()
def __init__(self,bg=(0,0,0),snake=(0,240,0),apple=(255,0,0),snake_max_len=4): super(SnakeScene,self).__init__(tempo=360,bg=bg) self.snake = Sprite(color=snake,blend=False,z=10,trail=snake_max_len) self.add_sprite(0,0,self.snake) self.apple_time = 0 self.apple = Sprite(color=apple,blend=False,z=5) self.add_sprite(0,0,self.apple) self.snake_reset() self.apple_reset() self.points = 0 self._snake_dir = rint(0,4)
def __init__(self, turtle_window, n): '''This class handles the display of palette selectors (Only relevant to GNOME version and very old versions of Sugar). ''' self.shapes = [] self.spr = None self._turtle_window = turtle_window self._index = n if not n < len(palette_names): # Shouldn't happen, but hey... debug_output('palette index %d is out of range' % n, self._turtle_window.running_sugar) self._name = 'extras' else: self._name = palette_names[n] icon_pathname = None for path in self._turtle_window.icon_paths: if os.path.exists(os.path.join(path, '%soff.svg' % (self._name))): icon_pathname = os.path.join(path, '%soff.svg' % (self._name)) break if icon_pathname is not None: off_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname)) else: off_shape = svg_str_to_pixbuf(svg_from_file(os.path.join( self._turtle_window.icon_paths[0], 'extrasoff.svg'))) error_output('Unable to open %soff.svg' % (self._name), self._turtle_window.running_sugar) icon_pathname = None for path in self._turtle_window.icon_paths: if os.path.exists(os.path.join(path, '%son.svg' % (self._name))): icon_pathname = os.path.join(path, '%son.svg' % (self._name)) break if icon_pathname is not None: on_shape = svg_str_to_pixbuf(svg_from_file(icon_pathname)) else: on_shape = svg_str_to_pixbuf(svg_from_file(os.path.join( self._turtle_window.icon_paths[0], 'extrason.svg'))) error_output('Unable to open %son.svg' % (self._name), self._turtle_window.running_sugar) self.shapes.append(off_shape) self.shapes.append(on_shape) x = int(ICON_SIZE * self._index) self.spr = Sprite(self._turtle_window.sprite_list, x, 0, off_shape) self.spr.type = 'selector' self.spr.name = self._name self.set_layer()
def __init__(self, sprites, svg, svgs, tile_type='tile', number=0): self.highlight = [svg_str_to_pixbuf(svg)] self.spr = Sprite(sprites, 0, 0, self.highlight[0]) for s in svgs: self.highlight.append(svg_str_to_pixbuf(s)) self.paths = [] # [[N, E, S, W], [N, E, S, W]] self.shape = None self.orientation = 0 self.type = tile_type self.number = number self.value = 1 self.spr.set_label_color('#FF0000')
def __init__(self, tw, width, height): """ Create a sprite to hold the canvas. """ self.tw = tw self.width = width self.height = height if self.tw.interactive_mode: self.canvas = Sprite(tw.sprite_list, 0, 0, gtk.gdk.Pixmap(self.tw.area, self.width * 2, self.height * 2, -1)) else: self.canvas = Sprite(None, 0, 0, self.tw.window) self.canvas.set_layer(CANVAS_LAYER) (self.cx, self.cy) = self.canvas.get_xy() self.canvas.type = 'canvas' self.gc = self.canvas.images[0].new_gc() self.cm = self.gc.get_colormap() self.fgrgb = [255, 0, 0] self.fgcolor = self.cm.alloc_color('red') self.bgrgb = [255, 248, 222] self.bgcolor = self.cm.alloc_color('#fff8de') self.textsize = 48 # depreciated self.textcolor = self.cm.alloc_color('blue') self.tw.active_turtle.show() self.shade = 0 self.pendown = False self.xcor = 0 self.ycor = 0 self.heading = 0 self.pensize = 5 self.tcolor = 0 self.color = 0 self.gray = 100 self.fill = False self.poly_points = [] self.svg = SVG() self.svg.set_fill_color('none') self.tw.svg_string = '' self.clearscreen(False)
def update(self, t=0, v=None): """ update render position (velocity is vector in OpenGL style coorinates/timestep)""" # if update() has not been run, set time_since_update to current time Sprite.update(self, t=t, v=v) p1, p2 = self.position_current if self.use_polar_coords: x, y = pol2cart(p1, p2) else: x, y = (p1, p2) sz = self.size th = self.thickness self.vertices = [ # horizontal beam (x - sz / 2.0, y + th / 2), # left-top (x - sz / 2.0, y - th / 2), # left-bottom (x + sz / 2.0, y - th / 2), # right-bottom (x + sz / 2.0, y + th / 2), # right-top # vertical beam (x - th / 2, y + sz / 2.0), # left-top (x - th / 2, y - sz / 2.0), # left-bottom (x + th / 2, y - sz / 2.0), # right-bottom (x + th / 2, y + sz / 2.0), # right-top ] self.t_since_update = t # set time_since_update to current time
def __init__(self, game, c, i, x, y): self.north = c[0] self.east = c[1] self.south = c[2] self.west = c[3] self.orientation = 0 self.images = [] self.images.append(load_image( os.path.join(game.path, 'card%d.svg' % (i)), game.card_dim * game.scale, game.card_dim * game.scale)) for j in range(3): self.images.append(self.images[j].rotate_simple(90)) # create sprite from svg file self.spr = Sprite(game.sprites, x, y, self.images[0]) self.spr.set_label(i)
def __init__(self, sprites, path, card_dim, scale, c, x, y, shape='circle'): """ Load a card from a precomputed SVG. """ self.images = [] self.orientation = 0 if shape == 'triangle': file = "%s/triangle-r0-%d.svg" % (path, c) self.increment = 60 elif shape == 'hexagon': file = "%s/hexagon-r0-%d.svg" % (path, c) self.increment = 120 else: file = "%s/card-%d.svg" % (path, c) self.increment = 90 self.images.append(load_image(file, card_dim * scale, card_dim * scale)) if shape == 'triangle': file = "%s/triangle-r60-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r120-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r180-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r240-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) file = "%s/triangle-r300-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) elif shape == 'hexagon': file = "%s/hexagon-r120-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) file = "%s/hexagon-r240-%d.svg" % (path, c) self.images.append(load_image(file, card_dim * scale, card_dim * scale)) else: for r in range(3): self.images.append(self.images[r].rotate_simple(90)) # create sprite from svg file self.spr = Sprite(sprites, x, y, self.images[0])
def __init__(self, sprites, filename): self._current_frame = 0 self._frames = [] # Easter Egg animation self._sprites = sprites self.ball = Sprite(self._sprites, 0, 0, svg_str_to_pixbuf( svg_from_file(filename))) self.ball.set_layer(3) self.ball.set_label_attributes(24, vert_align='top') ball = extract_svg_payload(file(filename, 'r')) for i in range(8): self._frames.append(Sprite( self._sprites, 0, 0, svg_str_to_pixbuf( svg_header(SIZE[0], SIZE[1], 1.0) + TRANSFORMS[i] + ball + PUNCTURE + AIR + '</g>' + svg_footer()))) for frame in self._frames: frame.set_layer(3) frame.move((0, -SIZE[1])) # move animation frames off screen
def __init__(self, turtles, key, turtle_colors=None): """ The turtle is not a block, just a sprite with an orientation """ self.x = 0 self.y = 0 self.hidden = False self.shapes = [] self.custom_shapes = False self.type = 'turtle' self.heading = 0 self.pen_shade = 50 self.pen_color = 0 self.pen_gray = 100 self.pen_size = 5 self.pen_state = True # If the turtle key is an int, we'll use a palette color as the # turtle color try: int_key = int(key) use_color_table = True except ValueError: use_color_table = False if turtle_colors is not None: self.colors = turtle_colors[:] self.shapes = generate_turtle_pixbufs(self.colors) elif use_color_table: fill = wrap100(int_key) stroke = wrap100(fill + 10) self.colors = ['#%06x' % (color_table[fill]), '#%06x' % (color_table[stroke])] self.shapes = generate_turtle_pixbufs(self.colors) else: self.shapes = turtles.get_pixbufs() if turtles.sprite_list is not None: self.spr = Sprite(turtles.sprite_list, 0, 0, self.shapes[0]) else: self.spr = None turtles.add_to_dict(key, self)
def _create_sprites(self, path): ''' Create all of the sprites we'll need ''' self.smiley_graphic = svg_str_to_pixbuf(svg_from_file( os.path.join(path, 'images', 'smiley.svg'))) self.frown_graphic = svg_str_to_pixbuf(svg_from_file( os.path.join(path, 'images', 'frown.svg'))) self.blank_graphic = svg_str_to_pixbuf( svg_header(REWARD_HEIGHT, REWARD_HEIGHT, 1.0) + svg_rect(REWARD_HEIGHT, REWARD_HEIGHT, 5, 5, 0, 0, 'none', 'none') + svg_footer()) self.ball = Ball(self._sprites, os.path.join(path, 'images', 'soccerball.svg')) self._current_frame = 0 self.bar = Bar(self._sprites, self.ball.width(), COLORS) self._current_bar = self.bar.get_bar(2) self.ball_y_max = self.bar.bar_y() - self.ball.height() + \ int(BAR_HEIGHT / 2.) self.ball.move_ball((int((self._width - self.ball.width()) / 2), self.ball_y_max)) self._backgrounds = {} width, height = self._calc_background_size() pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( os.path.join(path, 'images', 'grass_background.png'), width, height) if Gdk.Screen.height() > Gdk.Screen.width(): pixbuf = self._crop_to_portrait(pixbuf) self._backgrounds['grass_background.png'] = pixbuf self._background = Sprite(self._sprites, 0, 0, pixbuf) self._background.set_layer(-100) self._background.type = 'background' self._current_bg = 'grass_background.png'
def _make_wedge_mark(self): ''' Make a mark to show the fraction position on the bar. ''' dx = self._ball_size / 2. n = (self._width - self._ball_size) / dx dy = (BAR_HEIGHT * self._scale) / n s = 3.5 i = int(n / 2) - 1 mark = svg_header(self._ball_size, BAR_HEIGHT * self._scale + s, 1.0) mark += svg_wedge(dx, BAR_HEIGHT * self._scale + s, s, i * 2 * dy + s, (i * 2 + 1) * dy + s, '#FF0000', '#FFFFFF') mark += svg_wedge(dx, BAR_HEIGHT * self._scale + s, dx + s, (i * 2 + 1) * dy + s, (i * 2 + 2) * dy + s, '#FF0000', '#FFFFFF') mark += svg_footer() self.mark = Sprite(self._sprites, 0, self._height, # hide off bottom of screen svg_str_to_pixbuf(mark)) self.mark.set_layer(1)
def __init__(self, turtles, key, turtle_colors=None): """ The turtle is not a block, just a sprite with an orientation """ self.x = 0.0 self.y = 0.0 self.hidden = False self.shapes = [] self.custom_shapes = False self.type = 'turtle' self.name = key self.heading = 0.0 self.pen_shade = 50 self.pen_color = 0 self.pen_gray = 100 self.pen_size = 5 self.pen_state = True self.label_block = None self._prep_shapes(key, turtles, turtle_colors) # Choose a random angle from which to attach the turtle label. if turtles.sprite_list is not None: self.spr = Sprite(turtles.sprite_list, 0, 0, self.shapes[0]) angle = uniform(0, pi * 4 / 3.0) # 240 degrees w = self.shapes[0].get_width() r = w * 0.67 # Restrict angle the the sides 30-150; 210-330 if angle > pi * 2 / 3.0: angle += pi / 2.0 # + 90 self.label_xy = [int(r * sin(angle)), int(r * cos(angle) + w / 2.0)] else: angle += pi / 6.0 # + 30 self.label_xy = [int(r * sin(angle) + w / 2.0), int(r * cos(angle) + w / 2.0)] else: self.spr = None turtles.add_to_dict(key, self)
def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']): self._activity = parent self._colors = ['#FFFFFF'] self._colors.append(colors[0]) self._colors.append(colors[1]) self._colors.append('#000000') self._canvas = canvas if parent is not None: parent.show_all() self._parent = parent self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) self._canvas.connect("draw", self.__draw_cb) self._canvas.connect("button-press-event", self._button_press_cb) self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - (GRID_CELL_SIZE * 1.5) self._scale = self._width / (20 * DOT_SIZE * 1.1) self._dot_size = int(DOT_SIZE * self._scale) self._space = int(self._dot_size / 5.) self.we_are_sharing = False self._sum = 0 self._mode = 'ten' self.custom = [1, 1, 1, 1, 10] # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) Sprite(self._sprites, 0, 0, self._box(self._width, self._height, color=colors[1])) self._number_box = Sprite(self._sprites, 0, 0, self._box( self._width, 2 * self._dot_size, color=colors[1])) self._number_box.set_label_attributes(48) self._dots = [] for p in range(SIX): y = self._height - self._space Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int(p * self._width / 6) + self._space y -= self._dot_size for d in range(3): # bottom of fives row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size + self._space for d in range(2): # top of fives row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size for d in range(2): # bottom of threes row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space x = int((p * self._width / 6.) + self._dot_size) + self._space y -= self._dot_size + self._space for d in range(1): # top of threes row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size for d in range(2): # twos row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int((p * self._width / 6.) + self._dot_size) + self._space y -= self._dot_size for d in range(1): # ones row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) for p in range(SIX - 1): x = int((p + 1) * self._width / 6) Sprite(self._sprites, x - 1, y, self._line(vertical=True)) # and initialize a few variables we'll need. self._all_clear()
class Yupana(): def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']): self._activity = parent self._colors = ['#FFFFFF'] self._colors.append(colors[0]) self._colors.append(colors[1]) self._colors.append('#000000') self._canvas = canvas if parent is not None: parent.show_all() self._parent = parent self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) self._canvas.connect("draw", self.__draw_cb) self._canvas.connect("button-press-event", self._button_press_cb) self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - (GRID_CELL_SIZE * 1.5) self._scale = self._width / (20 * DOT_SIZE * 1.1) self._dot_size = int(DOT_SIZE * self._scale) self._space = int(self._dot_size / 5.) self.we_are_sharing = False self._sum = 0 self._mode = 'ten' self.custom = [1, 1, 1, 1, 10] # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) Sprite(self._sprites, 0, 0, self._box(self._width, self._height, color=colors[1])) self._number_box = Sprite(self._sprites, 0, 0, self._box( self._width, 2 * self._dot_size, color=colors[1])) self._number_box.set_label_attributes(48) self._dots = [] for p in range(SIX): y = self._height - self._space Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int(p * self._width / 6) + self._space y -= self._dot_size for d in range(3): # bottom of fives row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size + self._space for d in range(2): # top of fives row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size for d in range(2): # bottom of threes row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space x = int((p * self._width / 6.) + self._dot_size) + self._space y -= self._dot_size + self._space for d in range(1): # top of threes row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int((p * self._width / 6.) + self._dot_size / 2.) + self._space y -= self._dot_size for d in range(2): # twos row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) x = int((p * self._width / 6.) + self._dot_size) + self._space y -= self._dot_size for d in range(1): # ones row self._dots.append( Sprite(self._sprites, x, y, self._new_dot(self._colors[0]))) self._dots[-1].type = 0 # not set # self._dots[-1].set_label_color('white') x += self._dot_size + self._space y -= self._dot_size Sprite(self._sprites, 0, y, self._line(vertical=False)) for p in range(SIX - 1): x = int((p + 1) * self._width / 6) Sprite(self._sprites, x - 1, y, self._line(vertical=True)) # and initialize a few variables we'll need. self._all_clear() def _all_clear(self): ''' Things to reinitialize when starting up a new yupana. ''' self._sum = 0 for dot in self._dots: if dot.type > 0: dot.type = 0 dot.set_shape(self._new_dot(self._colors[0])) dot.set_label('') self._set_label(str(self._sum)) def _initiating(self): return self._activity.initiating def new_yupana(self, mode=None): ''' Create a new yupana. ''' self._all_clear() if mode is not None: self._mode = mode o = (SIX - 1) * (TEN + 1) # only label units if mode == 'ten': for i in range(TEN + 1): self._dots[o + i].set_label('1') self._dots[o - 1].set_label('10') elif mode == 'twenty': for i in range(TEN + 1): if i in [7, 10]: self._dots[o + i].set_label('1') else: self._dots[o + i].set_label('2') self._dots[o - 1].set_label('20') elif mode == 'factor': for i in range(TEN + 1): if i in [10]: self._dots[o + i].set_label('1') elif i in [8, 9]: self._dots[o + i].set_label('2') elif i in [5, 6, 7]: self._dots[o + i].set_label('3') else: self._dots[o + i].set_label('5') self._dots[o - 1].set_label('10') elif mode == 'fibonacci': for i in range(TEN + 1): if i in [10]: self._dots[o + i].set_label('1') elif i in [8, 9]: self._dots[o + i].set_label('2') elif i in [5, 6, 7]: self._dots[o + i].set_label('5') else: self._dots[o + i].set_label('20') self._dots[o - 1].set_label('60') else: # custom for i in range(TEN + 1): if i in [10]: self._dots[o + i].set_label(str(self.custom[0])) elif i in [8, 9]: self._dots[o + i].set_label(str(self.custom[1])) elif i in [5, 6, 7]: self._dots[o + i].set_label(str(self.custom[2])) else: self._dots[o + i].set_label(str(self.custom[3])) self._dots[o - 1].set_label(str(self.custom[4])) if self.we_are_sharing: _logger.debug('sending a new yupana') self._parent.send_new_yupana() def restore_yupana(self, dot_list): ''' Restore a yumpana from the Journal or share ''' for i, dot in enumerate(dot_list): self._dots[i].type = dot self._dots[i].set_shape(self._new_dot( self._colors[self._dots[i].type])) if self._dots[i].type == 1: self._sum += self._calc_bead_value(i) self._set_label(str(self._sum)) def save_yupana(self): ''' Return dot list and orientation for saving to Journal or sharing ''' dot_list = [] for dot in self._dots: dot_list.append(dot.type) return [self._mode, dot_list] def _set_label(self, string): ''' Set the label in the toolbar or the window frame. ''' self._number_box.set_label(string) # self._activity.status.set_label(string) def _button_press_cb(self, win, event): win.grab_focus() x, y = map(int, event.get_coords()) spr = self._sprites.find_sprite((x, y)) if spr == None: return if spr.type is not None: spr.type += 1 spr.type %= 2 spr.set_shape(self._new_dot(self._colors[spr.type])) if self.we_are_sharing: _logger.debug('sending a click to the share') self._parent.send_dot_click(self._dots.index(spr), spr.type) if spr.type == 1: self._sum += self._calc_bead_value(self._dots.index(spr)) else: self._sum -= self._calc_bead_value(self._dots.index(spr)) self._set_label(str(self._sum)) return True def _calc_bead_value(self, i): ''' Calculate a bead value based on the index and the mode ''' e = 5 - i / (TEN + 1) m = i % 11 if self._mode == 'ten': return 10 ** e elif self._mode == 'twenty': if m in [7, 10]: return 20 ** e else: return (20 ** e) * 2 elif self._mode == 'factor': if m in [10]: return 10 ** e elif m in [8, 9]: return (10 ** e) * 2 elif m in [5, 6, 7]: return (10 ** e) * 3 else: return (10 ** e) * 5 elif self._mode == 'fibonacci': if m in [10]: return 60 ** e elif m in [8, 9]: return (60 ** e) * 2 elif m in [5, 6, 7]: return (60 ** e) * 5 else: return (60 ** e) * 20 else: # custom if m in [10]: return (self.custom[4] ** e) * self.custom[0] elif m in [8, 9]: return (self.custom[4] ** e) * self.custom[1] elif m in [5, 6, 7]: return (self.custom[4] ** e) * self.custom[2] else: return (self.custom[4] ** e) * self.custom[3] def remote_button_press(self, dot, color): ''' Receive a button press from a sharer ''' self._dots[dot].type = color self._dots[dot].set_shape(self._new_dot(self._colors[color])) def set_sharing(self, share=True): _logger.debug('enabling sharing') self.we_are_sharing = share def _grid_to_dot(self, pos): ''' calculate the dot index from a column and row in the grid ''' return pos[0] + pos[1] * TEN def _dot_to_grid(self, dot): ''' calculate the grid column and row for a dot ''' return [dot % TEN, int(dot / TEN)] def __draw_cb(self, canvas, cr): self._sprites.redraw_sprites(cr=cr) def do_expose_event(self, event): ''' Handle the expose-event by drawing ''' # Restrict Cairo to the exposed area cr = self._canvas.window.cairo_create() cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) cr.clip() # Refresh sprite list self._sprites.redraw_sprites(cr=cr) def _destroy_cb(self, win, event): Gtk.main_quit() def _new_dot(self, color): ''' generate a dot of a color color ''' def darken(color): ''' return a darker color than color ''' gdk_fill_color = Gdk.color_parse(self._fill) gdk_fill_dark_color = Gdk.Color( int(gdk_fill_color.red * 0.5), int(gdk_fill_color.green * 0.5), int(gdk_fill_color.blue * 0.5)).to_string() return str(gdk_fill_dark_color) self._dot_cache = {} if not color in self._dot_cache: self._stroke = color self._fill = color self._fill_dark = darken(color) self._svg_width = self._dot_size self._svg_height = self._dot_size if color in ['#FFFFFF', '#000000']: pixbuf = svg_str_to_pixbuf( self._header() + \ self._circle(self._dot_size / 2., self._dot_size / 2., self._dot_size / 2.) + \ self._footer()) else: pixbuf = svg_str_to_pixbuf( self._header() + \ self._def(self._dot_size) + \ self._gradient(self._dot_size / 2., self._dot_size / 2., self._dot_size / 2.) + \ self._footer()) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self._svg_width, self._svg_height) context = cairo.Context(surface) Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0) context.rectangle(0, 0, self._svg_width, self._svg_height) context.fill() self._dot_cache[color] = surface return self._dot_cache[color] def _line(self, vertical=True): ''' Generate a center line ''' if vertical: self._svg_width = 3 self._svg_height = self._dot_size * 10 + self._space * 2 return svg_str_to_pixbuf( self._header() + \ self._rect(3, self._dot_size * 10 + self._space * 2, 0, 0) + \ self._footer()) else: self._svg_width = self._width self._svg_height = 3 return svg_str_to_pixbuf( self._header() + \ self._rect(self._width, 3, 0, 0) + \ self._footer()) def _box(self, w, h, color='white'): ''' Generate a box ''' self._svg_width = w self._svg_height = h return svg_str_to_pixbuf( self._header() + \ self._rect(self._svg_width, self._svg_height, 0, 0, color=color) + \ self._footer()) def _header(self): return '<svg\n' + 'xmlns:svg="http://www.w3.org/2000/svg"\n' + \ 'xmlns="http://www.w3.org/2000/svg"\n' + \ 'xmlns:xlink="http://www.w3.org/1999/xlink"\n' + \ 'version="1.1"\n' + 'width="' + str(self._svg_width) + '"\n' + \ 'height="' + str(self._svg_height) + '">\n' def _rect(self, w, h, x, y, color='black'): svg_string = ' <rect\n' svg_string += ' width="%f"\n' % (w) svg_string += ' height="%f"\n' % (h) svg_string += ' rx="%f"\n' % (0) svg_string += ' ry="%f"\n' % (0) svg_string += ' x="%f"\n' % (x) svg_string += ' y="%f"\n' % (y) if color == 'black': svg_string += 'style="fill:#000000;stroke:#000000;"/>\n' elif color == 'white': svg_string += 'style="fill:#ffffff;stroke:#ffffff;"/>\n' else: svg_string += 'style="fill:%s;stroke:%s;"/>\n' % (color, color) return svg_string def _circle(self, r, cx, cy): scale = (DOT_SIZE * self._scale) / 55. return '\ <g transform="matrix(%f,0,0,%f,0,0)">\ <path\ d="m 35.798426,4.2187227 c -2.210658,0.9528967 -4.993612,-0.9110169 -7.221856,0 C 23.805784,6.1692574 20.658687,10.945585 17.543179,15.051507 13.020442,21.012013 7.910957,27.325787 6.7103942,34.711004 6.0558895,38.737163 6.434461,43.510925 8.917073,46.747431 c 3.604523,4.699107 15.24614,7.62307 16.048569,7.62307 0.802429,0 8.366957,0.46766 12.036427,-1.203642 2.841316,-1.294111 5.173945,-3.766846 6.820641,-6.419428 2.543728,-4.097563 3.563068,-9.062928 4.21275,-13.841891 C 49.107723,25.018147 48.401726,15.967648 47.433639,9.0332932 47.09109,6.5796321 43.508442,7.2266282 42.329009,5.7211058 41.256823,4.3524824 42.197481,1.860825 40.813604,0.80840168 40.384481,0.48205899 39.716131,0.42556727 39.208747,0.60779459 37.650593,1.1674066 37.318797,3.5633724 35.798426,4.2187227 z"\ style="fill:none;fill-opacity:1;stroke:%s;stroke-width:3.0" />\ </g>' % ( scale, scale, self._colors[1]) def _gradient(self, r, cx, cy): scale = (DOT_SIZE * self._scale) / 55. return '\ <defs>\ <linearGradient\ id="linearGradient3769">\ <stop\ id="stop3771"\ style="stop-color:#ffff00;stop-opacity:1"\ offset="0" />\ <stop\ id="stop3773"\ style="stop-color:#ffff00;stop-opacity:0"\ offset="1" />\ </linearGradient>\ <linearGradient\ x1="10.761448"\ y1="41.003559"\ x2="56.70686"\ y2="41.003559"\ id="linearGradient2999"\ xlink:href="#linearGradient3769"\ gradientUnits="userSpaceOnUse"\ gradientTransform="matrix(0.93094239,0,0,0.93094239,-3.9217825,-2.4013121)" />\ </defs>\ <g transform="matrix(%f,0,0,%f,0,0)">\ <path\ d="m 35.798426,4.2187227 c -2.210658,0.9528967 -4.993612,-0.9110169 -7.221856,0 C 23.805784,6.1692574 20.658687,10.945585 17.543179,15.051507 13.020442,21.012013 7.910957,27.325787 6.7103942,34.711004 6.0558895,38.737163 6.434461,43.510925 8.917073,46.747431 c 3.604523,4.699107 15.24614,7.62307 16.048569,7.62307 0.802429,0 8.366957,0.46766 12.036427,-1.203642 2.841316,-1.294111 5.173945,-3.766846 6.820641,-6.419428 2.543728,-4.097563 3.563068,-9.062928 4.21275,-13.841891 C 49.107723,25.018147 48.401726,15.967648 47.433639,9.0332932 47.09109,6.5796321 43.508442,7.2266282 42.329009,5.7211058 41.256823,4.3524824 42.197481,1.860825 40.813604,0.80840168 40.384481,0.48205899 39.716131,0.42556727 39.208747,0.60779459 37.650593,1.1674066 37.318797,3.5633724 35.798426,4.2187227 z"\ style="fill:#fffec2;fill-opacity:1;stroke:#878600;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />\ <path\ d="m 15.11608,18.808876 c 1.271657,-1.444003 4.153991,-3.145785 5.495465,-1.7664 2.950062,3.033434 -6.07961,8.17155 -4.219732,11.972265 0.545606,1.114961 2.322391,1.452799 3.532799,1.177599 5.458966,-1.241154 6.490591,-12.132334 12.070397,-11.677864 1.584527,0.129058 2.526156,2.269906 2.845867,3.827199 0.453143,2.207236 -1.962667,6.182399 -1.570133,6.574932 0.392533,0.392533 2.371401,0.909584 3.140266,0.196266 1.91857,-1.779962 -0.490667,-7.752531 0.09813,-7.850664 0.5888,-0.09813 4.421663,2.851694 5.789865,5.004799 0.583188,0.917747 -0.188581,2.956817 0.8832,3.140266 2.128963,0.364398 1.601562,-5.672021 3.729066,-5.299199 1.836829,0.321884 1.450925,3.532631 1.471999,5.397332 0.06743,5.965698 -0.565586,12.731224 -4.317865,17.369596 -3.846028,4.75426 -10.320976,8.31978 -16.388263,7.556266 C 22.030921,53.720741 16.615679,52.58734 11.485147,49.131043 7.9833717,46.771994 6.8028191,42.063042 6.5784815,37.846738 6.3607378,33.754359 8.3381535,29.765466 10.111281,26.070741 c 1.271951,-2.650408 2.940517,-4.917813 5.004799,-7.261865 z"\ style="fill:url(#linearGradient2999);fill-opacity:1;stroke:none" />\ <path\ d="m 32.382709,4.7758124 c -0.123616,1.0811396 1.753928,2.8458658 2.728329,2.9439992 0.974405,0.098134 6.718874,0.7298319 9.159392,-0.1962668 0.820281,-0.3112699 0.968884,-0.9547989 0.974407,-1.4719993 0.02053,-1.9240971 0.03247,-4.7715376 -3.507853,-5.49546551 C 39.556079,0.11012647 37.217081,1.4131653 35.500801,2.2243463 34.054814,2.9077752 32.496703,3.7788369 32.382709,4.7758124 z"\ style="fill:#b69556;fill-opacity:1;stroke:#b69556;stroke-width:1.31189477px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /></g>' % ( scale, scale) def _def(self, r): return ' <defs>\ <linearGradient\ id="linearGradient3755">\ <stop\ id="stop3757"\ style="stop-color:%s;stop-opacity:1"\ offset="0" />\ <stop\ id="stop3759"\ style="stop-color:%s;stop-opacity:1"\ offset="1" />\ </linearGradient>\ <radialGradient\ cx="0"\ cy="0"\ r="%f"\ fx="%f"\ fy="%f"\ id="radialGradient3761"\ xlink:href="#linearGradient3755"\ gradientUnits="userSpaceOnUse" />\ </defs>\ ' % (self._fill, self._fill_dark, r, r / 3, r / 3) def _footer(self): return '</svg>\n'
class Turtle: def __init__(self, turtles, turtle_name, turtle_colors=None): ''' The turtle is not a block, just a sprite with an orientation ''' self.spr = None self.label_block = None self._turtles = turtles self._shapes = [] self._custom_shapes = False self._name = turtle_name self._hidden = False self._remote = False self._x = 0.0 self._y = 0.0 self._heading = 0.0 self._half_width = 0 self._half_height = 0 self._drag_radius = None self._pen_shade = 50 self._pen_color = 0 self._pen_gray = 100 if self._turtles.turtle_window.coord_scale == 1: self._pen_size = 5 else: self._pen_size = 1 self._pen_state = True self._pen_fill = False self._poly_points = [] self._prep_shapes(turtle_name, self._turtles, turtle_colors) # Create a sprite for the turtle in interactive mode. if turtles.sprite_list is not None: self.spr = Sprite(self._turtles.sprite_list, 0, 0, self._shapes[0]) self._calculate_sizes() # Choose a random angle from which to attach the turtle # label to be used when sharing. angle = uniform(0, pi * 4 / 3.0) # 240 degrees width = self._shapes[0].get_width() radius = width * 0.67 # Restrict the angle to the sides: 30-150; 210-330 if angle > pi * 2 / 3.0: angle += pi / 2.0 # + 90 self.label_xy = [int(radius * sin(angle)), int(radius * cos(angle) + width / 2.0)] else: angle += pi / 6.0 # + 30 self.label_xy = [int(radius * sin(angle) + width / 2.0), int(radius * cos(angle) + width / 2.0)] self._turtles.add_to_dict(turtle_name, self) def _calculate_sizes(self): self._half_width = int(self.spr.rect.width / 2.0) self._half_height = int(self.spr.rect.height / 2.0) self._drag_radius = ((self._half_width * self._half_width) + (self._half_height * self._half_height)) / 6 def set_remote(self): self._remote = True def get_remote(self): return self._remote def _prep_shapes(self, name, turtles=None, turtle_colors=None): # If the turtle name is an int, we'll use a palette color as the # turtle color try: int_key = int(name) use_color_table = True except ValueError: use_color_table = False if turtle_colors is not None: self.colors = turtle_colors[:] self._shapes = generate_turtle_pixbufs(self.colors) elif use_color_table: fill = wrap100(int_key) stroke = wrap100(fill + 10) self.colors = ['#%06x' % (COLOR_TABLE[fill]), '#%06x' % (COLOR_TABLE[stroke])] self._shapes = generate_turtle_pixbufs(self.colors) else: if turtles is not None: self.colors = DEFAULT_TURTLE_COLORS self._shapes = turtles.get_pixbufs() def set_turtle_colors(self, turtle_colors): ''' reset the colors of a preloaded turtle ''' if turtle_colors is not None: self.colors = turtle_colors[:] self._shapes = generate_turtle_pixbufs(self.colors) self.set_heading(self._heading, share=False) def set_shapes(self, shapes, i=0): ''' Reskin the turtle ''' n = len(shapes) if n == 1 and i > 0: # set shape[i] if i < len(self._shapes): self._shapes[i] = shapes[0] elif n == SHAPES: # all shapes have been precomputed self._shapes = shapes[:] else: # rotate shapes if n != 1: debug_output("%d images passed to set_shapes: ignoring" % (n), self._turtles.turtle_window.running_sugar) if self._heading == 0.0: # rotate the shapes images = [] w, h = shapes[0].get_width(), shapes[0].get_height() nw = nh = int(sqrt(w * w + h * h)) for i in range(SHAPES): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, nw, nh) context = cairo.Context(surface) context = gtk.gdk.CairoContext(context) context.translate(nw / 2.0, nh / 2.0) context.rotate(i * 10 * pi / 180.) context.translate(-nw / 2.0, -nh / 2.0) context.set_source_pixbuf(shapes[0], (nw - w) / 2.0, (nh - h) / 2.0) context.rectangle(0, 0, nw, nh) context.fill() images.append(surface) self._shapes = images[:] else: # associate shape with image at current heading j = int(self._heading + 5) % 360 / (360 / SHAPES) self._shapes[j] = shapes[0] self._custom_shapes = True self.show() self._calculate_sizes() def reset_shapes(self): ''' Reset the shapes to the standard turtle ''' if self._custom_shapes: self._shapes = generate_turtle_pixbufs(self.colors) self._custom_shapes = False self._calculate_sizes() def set_heading(self, heading, share=True): ''' Set the turtle heading (one shape per 360/SHAPES degrees) ''' try: self._heading = heading except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._heading %= 360 self._update_sprite_heading() if self._turtles.turtle_window.sharing() and share: event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick, round_int(self._heading)])) self._turtles.turtle_window.send_event(event) def _update_sprite_heading(self): ''' Update the sprite to reflect the current heading ''' i = (int(self._heading + 5) % 360) / (360 / SHAPES) if not self._hidden and self.spr is not None: try: self.spr.set_shape(self._shapes[i]) except IndexError: self.spr.set_shape(self._shapes[0]) def set_color(self, color=None, share=True): ''' Set the pen color for this turtle. ''' # Special case for color blocks if color is not None and color in COLORDICT: self.set_shade(COLORDICT[color][1], share) self.set_gray(COLORDICT[color][2], share) if COLORDICT[color][0] is not None: self.set_color(COLORDICT[color][0], share) color = COLORDICT[color][0] else: color = self._pen_color elif color is None: color = self._pen_color try: self._pen_color = color except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade, gray=self._pen_gray, color=self._pen_color) if self._turtles.turtle_window.sharing() and share: event = 'c|%s' % (data_to_string([self._turtles.turtle_window.nick, round_int(self._pen_color)])) self._turtles.turtle_window.send_event(event) def set_gray(self, gray=None, share=True): ''' Set the pen gray level for this turtle. ''' if gray is not None: try: self._pen_gray = gray except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return if self._pen_gray < 0: self._pen_gray = 0 if self._pen_gray > 100: self._pen_gray = 100 self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade, gray=self._pen_gray, color=self._pen_color) if self._turtles.turtle_window.sharing() and share: event = 'g|%s' % (data_to_string([self._turtles.turtle_window.nick, round_int(self._pen_gray)])) self._turtles.turtle_window.send_event(event) def set_shade(self, shade=None, share=True): ''' Set the pen shade for this turtle. ''' if shade is not None: try: self._pen_shade = shade except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade, gray=self._pen_gray, color=self._pen_color) if self._turtles.turtle_window.sharing() and share: event = 's|%s' % (data_to_string([self._turtles.turtle_window.nick, round_int(self._pen_shade)])) self._turtles.turtle_window.send_event(event) def set_pen_size(self, pen_size=None, share=True): ''' Set the pen size for this turtle. ''' if pen_size is not None: try: self._pen_size = max(0, pen_size) except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._turtles.turtle_window.canvas.set_pen_size( self._pen_size * self._turtles.turtle_window.coord_scale) if self._turtles.turtle_window.sharing() and share: event = 'w|%s' % (data_to_string([self._turtles.turtle_window.nick, round_int(self._pen_size)])) self._turtles.turtle_window.send_event(event) def set_pen_state(self, pen_state=None, share=True): ''' Set the pen state (down==True) for this turtle. ''' if pen_state is not None: self._pen_state = pen_state if self._turtles.turtle_window.sharing() and share: event = 'p|%s' % (data_to_string([self._turtles.turtle_window.nick, self._pen_state])) self._turtles.turtle_window.send_event(event) def set_fill(self, state=False): self._pen_fill = state if not self._pen_fill: self._poly_points = [] def set_poly_points(self, poly_points=None): if poly_points is not None: self._poly_points = poly_points[:] def start_fill(self): self._pen_fill = True self._poly_points = [] def stop_fill(self, share=True): self._pen_fill = False if len(self._poly_points) == 0: return self._turtles.turtle_window.canvas.fill_polygon(self._poly_points) if self._turtles.turtle_window.sharing() and share: shared_poly_points = [] for p in self._poly_points: x, y = self._turtles.turtle_to_screen_coordinates( (p[1], p[2])) if p[0] in ['move', 'line']: shared_poly_points.append((p[0], x, y)) elif p[0] in ['rarc', 'larc']: shared_poly_points.append((p[0], x, y, p[3], p[4], p[5])) event = 'F|%s' % (data_to_string( [self._turtles.turtle_window.nick, shared_poly_points])) self._turtles.turtle_window.send_event(event) self._poly_points = [] def hide(self): if self.spr is not None: self.spr.hide() if self.label_block is not None: self.label_block.spr.hide() self._hidden = True def show(self): if self.spr is not None: self.spr.set_layer(TURTLE_LAYER) self._hidden = False self.move_turtle_spr((self._x, self._y)) self.set_heading(self._heading, share=False) if self.label_block is not None: self.label_block.spr.set_layer(TURTLE_LAYER + 1) def move_turtle(self, pos=None): ''' Move the turtle's position ''' if pos is None: pos = self.get_xy() self._x, self._y = pos[0], pos[1] if self.spr is not None: self.move_turtle_spr(pos) def move_turtle_spr(self, pos): ''' Move the turtle's sprite ''' pos = self._turtles.turtle_to_screen_coordinates(pos) pos[0] -= self._half_width pos[1] -= self._half_height if not self._hidden and self.spr is not None: self.spr.move(pos) if self.label_block is not None: self.label_block.spr.move((pos[0] + self.label_xy[0], pos[1] + self.label_xy[1])) def right(self, degrees, share=True): ''' Rotate turtle clockwise ''' try: self._heading += degrees except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._heading %= 360 self._update_sprite_heading() if self._turtles.turtle_window.sharing() and share: event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick, round_int(self._heading)])) self._turtles.turtle_window.send_event(event) def _draw_line(self, old, new, pendown): if self._pen_state and pendown: self._turtles.turtle_window.canvas.set_source_rgb() pos1 = self._turtles.turtle_to_screen_coordinates(old) pos2 = self._turtles.turtle_to_screen_coordinates(new) self._turtles.turtle_window.canvas.draw_line(pos1[0], pos1[1], pos2[0], pos2[1]) if self._pen_fill: if self._poly_points == []: self._poly_points.append(('move', pos1[0], pos1[1])) self._poly_points.append(('line', pos2[0], pos2[1])) def forward(self, distance, share=True): scaled_distance = distance * self._turtles.turtle_window.coord_scale old = self.get_xy() try: xcor = old[0] + scaled_distance * sin(self._heading * DEGTOR) ycor = old[1] + scaled_distance * cos(self._heading * DEGTOR) except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._draw_line(old, (xcor, ycor), True) self.move_turtle((xcor, ycor)) if self._turtles.turtle_window.sharing() and share: event = 'f|%s' % (data_to_string([self._turtles.turtle_window.nick, int(distance)])) self._turtles.turtle_window.send_event(event) def set_xy(self, x, y, share=True, pendown=True, dragging=False): old = self.get_xy() try: if dragging: xcor = x ycor = y else: xcor = x * self._turtles.turtle_window.coord_scale ycor = y * self._turtles.turtle_window.coord_scale except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self._draw_line(old, (xcor, ycor), pendown) self.move_turtle((xcor, ycor)) if self._turtles.turtle_window.sharing() and share: event = 'x|%s' % (data_to_string([self._turtles.turtle_window.nick, [round_int(xcor), round_int(ycor)]])) self._turtles.turtle_window.send_event(event) def arc(self, a, r, share=True): ''' Draw an arc ''' if self._pen_state: self._turtles.turtle_window.canvas.set_source_rgb() try: if a < 0: pos = self.larc(-a, r) else: pos = self.rarc(a, r) except (TypeError, ValueError): debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return self.move_turtle(pos) if self._turtles.turtle_window.sharing() and share: event = 'a|%s' % (data_to_string([self._turtles.turtle_window.nick, [round_int(a), round_int(r)]])) self._turtles.turtle_window.send_event(event) def rarc(self, a, r): ''' draw a clockwise arc ''' r *= self._turtles.turtle_window.coord_scale if r < 0: r = -r a = -a pos = self.get_xy() cx = pos[0] + r * cos(self._heading * DEGTOR) cy = pos[1] - r * sin(self._heading * DEGTOR) if self._pen_state: npos = self._turtles.turtle_to_screen_coordinates((cx, cy)) self._turtles.turtle_window.canvas.rarc(npos[0], npos[1], r, a, self._heading) if self._pen_fill: if self._poly_points == []: self._poly_points.append(('move', npos[0], npos[1])) self._poly_points.append(('rarc', npos[0], npos[1], r, (self._heading - 180) * DEGTOR, (self._heading - 180 + a) * DEGTOR)) self.right(a, False) return [cx - r * cos(self._heading * DEGTOR), cy + r * sin(self._heading * DEGTOR)] def larc(self, a, r): ''' draw a counter-clockwise arc ''' r *= self._turtles.turtle_window.coord_scale if r < 0: r = -r a = -a pos = self.get_xy() cx = pos[0] - r * cos(self._heading * DEGTOR) cy = pos[1] + r * sin(self._heading * DEGTOR) if self._pen_state: npos = self._turtles.turtle_to_screen_coordinates((cx, cy)) self._turtles.turtle_window.canvas.larc(npos[0], npos[1], r, a, self._heading) if self._pen_fill: if self._poly_points == []: self._poly_points.append(('move', npos[0], npos[1])) self._poly_points.append(('larc', npos[0], npos[1], r, (self._heading) * DEGTOR, (self._heading - a) * DEGTOR)) self.right(-a, False) return [cx + r * cos(self._heading * DEGTOR), cy - r * sin(self._heading * DEGTOR)] def draw_pixbuf(self, pixbuf, a, b, x, y, w, h, path, share=True): ''' Draw a pixbuf ''' self._turtles.turtle_window.canvas.draw_pixbuf( pixbuf, a, b, x, y, w, h, self._heading) if self._turtles.turtle_window.sharing() and share: if self._turtles.turtle_window.running_sugar: tmp_path = get_path(self._turtles.turtle_window.activity, 'instance') else: tmp_path = '/tmp' tmp_file = os.path.join( get_path(self._turtles.turtle_window.activity, 'instance'), 'tmpfile.png') pixbuf.save(tmp_file, 'png', {'quality': '100'}) data = image_to_base64(tmp_file, tmp_path) height = pixbuf.get_height() width = pixbuf.get_width() pos = self._turtles.screen_to_turtle_coordinates((x, y)) event = 'P|%s' % (data_to_string([self._turtles.turtle_window.nick, [round_int(a), round_int(b), round_int(pos[0]), round_int(pos[1]), round_int(w), round_int(h), round_int(width), round_int(height), data]])) gobject.idle_add(self._turtles.turtle_window.send_event, event) os.remove(tmp_file) def draw_text(self, label, x, y, size, w, share=True): ''' Draw text ''' self._turtles.turtle_window.canvas.draw_text( label, x, y, size, w, self._heading, self._turtles.turtle_window.coord_scale) if self._turtles.turtle_window.sharing() and share: event = 'W|%s' % (data_to_string([self._turtles.turtle_window.nick, [label, round_int(x), round_int(y), round_int(size), round_int(w)]])) self._turtles.turtle_window.send_event(event) def get_name(self): return self._name def get_xy(self): return [self._x, self._y] def get_x(self): return self._x def get_y(self): return self._y def get_heading(self): return self._heading def get_color(self): return self._pen_color def get_gray(self): return self._pen_gray def get_shade(self): return self._pen_shade def get_pen_size(self): return self._pen_size def get_pen_state(self): return self._pen_state def get_fill(self): return self._pen_fill def get_poly_points(self): return self._poly_points def get_pixel(self): pos = self._turtles.turtle_to_screen_coordinates(self.get_xy()) return self._turtles.turtle_window.canvas.get_pixel(pos[0], pos[1]) def get_drag_radius(self): if self._drag_radius is None: self._calculate_sizes() return self._drag_radius
class Game(): def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']): self._activity = parent self._colors = [colors[0]] self._colors.append(colors[1]) self._colors.append('#FFFFFF') self._colors.append('#000000') self._colors.append('#FF0000') self._colors.append('#FF8000') self._colors.append('#FFFF00') self._colors.append('#00FF00') self._colors.append('#00FFFF') self._colors.append('#0000FF') self._colors.append('#FF00FF') self._canvas = canvas if parent is not None: parent.show_all() self._parent = parent self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) self._canvas.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK) self._canvas.add_events(Gdk.EventMask.POINTER_MOTION_MASK) self._canvas.connect("draw", self.__draw_cb) self._canvas.connect("button-press-event", self._button_press_cb) self._canvas.connect("button-release-event", self._button_release_cb) self._canvas.connect("motion-notify-event", self._mouse_move_cb) self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - GRID_CELL_SIZE scale = [self._width / (10 * DOT_SIZE * 1.2), self._height / (6 * DOT_SIZE * 1.2)] self._scale = min(scale) self._dot_size = int(DOT_SIZE * self._scale) self._space = int(self._dot_size / 5.) self._orientation = 'horizontal' self.we_are_sharing = False self.playing_with_robot = False self._press = False self.last_spr = None self._timer = None self.roygbiv = False # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) self._dots = [] for y in range(SIX): for x in range(TEN): xoffset = int((self._width - TEN * self._dot_size - \ (TEN - 1) * self._space) / 2.) self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), y * (self._dot_size + self._space), self._new_dot(self._colors[2]))) self._dots[-1].type = 2 # not set self._dots[-1].set_label_attributes(40) self.vline = Sprite(self._sprites, int(self._width / 2.) - 1, 0, self._line(vertical=True)) n = SIX / 2. self.hline = Sprite( self._sprites, 0, int(self._dot_size * n + self._space * (n - 0.5)) - 1, self._line(vertical=False)) self.hline.hide() # and initialize a few variables we'll need. self._all_clear() def _all_clear(self): ''' Things to reinitialize when starting up a new game. ''' for dot in self._dots: dot.type = 2 dot.set_shape(self._new_dot(self._colors[2])) dot.set_label('') self._set_orientation() def _set_orientation(self): ''' Set bar and message for current orientation ''' if self._orientation == 'horizontal': self.hline.hide() self.vline.set_layer(1000) elif self._orientation == 'vertical': self.hline.set_layer(1000) self.vline.hide() else: self.hline.set_layer(1000) self.vline.set_layer(1000) ''' if self._orientation == 'horizontal': self._set_label( _('Click on the dots to make a horizontal reflection.')) elif self._orientation == 'vertical': self._set_label( _('Click on the dots to make a vertical reflection.')) else: self._set_label( _('Click on the dots to make a bilateral reflection.')) ''' def _initiating(self): return self._activity.initiating def new_game(self, orientation='horizontal'): ''' Start a new game. ''' self._orientation = orientation self._all_clear() # Fill in a few dots to start for i in range(int(TEN * SIX / 2)): n = int(uniform(0, TEN * SIX)) if self.roygbiv: self._dots[n].type = int(uniform(2, len(self._colors))) else: self._dots[n].type = int(uniform(0, 4)) self._dots[n].set_shape(self._new_dot( self._colors[self._dots[n].type])) if self.we_are_sharing: _logger.debug('sending a new game') self._parent.send_new_game() def restore_game(self, dot_list, orientation): ''' Restore a game from the Journal or share ''' for i, dot in enumerate(dot_list): self._dots[i].type = dot self._dots[i].set_shape(self._new_dot( self._colors[self._dots[i].type])) self._orientation = orientation self._set_orientation() def save_game(self): ''' Return dot list and orientation for saving to Journal or sharing ''' dot_list = [] for dot in self._dots: dot_list.append(dot.type) return [dot_list, self._orientation] def _set_label(self, string): ''' Set the label in the toolbar or the window frame. ''' self._activity.status.set_label(string) def _button_press_cb(self, win, event): win.grab_focus() x, y = map(int, event.get_coords()) self._press = True spr = self._sprites.find_sprite((x, y)) if spr == None: return True self.last_spr = spr if spr.type is not None: if not self._timer is None: GObject.source_remove(self._timer) self._increment_dot(spr) return True def _button_release_cb(self, win, event): self._press = False if not self._timer is None: GObject.source_remove(self._timer) def _increment_dot(self, spr): spr.type += 1 if self.roygbiv: if spr.type >= len(self._colors): spr.type = 2 else: spr.type %= 4 spr.set_shape(self._new_dot(self._colors[spr.type])) if self.playing_with_robot: self._robot_play(spr) self._test_game_over() if self.we_are_sharing: _logger.debug('sending a click to the share') self._parent.send_dot_click(self._dots.index(spr), spr.type) self._timer = GObject.timeout_add(1000, self._increment_dot, spr) def _mouse_move_cb(self, win, event): """ Drag a tile with the mouse. """ if not self._press: return x, y = map(int, event.get_coords()) spr = self._sprites.find_sprite((x, y)) if spr == self.last_spr: return True if spr is None: return True if spr.type is not None: self.last_spr = spr if not self._timer is None: GObject.source_remove(self._timer) self._increment_dot(spr) def _robot_play(self, dot): ''' Robot reflects dot clicked. ''' x, y = self._dot_to_grid(self._dots.index(dot)) if self._orientation == 'horizontal': x = TEN - x - 1 i = self._grid_to_dot((x, y)) self._dots[i].type = dot.type self._dots[i].set_shape(self._new_dot(self._colors[dot.type])) if self.we_are_sharing: _logger.debug('sending a robot click to the share') self._parent.send_dot_click(i, dot.type) elif self._orientation == 'vertical': y = SIX - y - 1 i = self._grid_to_dot((x, y)) self._dots[i].type = dot.type self._dots[i].set_shape(self._new_dot(self._colors[dot.type])) if self.we_are_sharing: _logger.debug('sending a robot click to the share') self._parent.send_dot_click(i, dot.type) else: x = TEN - x - 1 i = self._grid_to_dot((x, y)) self._dots[i].type = dot.type self._dots[i].set_shape(self._new_dot(self._colors[dot.type])) if self.we_are_sharing: _logger.debug('sending a robot click to the share') self._parent.send_dot_click(i, dot.type) y = SIX - y - 1 i = self._grid_to_dot((x, y)) self._dots[i].type = dot.type self._dots[i].set_shape(self._new_dot(self._colors[dot.type])) if self.we_are_sharing: _logger.debug('sending a robot click to the share') self._parent.send_dot_click(i, dot.type) x = TEN - x - 1 i = self._grid_to_dot((x, y)) self._dots[i].type = dot.type self._dots[i].set_shape(self._new_dot(self._colors[dot.type])) if self.we_are_sharing: _logger.debug('sending a robot click to the share') self._parent.send_dot_click(i, dot.type) def remote_button_press(self, dot, color): ''' Receive a button press from a sharer ''' self._dots[dot].type = color self._dots[dot].set_shape(self._new_dot(self._colors[color])) def set_sharing(self, share=True): _logger.debug('enabling sharing') self.we_are_sharing = share def _smile(self): for dot in self._dots: dot.set_label(':)') def _test_game_over(self): ''' Check to see if game is over ''' if self._orientation == 'horizontal': for y in range(SIX): for x in range(SIX): if self._dots[y * TEN + x].type != \ self._dots[y * TEN + TEN - x - 1].type: self._set_label(_('keep trying')) return False self._set_label(_('good work')) self._smile() return True if self._orientation == 'vertical': for y in range(int(SIX / 2)): for x in range(TEN): if self._dots[y * TEN + x].type != \ self._dots[(SIX - y - 1) * TEN + x].type: self._set_label(_('keep trying')) return False self._set_label(_('good work')) else: for y in range(SIX): for x in range(SIX): if self._dots[y * TEN + x].type != \ self._dots[y * TEN + TEN - x - 1].type: self._set_label(_('keep trying')) return False for y in range(int(SIX / 2)): for x in range(TEN): if self._dots[y * TEN + x].type != \ self._dots[(SIX - y - 1) * TEN + x].type: self._set_label(_('keep trying')) return False self._set_label(_('good work')) self._smile() return True def __draw_cb(self,canvas,cr): self._sprites.redraw_sprites(cr=cr) def _grid_to_dot(self, pos): ''' calculate the dot index from a column and row in the grid ''' return pos[0] + pos[1] * TEN def _dot_to_grid(self, dot): ''' calculate the grid column and row for a dot ''' return [dot % TEN, int(dot / TEN)] def _expose_cb(self, win, event): self.do_expose_event(event) def do_expose_event(self, event): ''' Handle the expose-event by drawing ''' # Restrict Cairo to the exposed area cr = self._canvas.window.cairo_create() cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) cr.clip() # Refresh sprite list self._sprites.redraw_sprites(cr=cr) def _destroy_cb(self, win, event): Gtk.main_quit() def _new_dot(self, color): ''' generate a dot of a color color ''' self._dot_cache = {} if not color in self._dot_cache: self._stroke = color self._fill = color self._svg_width = self._dot_size self._svg_height = self._dot_size pixbuf = svg_str_to_pixbuf( self._header() + \ self._circle(self._dot_size / 2., self._dot_size / 2., self._dot_size / 2.) + \ self._footer()) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self._svg_width, self._svg_height) context = cairo.Context(surface) Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0) context.rectangle(0, 0, self._svg_width, self._svg_height) context.fill() self._dot_cache[color] = surface return self._dot_cache[color] def _line(self, vertical=True): ''' Generate a center line ''' if vertical: self._svg_width = 3 self._svg_height = self._height return svg_str_to_pixbuf( self._header() + \ self._rect(3, self._height, 0, 0) + \ self._footer()) else: self._svg_width = self._width self._svg_height = 3 return svg_str_to_pixbuf( self._header() + \ self._rect(self._width, 3, 0, 0) + \ self._footer()) def _header(self): return '<svg\n' + 'xmlns:svg="http://www.w3.org/2000/svg"\n' + \ 'xmlns="http://www.w3.org/2000/svg"\n' + \ 'xmlns:xlink="http://www.w3.org/1999/xlink"\n' + \ 'version="1.1"\n' + 'width="' + str(self._svg_width) + '"\n' + \ 'height="' + str(self._svg_height) + '">\n' def _rect(self, w, h, x, y): svg_string = ' <rect\n' svg_string += ' width="%f"\n' % (w) svg_string += ' height="%f"\n' % (h) svg_string += ' rx="%f"\n' % (0) svg_string += ' ry="%f"\n' % (0) svg_string += ' x="%f"\n' % (x) svg_string += ' y="%f"\n' % (y) svg_string += 'style="fill:#000000;stroke:#000000;"/>\n' return svg_string def _circle(self, r, cx, cy): return '<circle style="fill:' + str(self._fill) + ';stroke:' + \ str(self._stroke) + ';" r="' + str(r - 0.5) + '" cx="' + \ str(cx) + '" cy="' + str(cy) + '" />\n' def _footer(self): return '</svg>\n'
def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']): self._activity = parent self._colors = [colors[0]] self._colors.append(colors[1]) self._colors.append('#FFFFFF') self._colors.append('#000000') self._colors.append('#FF0000') self._colors.append('#FF8000') self._colors.append('#FFFF00') self._colors.append('#00FF00') self._colors.append('#00FFFF') self._colors.append('#0000FF') self._colors.append('#FF00FF') self._canvas = canvas if parent is not None: parent.show_all() self._parent = parent self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) self._canvas.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK) self._canvas.add_events(Gdk.EventMask.POINTER_MOTION_MASK) self._canvas.connect("draw", self.__draw_cb) self._canvas.connect("button-press-event", self._button_press_cb) self._canvas.connect("button-release-event", self._button_release_cb) self._canvas.connect("motion-notify-event", self._mouse_move_cb) self._width = Gdk.Screen.width() self._height = Gdk.Screen.height() - GRID_CELL_SIZE scale = [self._width / (10 * DOT_SIZE * 1.2), self._height / (6 * DOT_SIZE * 1.2)] self._scale = min(scale) self._dot_size = int(DOT_SIZE * self._scale) self._space = int(self._dot_size / 5.) self._orientation = 'horizontal' self.we_are_sharing = False self.playing_with_robot = False self._press = False self.last_spr = None self._timer = None self.roygbiv = False # Generate the sprites we'll need... self._sprites = Sprites(self._canvas) self._dots = [] for y in range(SIX): for x in range(TEN): xoffset = int((self._width - TEN * self._dot_size - \ (TEN - 1) * self._space) / 2.) self._dots.append( Sprite(self._sprites, xoffset + x * (self._dot_size + self._space), y * (self._dot_size + self._space), self._new_dot(self._colors[2]))) self._dots[-1].type = 2 # not set self._dots[-1].set_label_attributes(40) self.vline = Sprite(self._sprites, int(self._width / 2.) - 1, 0, self._line(vertical=True)) n = SIX / 2. self.hline = Sprite( self._sprites, 0, int(self._dot_size * n + self._space * (n - 0.5)) - 1, self._line(vertical=False)) self.hline.hide() # and initialize a few variables we'll need. self._all_clear()