diff options
author | Gonzalo Odiard <godiard@gmail.com> | 2014-06-02 21:14:34 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2014-06-16 15:26:37 (GMT) |
commit | cdca918f56e4d8a10fa7337af0bf5ceb1a3e3b67 (patch) | |
tree | f3b378848e9c99ba0019329e72c99da359b0a18d | |
parent | 88ab6a44bd0afde51b5d3e6d87ffc39a4dfc53ab (diff) |
Initial draw of maze using cairo
-rwxr-xr-x | activity.py | 46 | ||||
-rw-r--r-- | game.py | 308 | ||||
-rw-r--r-- | maze.py | 30 | ||||
-rw-r--r-- | player.py | 48 | ||||
-rwxr-xr-x | setup.py | 2 |
5 files changed, 232 insertions, 202 deletions
diff --git a/activity.py b/activity.py index 3ada097..984c437 100755 --- a/activity.py +++ b/activity.py @@ -1,17 +1,29 @@ # -*- coding: utf-8 -*- -import logging -import olpcgames -import gtk - -from sugar.activity.widgets import ActivityToolbarButton -from sugar.activity.widgets import StopButton -from sugar.graphics.toolbarbox import ToolbarBox -from sugar.graphics.toolbutton import ToolButton +from gi.repository import Gtk + +from sugar3.activity import activity +from sugar3.activity.widgets import ActivityToolbarButton +from sugar3.activity.widgets import StopButton +from sugar3.graphics.toolbarbox import ToolbarBox +from sugar3.graphics.toolbutton import ToolButton from gettext import gettext as _ +import game + + +class MazeActivity(activity.Activity): + + def __init__(self, handle): + """Set up the HelloWorld activity.""" + activity.Activity.__init__(self, handle) + self.build_toolbar() + + self.game = game.MazeGame() + self.set_canvas(self.game) + self.game.show() -class MazeActivity(olpcgames.PyGameActivity): + """ game_name = 'game' game_title = _('Maze') game_size = None # Let olpcgames pick a nice size for us @@ -51,6 +63,7 @@ class MazeActivity(olpcgames.PyGameActivity): # if set at this point, it means we've already joined (i.e., # launched from Neighborhood) joined_cb() + """ def build_toolbar(self): """Build our Activity toolbar for the Sugar system.""" @@ -60,7 +73,7 @@ class MazeActivity(olpcgames.PyGameActivity): toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) separator.show() @@ -74,7 +87,7 @@ class MazeActivity(olpcgames.PyGameActivity): harder_button.connect('clicked', self._harder_button_cb) toolbar_box.toolbar.insert(harder_button, -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_size_request(0, -1) separator.set_expand(True) @@ -88,17 +101,10 @@ class MazeActivity(olpcgames.PyGameActivity): self.set_toolbar_box(toolbar_box) toolbar_box.show_all() - self.connect("destroy", self.__stop_pygame) - return toolbar_box - def __stop_pygame(self, widget): - pygame.quit() - def _easier_button_cb(self, button): - pygame.event.post(olpcgames.eventwrap.Event( - pygame.USEREVENT, action='easier_button')) + self.game.easier() def _harder_button_cb(self, button): - pygame.event.post(olpcgames.eventwrap.Event( - pygame.USEREVENT, action='harder_button')) + self.game.harder() @@ -26,43 +26,34 @@ import sys import time import json -import gtk +from math import pi +from gi.repository import Gdk +from gi.repository import Gtk import logging -from sugar.presence import presenceservice -from sugar.graphics.style import GRID_CELL_SIZE +from sugar3.presence import presenceservice +from sugar3.graphics.style import GRID_CELL_SIZE presenceService = presenceservice.get_instance() -from maze import Maze +from maze import Maze, Rectangle from player import Player -class MazeGame: +class MazeGame(Gtk.DrawingArea): """Maze game controller. This class handles all of the game logic, event loop, mulitplayer, etc.""" # Munsell color values http://wiki.laptop.org/go/Munsell - N10 = (255, 255, 255) - N9p5 = (243, 243, 243) - N9 = (232, 232, 232) - N8 = (203, 203, 203) - N7 = (179, 179, 179) - N6 = (150, 150, 150) - N5 = (124, 124, 124) - N4 = (97, 97, 97) - N3 = (70, 70, 70) - N2 = (48, 48, 48) - N1 = (28, 28, 28) - N0 = (0, 0, 0) - EMPTY_COLOR = N8 - SOLID_COLOR = N1 - TRAIL_COLOR = N10 + EMPTY_COLOR = (203.0 / 255.0, 203.0 / 255.0, 203.0 / 255.0) + SOLID_COLOR = (28.0 / 255.0, 28.0 / 255.0, 28.0 / 255.0) + TRAIL_COLOR = (1.0, 1.0, 1.0) GOAL_COLOR = (0x00, 0xff, 0x00) WIN_COLOR = (0xff, 0xff, 0x00) - def __init__(self, screen): + def __init__(self): + super(MazeGame, self).__init__() # note what time it was when we first launched self.game_start_time = time.time() @@ -81,9 +72,8 @@ class MazeGame: # keep a list of all players, local and remote, self.allplayers = [] + self.localplayers - self.screen = screen - canvas_size = screen.get_size() - self.aspectRatio = canvas_size[0] / float(canvas_size[1]) + screen = Gdk.Screen.get_default() + self.aspectRatio = float(screen.width()) / screen.height() # start with a small maze using a seed that will be different # each time you play @@ -91,16 +81,18 @@ class MazeGame: 'width': int(9 * self.aspectRatio), 'height': 9} - log.debug('Starting the game with: %s', data) + logging.debug('Starting the game with: %s', data) self.maze = Maze(**data) self.reset() self.frame = 0 - self.font = pygame.font.Font(None, 30) + # self.font = pygame.font.Font(None, 30) # support arrow keys, game pad arrows and game pad buttons # each set maps to a local player index and a direction + # TODO + """ self.arrowkeys = { # real key: (localplayer index, ideal key) pygame.K_UP: (0, pygame.K_UP), @@ -116,18 +108,17 @@ class MazeGame: pygame.K_KP7: (2, pygame.K_LEFT), pygame.K_KP1: (2, pygame.K_RIGHT) } - - gtk.gdk.screen_get_default().connect('size-changed', - self.__configure_cb) + """ + Gdk.Screen.get_default().connect('size-changed', + self.__configure_cb) + self.connect('draw', self.__draw_cb) def __configure_cb(self, event): ''' Screen size has changed ''' - width = gtk.gdk.screen_width() - height = gtk.gdk.screen_height() - GRID_CELL_SIZE - self.aspectRatio = width / float(height) - pygame.display.set_mode((width, height), pygame.RESIZABLE) + width = Gdk.Screen.get_default().width() + height = Gdk.Screen.get_default().height() - GRID_CELL_SIZE + self.aspectRatio = width / height - seed = self.maze.seed if width < height: if self.maze.width < self.maze.height: self.maze = Maze(self.maze.seed, self.maze.width, @@ -155,16 +146,116 @@ class MazeGame: self.finish_time = None for player in self.allplayers: player.reset() - self.dirtyRect = None + self.dirtyRect = self.maze.bounds self.dirtyPoints = [] self.maze.map[self.maze.width - 2][self.maze.height - 2] = \ - self.maze.GOAL + self.maze.GOAL # clear and mark the whole screen as dirty - self.screen.fill((0, 0, 0)) - self.markRectDirty(pygame.Rect(0, 0, 99999, 99999)) + # TODO + # self.screen.fill((0, 0, 0)) + self.queue_draw() self.mouse_in_use = 0 + def __draw_cb(self, widget, ctx): + """Draw the current state of the game. + This makes use of the dirty rectangle to reduce CPU load.""" + # TODO + # if self.dirtyRect is None and len(self.dirtyPoints) == 0: + # return + + # compute the size of the tiles given the screen size, etc. + allocation = self.get_allocation() + + ctx.rectangle(0, 0, allocation.width, allocation.height) + ctx.set_source_rgb(*self.SOLID_COLOR) + ctx.fill() + + self.tileSize = min(allocation.width / self.maze.width, + allocation.height / self.maze.height) + self.bounds = Rectangle((allocation.width - self.tileSize * + self.maze.width) / 2, + (allocation.height - self.tileSize * + self.maze.height) / 2, + self.tileSize * self.maze.width, + self.tileSize * self.maze.height) + self.outline = int(self.tileSize / 5) + + def drawPoint(x, y): + # logging.error('drawing %s %s = %s', x, y, self.maze.map[x][y]) + rect = Rectangle(self.bounds.x + x * self.tileSize, + self.bounds.y + y * self.tileSize, + self.tileSize, self.tileSize) + tile = self.maze.map[x][y] + background_color = (0xff, 0x00, 0xff) + if tile == self.maze.EMPTY: + background_color = self.EMPTY_COLOR + elif tile == self.maze.SOLID: + background_color = self.SOLID_COLOR + elif tile == self.maze.GOAL: + background_color = self.GOAL_COLOR + ctx.save() + ctx.set_source_rgb(*background_color) + ctx.rectangle(*rect.get_bounds()) + logging.error('drawing %s %s', rect.get_bounds(), background_color) + ctx.fill() + + if tile == self.maze.SEEN: + ctx.set_source_rgb(*self.TRAIL_COLOR) + radius = self.tileSize / 2 - self.outline + ctx.arc(rect.x + radius, rect.y + radius, radius, 0, 2 * pi) + ctx.fill() + ctx.restore() + + # re-draw the dirty rectangle + if self.dirtyRect is not None: + # compute the area that needs to be redrawn + left = max(0, self.dirtyRect.x) + right = min(self.maze.width, + self.dirtyRect.x + self.dirtyRect.width) + top = max(0, self.dirtyRect.y) + bottom = min(self.maze.height, + self.dirtyRect.y + self.dirtyRect.height) + + # loop over the dirty rect and draw + for x in range(left, right): + for y in range(top, bottom): + drawPoint(x, y) + + # re-draw the dirty points + # for x, y in self.dirtyPoints: + # drawPoint(x, y) + + # draw all players + for player in self.allplayers: + if not player.hidden: + player.draw(ctx, self.bounds, self.tileSize) + + # draw the elapsed time for each player that has finished + # TODO + """ + finishedPlayers = filter(lambda p: p.elapsed is not None, + self.allplayers) + finishedPlayers.sort(lambda a, b: cmp(a.elapsed, b.elapsed)) + y = 0 + for player in finishedPlayers: + fg, bg = player.colors + text = "%3.2f - %s" % (player.elapsed, player.nick) + textimg = self.font.render(text, 1, fg) + textwidth, textheight = self.font.size(text) + rect = pygame.Rect(8, y + 4, textwidth, textheight) + bigrect = rect.inflate(16, 8) + pygame.draw.rect(self.screen, bg, bigrect, 0) + pygame.draw.rect(self.screen, fg, bigrect, 2) + self.screen.blit(textimg, rect) + + y += bigrect.height + 4 + """ + # clear the dirty rect so nothing will be drawn until there is a change + # TODO + # self.dirtyRect = None + # self.dirtyPoints = [] + def markRectDirty(self, rect): """Mark an area that needs to be redrawn. This lets us play really big mazes without needing to re-draw the whole @@ -203,7 +294,7 @@ class MazeGame: player.direction = (1, 0) if len(self.remoteplayers) > 0: - mesh.broadcast("move:%s,%d,%d,%d,%d" % \ + mesh.broadcast("move:%s,%d,%d,%d,%d" % (player.uid, player.position[0], player.position[1], @@ -224,7 +315,7 @@ class MazeGame: new_mouse_pos[1] - self.prev_mouse_pos[1]) if ((abs(mouse_movement[0]) > 10) or - (abs(mouse_movement[1]) > 10)): + (abs(mouse_movement[1]) > 10)): player = self.localplayers[0] player.hidden = False # x movement larger @@ -243,7 +334,7 @@ class MazeGame: player.direction = (0, 1) if len(self.remoteplayers) > 0: - mesh.broadcast("move:%s,%d,%d,%d,%d" % \ + mesh.broadcast("move:%s,%d,%d,%d,%d" % (player.nick, player.position[0], player.position[1], @@ -253,14 +344,14 @@ class MazeGame: self.mouse_in_use = 0 elif event.type == mesh.CONNECT: - log.debug("Connected to the mesh") + logging.debug("Connected to the mesh") elif event.type == mesh.PARTICIPANT_ADD: - log.debug('mesh.PARTICIPANT_ADD') + logging.debug('mesh.PARTICIPANT_ADD') def withBuddy(buddy): if event.handle == mesh.my_handle(): - log.debug("Me: %s - %s", buddy.props.nick, + logging.debug("Me: %s - %s", buddy.props.nick, buddy.props.color) # README: this is a workaround to use an unique # identifier instead the nick of the buddy @@ -271,7 +362,7 @@ class MazeGame: count = '-%d' % i player.uid = mesh.my_handle() + count else: - log.debug("Join: %s - %s", buddy.props.nick, + logging.debug("Join: %s - %s", buddy.props.nick, buddy.props.color) player = Player(buddy) player.uid = event.handle @@ -282,14 +373,14 @@ class MazeGame: # send a test message to the new player mesh.broadcast("Welcome %s" % player.nick) # tell them which maze we are playing, so they can sync up - mesh.send_to(event.handle, "maze:%d,%d,%d,%d" % \ + mesh.send_to(event.handle, "maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height)) for player in self.localplayers: if not player.hidden: mesh.send_to(event.handle, - "move:%s,%d,%d,%d,%d" % \ + "move:%s,%d,%d,%d,%d" % (player.uid, player.position[0], player.position[1], @@ -298,10 +389,10 @@ class MazeGame: mesh.lookup_buddy(event.handle, callback=withBuddy) elif event.type == mesh.PARTICIPANT_REMOVE: - log.debug('mesh.PARTICIPANT_REMOVE') + logging.debug('mesh.PARTICIPANT_REMOVE') if event.handle in self.remoteplayers: player = self.remoteplayers[event.handle] - log.debug("Leave: %s", player.nick) + logging.debug("Leave: %s", player.nick) self.markPointDirty(player.position) self.allplayers.remove(player) for bonusplayer in player.bonusPlayers(): @@ -309,8 +400,8 @@ class MazeGame: self.allplayers.remove(bonusplayer) del self.remoteplayers[event.handle] elif event.type == mesh.MESSAGE_UNI or \ - event.type == mesh.MESSAGE_MULTI: - log.debug('mesh.MESSAGE_UNI or mesh.MESSAGE_MULTI') + event.type == mesh.MESSAGE_MULTI: + logging.debug('mesh.MESSAGE_UNI or mesh.MESSAGE_MULTI') if event.handle == mesh.my_handle(): # ignore messages from ourself pass @@ -319,10 +410,10 @@ class MazeGame: try: self.handleMessage(player, event.content) except: - log.debug("Error handling message: %s\n%s", + logging.debug("Error handling message: %s\n%s", event, sys.exc_info()) else: - log.debug("Message from unknown buddy?") + logging.debug("Message from unknown buddy?") elif event.type == pygame.USEREVENT: # process our buttons @@ -332,29 +423,28 @@ class MazeGame: self.easier() # process file save / restore events elif event.code == olpcgames.FILE_READ_REQUEST: - log.debug('Loading the state of the game...') + logging.debug('Loading the state of the game...') state = json.loads(event.metadata['state']) - log.debug('Loaded data: %s', state) + logging.debug('Loaded data: %s', state) self.maze = Maze(**state) self.reset() return True elif event.code == olpcgames.FILE_WRITE_REQUEST: - log.debug('Saving the state of the game...') + logging.debug('Saving the state of the game...') data = {'seed': self.maze.seed, 'width': self.maze.width, - 'height': self.maze.height, - } - log.debug('Saving data: %s', data) + 'height': self.maze.height, } + logging.debug('Saving data: %s', data) event.metadata['state'] = json.dumps(data) f = open(event.filename, 'w') try: f.write(str(time.time())) finally: f.close() - log.debug('Done saving.') + logging.debug('Done saving.') return True else: - log.debug('Unknown event: %r', event) + logging.debug('Unknown event: %r', event) def handleMessage(self, player, message): """Handle a message from a player on the mesh. @@ -380,7 +470,7 @@ class MazeGame: finish: nick, elapsed A player has finished the maze """ - log.debug('mesh message: %s', message) + logging.debug('mesh message: %s', message) # ignore messages from myself if player in self.localplayers: @@ -426,7 +516,7 @@ class MazeGame: self.markPointDirty(player.position) else: # it was something I don't recognize... - log.debug("Message from %s: %s", player.nick, message) + logging.debug("Message from %s: %s", player.nick, message) def arrowKeysPressed(self): keys = pygame.key.get_pressed() @@ -474,7 +564,7 @@ class MazeGame: if len(self.remoteplayers) > 0: # but fudge it a little so that we can be sure they'll use our maze self.game_start_time -= 10 - mesh.broadcast("maze:%d,%d,%d,%d" % \ + mesh.broadcast("maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height)) @@ -491,7 +581,7 @@ class MazeGame: if len(self.remoteplayers) > 0: # but fudge it a little so that we can be sure they'll use our maze self.game_start_time -= 10 - mesh.broadcast("maze:%d,%d,%d,%d" % \ + mesh.broadcast("maze:%d,%d,%d,%d" % (self.game_running_time(), self.maze.seed, self.maze.width, self.maze.height)) @@ -506,9 +596,9 @@ class MazeGame: self.markPointDirty(newposition) if player in self.localplayers: self.maze.map[player.previous[0]][player.previous[1]] = \ - self.maze.SEEN + self.maze.SEEN if self.maze.map[newposition[0]][newposition[1]] == \ - self.maze.GOAL: + self.maze.GOAL: self.finish(player) finish_delay = min(2 * len(self.allplayers), 6) @@ -522,91 +612,11 @@ class MazeGame: if len(self.remoteplayers) > 0: mesh.broadcast("finish:%s,%.2f" % (player.nick, player.elapsed)) - def draw(self): - """Draw the current state of the game. - This makes use of the dirty rectangle to reduce CPU load.""" - if self.dirtyRect is None and len(self.dirtyPoints) == 0: - return - - # compute the size of the tiles given the screen size, etc. - size = self.screen.get_size() - self.tileSize = min(size[0] / self.maze.width, - size[1] / self.maze.height) - self.bounds = pygame.Rect((size[0] - self.tileSize * - self.maze.width) / 2, - (size[1] - self.tileSize * - self.maze.height) / 2, - self.tileSize * self.maze.width, - self.tileSize * self.maze.height) - self.outline = int(self.tileSize / 5) - - def drawPoint(x, y): - rect = pygame.Rect(self.bounds.x + x * self.tileSize, - self.bounds.y + y * self.tileSize, - self.tileSize, self.tileSize) - tile = self.maze.map[x][y] - if tile == self.maze.EMPTY: - pygame.draw.rect(self.screen, self.EMPTY_COLOR, rect, 0) - elif tile == self.maze.SOLID: - pygame.draw.rect(self.screen, self.SOLID_COLOR, rect, 0) - elif tile == self.maze.SEEN: - pygame.draw.rect(self.screen, self.EMPTY_COLOR, rect, 0) - dot = rect.inflate(-self.outline * 2, -self.outline * 2) - pygame.draw.ellipse(self.screen, self.TRAIL_COLOR, dot, 0) - elif tile == self.maze.GOAL: - pygame.draw.rect(self.screen, self.GOAL_COLOR, rect, 0) - else: - pygame.draw.rect(self.screen, (0xff, 0x00, 0xff), rect, 0) - - # re-draw the dirty rectangle - if self.dirtyRect is not None: - # compute the area that needs to be redrawn - left = max(0, self.dirtyRect.left) - right = min(self.maze.width, self.dirtyRect.right) - top = max(0, self.dirtyRect.top) - bottom = min(self.maze.height, self.dirtyRect.bottom) - - # loop over the dirty rect and draw - for x in range(left, right): - for y in range(top, bottom): - drawPoint(x, y) - - # re-draw the dirty points - for x, y in self.dirtyPoints: - drawPoint(x, y) - - # draw all players - for player in self.allplayers: - if not player.hidden: - player.draw(self.screen, self.bounds, self.tileSize) - - # draw the elapsed time for each player that has finished - finishedPlayers = filter(lambda p: p.elapsed is not None, - self.allplayers) - finishedPlayers.sort(lambda a, b: cmp(a.elapsed, b.elapsed)) - y = 0 - for player in finishedPlayers: - fg, bg = player.colors - text = "%3.2f - %s" % (player.elapsed, player.nick) - textimg = self.font.render(text, 1, fg) - textwidth, textheight = self.font.size(text) - rect = pygame.Rect(8, y + 4, textwidth, textheight) - bigrect = rect.inflate(16, 8) - pygame.draw.rect(self.screen, bg, bigrect, 0) - pygame.draw.rect(self.screen, fg, bigrect, 2) - self.screen.blit(textimg, rect) - - y += bigrect.height + 4 - - # clear the dirty rect so nothing will be drawn until there is a change - self.dirtyRect = None - self.dirtyPoints = [] - def main(): """Run a game of Maze.""" - #canvas_size = 1024,768-75 - #screen = pygame.display.set_mode(canvas_size) + # canvas_size = 1024,768-75 + # screen = pygame.display.set_mode(canvas_size) # ask pygame how big the screen is, leaving a little room for the toolbar toolbarheight = 75 @@ -23,7 +23,19 @@ # along with Maze.activity. If not, see <http://www.gnu.org/licenses/>. import random -import gtk +import logging + + +class Rectangle: + + def __init__(self, x, y, width, height): + self.x = x + self.y = y + self.width = width + self.height = height + + def get_bounds(self): + return (self.x, self.y, self.width, self.height) class Maze: @@ -36,12 +48,13 @@ class Maze: # use the seed given to us to make a pseudo-random number generator # we will use that to generate the maze, so that other players can # generate the exact same maze given the same seed. - print "Generating maze:%d,%d,%d" % (seed, width, height) + logging.debug("Generating maze: seed %d, width %d, height %d", seed, + width, height) self.seed = seed self.generator = random.Random(seed) self.width, self.height = width, height self.map = [] - self.bounds = gtk.gdk.Rectangle(0, 0, width, height) + self.bounds = Rectangle(0, 0, width, height) for x in range(0, width): self.map.append([self.SOLID] * self.height) @@ -49,12 +62,14 @@ class Maze: startx = self.generator.randrange(1, width, 2) starty = self.generator.randrange(1, height, 2) self.dig(startx, starty) + for row in self.map: + logging.error(row) def _check_point_in_rectangle(self, rectangle, x, y): if x < rectangle.x or y < rectangle.y: return False - if x > rectangle.x + rectangle.width or \ - y > rectangle.y + rectangle.height: + if x >= rectangle.x + rectangle.width or \ + y >= rectangle.y + rectangle.height: return False return True @@ -78,11 +93,6 @@ class Maze: directions.append((-1, 0)) return directions - def fill(self, color): - for y in range(0, height): - for x in range(0, width): - self.map[x][y] = color - def digRecursively(self, x, y): """This works great, except for python's lame limit on recursion depth. @@ -23,10 +23,12 @@ # along with Maze.activity. If not, see <http://www.gnu.org/licenses/>. import math -import gtk import unicodedata -from sugar.graphics import style +from sugar3.graphics import style + +from maze import Rectangle + class Player: def __init__(self, buddy, shape='circle'): @@ -47,29 +49,31 @@ class Player: self.bonusplayers = None self.reset() - def draw(self, context, bounds, size): - rect = gtk.gdk.Rectangle(bounds.x + self.position[0] * size, - bounds.y + self.position[1] * size, size, - size) - context.save() + def draw(self, ctx, bounds, size): + line_width = size / 10. + rect = Rectangle(bounds.x + self.position[0] * size, + bounds.y + self.position[1] * size, size, + size) + ctx.save() if self.shape == 'circle': - context.arc(rect.x + size / 2, rect.y + size / 2, size, 0, - 2 * math.pi) + ctx.arc(rect.x + size / 2, rect.y + size / 2, + (size / 2 - line_width), 0, 2 * math.pi) elif self.shape == 'square': - context.rectangle(rect.x, rect.y, size, size) + ctx.rectangle(rect.x + line_width, rect.y + line_width, + size - line_width * 2, size - line_width * 2) elif self.shape == 'triangle': - context.new_path() - context.move_to(rect.x, rect.y + size) - context.line_to(rect.x + size / 2, rect.y) - context.line_to(rect.x + size, rect.y + size) - context.close_path() - - context.set_source_rgba(*self.bg.get_rgba()) - context.set_line_width(size / 10.) - context.fill_preserve() - context.set_source_rgba(*self.fg.get_rgba()) - context.stroke() - context.restore() + ctx.new_path() + ctx.move_to(rect.x, rect.y + size) + ctx.line_to(rect.x + size / 2, rect.y) + ctx.line_to(rect.x + size, rect.y + size) + ctx.close_path() + + ctx.set_source_rgba(*self.bg.get_rgba()) + ctx.set_line_width(line_width) + ctx.fill_preserve() + ctx.set_source_rgba(*self.fg.get_rgba()) + ctx.stroke() + ctx.restore() def reset(self): self.direction = (0, 0) @@ -1,3 +1,3 @@ #!/usr/bin/env python -from sugar.activity import bundlebuilder +from sugar3.activity import bundlebuilder bundlebuilder.start() |