From ed12012f5fba420d7de285110dc83655ad8e594b Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Tue, 22 Dec 2009 15:07:09 +0000 Subject: major refactoring of sprites library --- diff --git a/VisualMatchActivity.py b/VisualMatchActivity.py index 0fa9113..92c562a 100644 --- a/VisualMatchActivity.py +++ b/VisualMatchActivity.py @@ -209,7 +209,6 @@ class VisualMatchActivity(activity.Activity): # Button callbacks # def _select_game_cb(self, button, activity, cardtype): - print "in _select_game_cb: %s" % (cardtype) window.new_game(activity.vmw, cardtype) def _journal_cb(self, button, path): diff --git a/card.py b/card.py index 8e7d94f..373464e 100644 --- a/card.py +++ b/card.py @@ -26,7 +26,6 @@ import gobject import os.path from constants import * - from sprites import * # @@ -41,21 +40,14 @@ from sprites import * # if shape == SELECTMASK then generate special card-selected overlay # class Card: - def __init__(self, vmw, path, cardtype, width, height, attributes): - # what do we need to know about each card? + def __init__(self, sprites, path, cardtype, width, height, attributes): if attributes[0] == SELECTMASK: - self.spr = sprNew(vmw,0,0,self.load_image( - path, - "selected", - width, - height)) + self.spr = Sprite(sprites, 0, 0, + self.load_image(path, "selected", width, height)) self.index = SELECTMASK elif attributes[0] == MATCHMASK: - self.spr = sprNew(vmw,0,0,self.load_image( - path, - "match", - width, - height)) + self.spr = Sprite(sprites, 0, 0, + self.load_image(path, "match", width, height)) self.index = MATCHMASK else: self.shape = attributes[0] @@ -66,19 +58,17 @@ class Card: self.color*NUMBER*FILLS+\ self.num*FILLS+\ self.fill - # create sprite from svg file - self.spr = sprNew(vmw,0,0,self.load_image( - path, - cardtype+"-"+str(self.index), - width, height)) - self.spr.label = "" + self.spr = Sprite(sprites, 0, 0, + self.load_image(path, cardtype+"-"+\ + str(self.index), + width, height)) def show_card(self): - setlayer(self.spr,2000) - draw(self.spr) + self.spr.setlayer(2000) + self.spr.draw() def hide_card(self): - hide(self.spr) + self.spr.hide() def load_image(self, path, file, w, h): return gtk.gdk.pixbuf_new_from_file_at_size( diff --git a/constants.py b/constants.py index c737c02..2acbdde 100644 --- a/constants.py +++ b/constants.py @@ -28,6 +28,7 @@ DEAL=12 EXTRAS=3 SELECTMASK = -1 MATCHMASK = -2 -CARD_W = 125 -CARD_H = 75 +CARD_WIDTH = 125 +CARD_HEIGHT = 75 +KEYMAP = ['1','2','3','q','w','e','a','s','d','z','x','c','8','9','0'] diff --git a/deck.py b/deck.py index 402df3a..33616ba 100644 --- a/deck.py +++ b/deck.py @@ -32,7 +32,7 @@ from card import * # class for defining deck of cards # class Deck: - def __init__(self, vmw, path, card_type, width, height): + def __init__(self, sprites, path, cardtype, width, height): # create the deck of cards self.cards = {} # remember the position in the deck @@ -44,7 +44,7 @@ class Deck: for color in range(0, COLORS): for num in range(0, NUMBER): for fill in range(0, FILLS): - self.cards[self.count] = Card(vmw, path, card_type, + self.cards[self.count] = Card(sprites, path, cardtype, width, height, [shape,color,num,fill]) self.count += 1 diff --git a/grid.py b/grid.py index bd0f665..f6eafe8 100644 --- a/grid.py +++ b/grid.py @@ -37,17 +37,17 @@ COL = 3 # class for managing 3x5 matrix of cards # class Grid: - def __init__(self, width, height, card_width, card_height, scale): + def __init__(self, width, height, card_width, card_height): # the playing surface is a 3x5 grid self.grid = [] # how many cards are on the playing field self.cards = 0 # card spacing - self.left = int((width-(card_width*2*scale))/2) - self.xinc = int(card_width*1.2*scale) - # self.top = int((height-(card_height*3.5*card_scale))/2) + self.left = int((width-(card_width*2))/2) + self.xinc = int(card_width*1.2) + # self.top = int((height-(card_height*3.5))/2) self.top = 10 - self.yinc = int(card_height*1.33*scale) + self.yinc = int(card_height*1.33) # deal the initial deck of cards def deal(self, deck): @@ -60,7 +60,7 @@ class Grid: for c in range(0, COL): a = deck.deal_next_card() self.grid.append(a) - self.place_a_card(a,x,y) + self.place_a_card(a, x, y) x += self.xinc self.cards += 1 x = self.left @@ -79,7 +79,7 @@ class Grid: self.grid[i] = deck.deal_next_card() x = self.left+self.xinc*(i%COL) y = self.top+self.yinc*int(i/COL) - self.place_a_card(self.grid[i],x,y) + self.place_a_card(self.grid[i], x, y) self.cards += 1 # remove a match from the grid and deal new cards from the deck @@ -94,7 +94,7 @@ class Grid: else: # save card in grid position of card we are replacing self.grid[i] = deck.deal_next_card() - self.place_a_card(self.grid[i],a.x,a.y) + self.place_a_card(self.grid[i], a.x, a.y) else: self.cards -= 1 # mark grid positions of cards we are not replacing @@ -105,12 +105,18 @@ class Grid: deck.spr_to_card(a).show_card() # place a card at position x,y and display it - def place_a_card(self,c,x,y): + def place_a_card(self, c, x, y): if c is not None: c.spr.x = x c.spr.y = y c.show_card() # convert from sprite x,y to grid index - def xy_to_grid(self,x,y): + def xy_to_grid(self, x, y): return int(COL*(y-self.top)/self.yinc) + int((x-self.left)/self.xinc) + + + # return sprite in grid element i + def grid_to_spr(self, i): + print self.grid[i].spr + return self.grid[i].spr diff --git a/sprites.py b/sprites.py index e1b037e..9f69f08 100644 --- a/sprites.py +++ b/sprites.py @@ -26,136 +26,112 @@ pygtk.require('2.0') import gtk import gobject import pango -class taSprite: pass - -def findsprite(tw,pos): - list = tw.sprites[:] - list.reverse() - for s in list: - if hit(s,pos): return s - return None - -def redrawsprites(tw): - for s in tw.sprites: draw(s) - -def sprNew(tw,x,y,image,altlabel=False): - spr = taSprite() - spr.tw, spr.x, spr.y = tw,x,y - setimage(spr,image) - spr.label = None - spr.ds_id = None - if altlabel: - spr.draw_label = draw_label2 - else: spr.draw_label = draw_label1 - return spr - -def setimage(spr,image): - spr.image = image - if isinstance(image,gtk.gdk.Pixbuf): - spr.width = image.get_width() - spr.height = image.get_height() - else: spr.width,spr.height=image.get_size() - -def move(spr,pos): - inval(spr) - spr.x,spr.y = pos - inval(spr) - -def setshape(spr,image): - inval(spr) - setimage(spr,image) - inval(spr) - -def setshapex(spr): - inval(spr) - -def setlayer(spr, layer): - sprites = spr.tw.sprites - if spr in sprites: sprites.remove(spr) - spr.layer = layer - for i in range(len(sprites)): - if layer < sprites[i].layer: - sprites.insert(i, spr) - inval(spr) - return - sprites.append(spr) - inval(spr) - -def hide(spr): - if spr not in spr.tw.sprites: return - inval(spr) - spr.tw.sprites.remove(spr) - -def setlabel(spr,label): - spr.label = label - inval(spr) - -def inval(spr): - spr.tw.area.invalidate_rect(gtk.gdk.Rectangle(spr.x,spr.y,spr.width, \ - spr.height), False) - -def draw(spr): - if isinstance(spr.image,gtk.gdk.Pixbuf): - spr.tw.area.draw_pixbuf(spr.tw.gc, spr.image, 0, 0, spr.x, spr.y) - else: - spr.tw.area.draw_drawable(spr.tw.gc,spr.image,0,0,spr.x,spr.y,-1,-1) - if spr.label!=None: - if hasattr(spr, 'proto') and hasattr(spr.proto, 'name'): - name = spr.proto.name + +class Sprites: + def __init__(self, area, gc): + self.area = area + self.gc = gc + self.list = [] + + def get_sprite(self, i): + if i < 0 or i > len(self.list)-1: + return(None) else: - name = "" - spr.draw_label(spr,str(spr.label)) - -def hit(spr,pos): - x,y = pos - if xspr.x+spr.width: return False - if yspr.y+spr.height: return False - if isinstance(spr.image,gtk.gdk.Pixmap): return True - if hasattr(spr, 'proto') and hasattr(spr.proto, 'name') and \ - spr.proto.name == 'journal': - return True - dx,dy = x-spr.x, y-spr.y - try: - return ord(spr.image.get_pixels()[(dy*spr.width+dx)*4+3]) == 255 - except IndexError: - if hasattr(spr, 'proto') and hasattr(spr.proto, 'name'): - print spr.proto.name - print "IndexError: string index out of range" + str(dx) + " " \ - + str(dy) + " " + str(spr.width) + " " + str(spr.height) - return True + return(self.list[i]) + + def length_of_list(self): + return(len(self.list)) -def draw_label(spr, label, myscale, center_flag, truncate_flag): - fd = pango.FontDescription('Sans') - fd.set_size(int(myscale*spr.tw.scale*pango.SCALE)) - if type(label) == str or type(label) == unicode: - mylabel = label.replace("\0"," ") - l = len(mylabel) - if truncate_flag and l > 8: - pl = spr.tw.canvas.create_pango_layout("..."+mylabel[l-8:]) + def append_to_list(self,spr): + self.list.append(spr) + + def insert_in_list(self,spr,i): + if i < 0: + self.list.insert(0, spr) + elif i > len(self.list)-1: + self.list.append(spr) + else: + self.list.insert(i, spr) + + def remove_from_list(self,spr): + if spr in self.list: + self.list.remove(spr) + + def findsprite(self, pos): + list = self.list + list.reverse() + for spr in list: + if spr.hit(pos): return spr + return None + + def redrawsprites(self): + for spr in self.list: + spr.draw() + + +class Sprite: + def __init__(self, sprites, x, y, image): + self.x = x + self.y = y + self.layer = 100 + self.setimage(image) + self.sprites = sprites + self.sprites.append_to_list(self) + + def setimage(self, image): + self.image = image + if isinstance(self.image,gtk.gdk.Pixbuf): + self.width = self.image.get_width() + self.height = self.image.get_height() else: - pl = spr.tw.canvas.create_pango_layout(mylabel) - pl.set_font_description(fd) - if center_flag: - swidth = pl.get_size()[0]/pango.SCALE - centerx = spr.x+spr.width/2 - x = int(centerx-swidth/2) + self.width, self.height = self.image.get_size() + + def move(self, pos): + self.inval() + self.x,self.y = pos + self.inval() + + def setshape(self, image): + self.inval() + self.setimage(image) + self.inval() + + def setlayer(self, layer): + self.sprites.remove_from_list(self) + self.layer = layer + for i in range(self.sprites.length_of_list()): + if layer < self.sprites.get_sprite(i).layer: + self.sprites.insert_in_list(i, self) + self.inval() + return + self.sprites.append_to_list(self) + self.inval() + + def hide(self): + self.inval() + self.sprites.remove_from_list(self) + + def inval(self): + self.sprites.area.invalidate_rect( + gtk.gdk.Rectangle(self.x,self.y,self.width,self.height), False) + + def draw(self): + if isinstance(self.image,gtk.gdk.Pixbuf): + self.sprites.area.draw_pixbuf( + self.sprites.gc, self.image, 0, 0, self.x, self.y) else: - x = spr.x+70 - sheight = pl.get_size()[1]/pango.SCALE - centery = spr.y+spr.height/2 - y = int(centery-sheight/2) - spr.tw.gc.set_foreground(spr.tw.msgcolor) - spr.tw.area.draw_layout(spr.tw.gc, x, y, pl) - else: - print type(label) - -# used for most things -def draw_label1(spr, label): - draw_label(spr, label, 12, True, True) - -# used for status blocks -def draw_label2(spr, label): - draw_label(spr, str(label), 14, False, False) + self.sprites.area.draw_drawable( + self.sprites.gc, self.image, 0, 0, self.x, self.y, -1, -1) + + def hit(self, pos): + x, y = pos + if x < self.x: + return False + if x > self.x+self.width: + return False + if y < self.y: + return False + if y > self.y+self.height: + return False + return True diff --git a/window.py b/window.py index 40335dc..8c68267 100644 --- a/window.py +++ b/window.py @@ -36,8 +36,7 @@ from constants import * from grid import * from deck import * from card import * - -from math import sqrt +from sprites import * class vmWindow: pass @@ -70,32 +69,26 @@ def new_window(canvas, path, cardtype, parent=None): vmw.canvas.connect("key_press_event", _keypress_cb, vmw) vmw.width = gtk.gdk.screen_width() vmw.height = gtk.gdk.screen_height()-GRID_CELL_SIZE - vmw.card_width = CARD_W - vmw.card_height = CARD_H vmw.cardtype = cardtype - vmw.scale = 0.8 * vmw.height/(vmw.card_height*5.5) - vmw.area = vmw.canvas.window - vmw.gc = vmw.area.new_gc() - vmw.cm = vmw.gc.get_colormap() - vmw.msgcolor = vmw.cm.alloc_color('black') - vmw.sprites = [] + scale = 0.8 * vmw.height/(CARD_HEIGHT*5.5) + vmw.card_width = CARD_WIDTH*scale + vmw.card_height = CARD_HEIGHT*scale + vmw.sprites = Sprites(vmw.canvas.window, vmw.canvas.window.new_gc()) vmw.selected = [] vmw.match_display_area = [] # create a deck of cards and a grid for the playing field - vmw.deck = Deck(vmw, vmw.path, vmw.cardtype, vmw.card_width*vmw.scale, - vmw.card_height*vmw.scale) - vmw.grid = Grid(vmw.width,vmw.height,vmw.card_width,vmw.card_height, - vmw.scale) + vmw.deck = Deck(vmw.sprites, vmw.path, vmw.cardtype, vmw.card_width, + vmw.card_height) + vmw.grid = Grid(vmw.width, vmw.height, vmw.card_width, vmw.card_height) - # initialize three card-selected overlays and - # a place to put the matched cards + # initialize three card-selected overlays and a place for the matches for i in range(0,3): - vmw.selected.append(Card(vmw,vmw.path,"",vmw.card_width*vmw.scale, - vmw.card_height*vmw.scale,[SELECTMASK,0,0,0])) - vmw.match_display_area.append(Card(vmw,vmw.path,"", - vmw.card_width*vmw.scale, - vmw.card_height*vmw.scale,[MATCHMASK,0,0,0])) + vmw.selected.append(Card(vmw.sprites, vmw.path, "", vmw.card_width, + vmw.card_height, [SELECTMASK,0,0,0])) + vmw.match_display_area.append(Card(vmw.sprites, vmw.path, "", + vmw.card_width, + vmw.card_height, [MATCHMASK,0,0,0])) vmw.match_display_area[i].spr.x = 10 vmw.match_display_area[i].spr.y = vmw.grid.top+i*vmw.grid.yinc vmw.match_display_area[i].show_card() @@ -105,7 +98,6 @@ def new_window(canvas, path, cardtype, parent=None): # Start doing something vmw.low_score = -1 - vmw.keypress = "" new_game(vmw, cardtype) return vmw @@ -116,12 +108,13 @@ def new_game(vmw,cardtype): vmw.deck.hide() if vmw.cardtype is not cardtype: vmw.cardtype = cardtype - vmw.deck = Deck(vmw, vmw.path, vmw.cardtype, vmw.card_width*vmw.scale, - vmw.card_height*vmw.scale) + vmw.deck = Deck(vmw.sprites, vmw.path, vmw.cardtype, + vmw.card_width, vmw.card_height) vmw.deck.shuffle() vmw.grid.deal(vmw.deck) if find_a_match(vmw) is False: vmw.grid.deal_extra_cards(vmw.deck) + unselect(vmw) vmw.matches = 0 vmw.total_time = 0 set_label(vmw, "deck", "%d %s" % @@ -144,10 +137,12 @@ def _button_press_cb(win, event, vmw): def _button_release_cb(win, event, vmw): win.grab_focus() x, y = map(int, event.get_coords()) - spr = findsprite(vmw,(x,y)) + spr = vmw.sprites.findsprite((x, y)) if spr is None: return True + return _process_selection(vmw, spr) +def _process_selection(vmw, spr): # check to make sure a card in the matched pile isn't selected if spr.x == 10: return True @@ -210,7 +205,7 @@ def _button_release_cb(win, event, vmw): return True # test to see if we need to deal extra cards if find_a_match(vmw) is False: - vmw.grid.deal_extra_cards(vmw.deck) + vmw.grid.deal_extra_cards(vmw.deck) else: # set_label(vmw,"status",vmw.msg) set_label(vmw,"status",_("match")) @@ -240,14 +235,16 @@ def unselect(vmw): # Keypress # def _keypress_cb(area, event, vmw): - vmw.keypress = gtk.gdk.keyval_name(event.keyval) + k = gtk.gdk.keyval_name(event.keyval) + if k in KEYMAP: + return _process_selection(vmw, vmw.grid.grid_to_spr(KEYMAP.index(k))) return True # # Repaint # def _expose_cb(win, event, vmw): - redrawsprites(vmw) + vmw.sprites.redrawsprites() return True # @@ -273,7 +270,7 @@ def set_label(vmw, label, s): vmw.win.set_title("%s: %s" % (_("Visual Match"),s)) # -# Display # of seconds since start_time +# Display of seconds since start_time # def _counter(vmw): set_label(vmw,"clock",str(int(gobject.get_current_time()-\ -- cgit v0.9.1