def convert_to_colorkey_alpha(surf, colorkey=Color('magenta')): """Give the surface a colorkeyed background that will be transparent when drawing. Colorkey alpha, unlike per-pixel alpha, will keep the image's transparent background while using methods such as Surface.set_alpha(). Keyword arguments: surf (Surface): Will be converted to alpha using colorkey. colorkey (Color): The color value for the colorkey. The default is magenta or RGB(255, 0, 255). This should be set to a color that isn't present in the image, otherwise those areas with a matching colour will be drawn transparent as well. """ colorkeyed_surf = Surface(surf.get_size()) colorkeyed_surf.fill(colorkey) colorkeyed_surf.blit(surf, (0, 0)) colorkeyed_surf.set_colorkey(colorkey) colorkeyed_surf.convert() colorkeyed_surf.set_alpha(255) return colorkeyed_surf
def create_blank_surface(width, height): """Return a completely transparent Surface of the given dimensions. Args: width (int): The width of the Surface in pixels. height (int): The height of the Surface in pixels. """ blank_surf = Surface((width, height)) blank_surf.fill(Color('magenta')) blank_surf.set_colorkey(Color('magenta')) blank_surf.convert() blank_surf.set_alpha(255) return blank_surf
def update(self, duration): """ update all the contained linewidgets. Return right away if no text has changed. """ if self.dirty == 0: # no new text has been added return # make the box size = self.rect.size bgcolor = self.bgcolor if bgcolor: # completely opaque bg img = Surface(size) img.fill(self.bgcolor) img = img.convert() else: # more or less transparent img = Surface(size, SRCALPHA) # handles transparency transparency = 50 # 0 = transparent, 255 = opaque img.fill((0, 0, 0, transparency)) # black img = img.convert_alpha() # blit each line for wid in self.linewidgets: wid.update(duration) img.blit(wid.image, wid.rect) self.image = img self.dirty = 0
def __init__(self, evManager, numlines=3, rect=(0, 0, 100, 20), txtcolor=(255, 0, 0), bgcolor=None): Widget.__init__(self, evManager) self._em.reg_cb(ChatlogUpdatedEvent, self.on_remotechat) self._em.reg_cb(MGameAdminEvt, self.on_gameadmin) self._em.reg_cb(MNameChangeFailEvt, self.on_namechangefail) self._em.reg_cb(MMyNameChangedEvent, self.on_namechangesuccess) self._em.reg_cb(MNameChangedEvt, self.on_namechangesuccess) self._em.reg_cb(MdHpsChangeEvt, self.on_updatehps) self.font = Font(None, config_get_fontsize()) self.rect = rect size = rect.size self.txtcolor = txtcolor self.bgcolor = bgcolor if bgcolor: # completely opaque bg img = Surface(size) img.fill(self.bgcolor) img = img.convert() else: # more or less transparent img = Surface(self.rect.size, SRCALPHA) # handles transparency transparency = 50 # 0 = transparent, 255 = opaque img.fill((0, 0, 0, transparency)) # black img = img.convert_alpha() self.image = img self.maxnumlines = numlines self.linewidgets = deque(maxlen=numlines) # deque of TextLabelWidgets
def update(self, duration): """ update all the contained linewidgets TODO: check that it works with transparent bg """ if self.dirty == 0: return # make the box size = self.rect.size bgcol = self.bgcolor if bgcol: # only display a bg img if bgcolor specified img = Surface(size) img.fill(bgcol) img = img.convert() else: # more or less transparent img = Surface(size, SRCALPHA) # handles transparency transparency = 50 # 0 = transparent, 255 = opaque img.fill((0, 0, 0, transparency)) img = img.convert_alpha() # blit each line numelemts = min(len(self.texts), self.maxnumlines) for i in range(numelemts): wid = self.linewidgets[i] wid.set_text(self.texts[-i - 1]) wid.update(duration) img.blit(wid.image, wid.rect) self.image = img
def make_surface(size: Tuple[int, int], alpha: bool=True, used_colors: List[Color]=[], bg_color: Optional[Color]=None): if bg_color is not None: fill_color = bg_color else: used_colors = set(used_colors) for i in range(256): fill_color = (i, i, i) if fill_color not in used_colors: break surface = Surface(size) surface.fill(fill_color) if pygame.display.get_init(): if alpha and bg_color is None: surface.convert_alpha() surface.set_colorkey(surface.get_at((0, 0))) else: surface.convert() return surface
def convert_to_colorkey_alpha(surf, colorkey=color.Color('magenta')): """Give the surface a colorkeyed background that will be transparent when drawing. Colorkey alpha, unlike per-pixel alpha, will allow the surface's transparent background to remain while using methods such as Surface.set_alpha(). Keyword arguments: surf The Surface to convert. colorkey The color value for the colorkey. The default is magenta or RGB(255, 0, 255). This should be set to a color that isn't present in the image, otherwise those areas with a matching colour will be drawn transparent as well. """ colorkeyed_surf = Surface(surf.get_size()) colorkeyed_surf.fill(colorkey) colorkeyed_surf.blit(surf, (0, 0)) colorkeyed_surf.set_colorkey(colorkey) colorkeyed_surf.convert() return colorkeyed_surf
def __init__(self, color="black"): surface = Surface(Window().size) surface = surface.convert() try: color = Color(color) except: color = Color("black") surface.fill(color) self._sprite = SpriteFactory().fromSurface("main.fx.overlay", surface, layer=10000) self._sprite.pinned = True self._sprite.dirty = 1 self._sprite.visible = False self._sprite.image.set_alpha(0) self._fading = 0 # 0: idle | 1: fade in | -1: fade out
def on_board_built(self, ev): """ Build the board background. """ width, height = ev.width, ev.height board = ev.board # to obtain cells from coords win_height = self.window.get_height() bg = Surface((win_height, win_height)) bg = bg.convert() bg.fill(bg_color) for left in range(width): for top in range(height): cell = board.get_cell(left, top) bg.blit(cell.image, cell.rect) # blit the board bg onto the window's bg self.window_bg.blit(bg, (0, 0)) self._em.subscribe(BoardUpdatedEvent, self.on_board_update)
def __init__(self, em, ev): """ em is the mode's event manager, ev is an event containing data from the previous mode. """ self._em = em window = pygame.display.set_mode(resolution) self.window = window pygame.display.set_caption('Smoothie Factory - %s' % self.pagename) # blit the bg screen: all black bg = Surface(window.get_size()) bg.fill((0, 0, 0)) bg = bg.convert() self.window_bg = bg self.window.blit(bg, (0, 0)) # build GUI self.gui = self._build_gui() # return a sprite group em.subscribe(VTickEvent, self.on_tick)
def __init__(self, em, ev): """ Score and recipe widgets on the right, game board on the left. em is the mode's event manager, ev is an event containing data from the previous mode (e.g. menu or level transition). ev contains the level number. """ pygame.display.init() # OK to init multiple times pygame.font.init() self._em = em window = pygame.display.set_mode(resolution) self.window = window pygame.display.set_caption("Smoothie Factory - In Play") # blit the bg screen: all black bg = Surface(window.get_size()) bg.fill((0, 0, 0)) bg = bg.convert() self.window_bg = bg self.window.blit(bg, (0, 0)) # fruit sprites self.fruit_to_spr = {} # map a fruit to its sprite self.fruit_sprites = LayeredDirty() # only reblit when dirty=1 self.interp_steps = 0 # 2 interpolation steps between 2 model updates # build GUI self.gui = self._build_gui() # return a sprite group em.subscribe(BoardBuiltEvent, self.on_board_built) em.subscribe(GameBuiltEvent, self.on_game_built) em.subscribe(FruitKilledEvent, self.on_fruit_killed) em.subscribe(FruitPlacedEvent, self.on_fruit_spawned) em.subscribe(FruitSpeedEvent, self.on_speed_change) em.subscribe(QuitEvent, self.on_quit)
class Player(Entity): def __init__(self, x, y): pygame.init() Entity.__init__(self) self.xvel = 0 self.yvel = 0 self.is_dead = False self.next = False self.level = 1 self.on_ground = False self.image = Surface(PLAYER_SIZE) self.image.convert() self.image.fill(Color(PLAYER_COLOR)) #self.image.fill.blit(PLAYER_SURFACE,x,y) self.rect = Rect(x, y, 32, 32) self.check = False def update(self, up, down, left, right, platforms): if up: # only jump if on the ground if self.on_ground: self.yvel -= 7 if down: pass if left: self.xvel = -5 if right: self.xvel = 5 if not self.on_ground: # only accelerate with gravity if in the air self.yvel += 0.3 # max falling speed if self.yvel > 30: self.yvel = 30 if not (left or right): self.xvel = 0 # increment in x direction self.rect.left += self.xvel # do x-axis collisions self.collide(self.xvel, 0, platforms) # increment in y direction self.rect.top += self.yvel # assuming we're in the air self.on_ground = False; # do y-axis collisions self.collide(0, self.yvel, platforms) def coin_check(self, platforms): for p in platforms: if isinstance(p, CoinBlock): return False return True def collide(self, xvel, yvel, platforms): for p in platforms: if pygame.sprite.collide_rect(self, p): if isinstance(p, ExitBlock): if self.coin_check(platforms): self.next = True self.level += 1 if isinstance(p, SpikeBlock): self.is_dead = True if isinstance(p, CoinBlock): p.collected = True continue if xvel > 0: self.rect.right = p.rect.left if xvel < 0: self.rect.left = p.rect.right if yvel > 0: self.rect.bottom = p.rect.top self.on_ground = True self.yvel = 0 if yvel < 0: self.rect.top = p.rect.bottom
def __init__(self, em, recipes, events_attrs={}, rect=None, txtcolor=None, bgcolor=None): """ Representation of the recipes and their score. When receiving a recipe match event, blink the recipe. events_attrs maps event classes to recipe attributes. Usage: RecipesWidget(em, recipes_to_display, {EventName: 'recipe_attr'}) recipes maps tuples of fruit type to their score. """ Widget.__init__(self, em) # subscribe to recipe match events self.events_attrs = events_attrs for evtClass in events_attrs: self._em.subscribe(evtClass, self.on_recipe_match) self.recipes = recipes # sort recipes by length, then score, then color ord_recipes = list(zip(recipes.keys(), recipes.values())) ord_recipes.sort(key=lambda pair: (len(pair[0]), pair[1], pair[0][0])) # gfx self.font = Font(None, font_size) if rect: self.rect = rect else: self.rect = Rect((0, 0), (100, font_size + 4)) #default width = 100px, # 4px from 1px each of border bottom, # padding bottom, padding top, and border top self.txtcolor = txtcolor self.bgcolor = bgcolor # widget surface widget_surf = Surface(self.rect.size) # recipe lines self.recipe_lines = {} recipe_num = 0 for recipe, score in ord_recipes: # blit fruit surfs and recipe surf on line surf line_rect = Rect(0, recipe_num * font_size + 10, # 10px between lines self.rect.width, font_size) line_surf = Surface(line_rect.size) # score surf score_surf = self.font.render(str(score), True, txtcolor, bgcolor) score_rect = Rect(line_rect.width - 30, 0, 10, line_rect.height) line_surf.blit(score_surf, score_rect) # fruits surf fruit_size = int(font_size * 0.75) for fruit_num, fruit in enumerate(recipe): fruit_color = FRUIT_COLORS[fruit] fruit_rect = Rect(fruit_num * (fruit_size + 5), 0, # 5px-interspace fruit_size, fruit_size) fruit_surf = Surface(fruit_rect.size) fruit_surf.fill(fruit_color) line_surf.blit(fruit_surf, fruit_rect) # store the line so that we can blink/reblit it recipe_line = {'score':score, 'rect': line_rect} self.recipe_lines[recipe] = recipe_line widget_surf.blit(line_surf, line_rect) recipe_num += 1 self.image = widget_surf.convert()
############################# TESTS ################################## if __name__ == "__main__": import pygame from pygame.sprite import Sprite from pygame.surface import Surface from pygame.locals import KEYDOWN, RLEACCEL, SRCALPHA from pygame.font import Font pygame.init() screen = pygame.display.set_mode((300, 300)) bg = Surface((200, 200)) bg.fill((255, 0, 0)) bg = bg.convert() screen.blit(bg, (50, 50)) font = Font(None, 25) txt = 'qwertyuiop' txtimg = font.render(txt, 1, (255, 255, 255)) # antialiasing w/o bg => alpha b = Surface((100, 100), SRCALPHA) b.fill((111, 111, 111, 128)) b.blit(txtimg, (10, 10)) b = b.convert_alpha() screen.blit(b, (25, 25)) # what's below has better perf, but bad output when antialias + transparency c = Surface((100, 100)) colkey = (255, 0, 255)
class Grid(object): def __init__(self, batch=None): self.batch = batch self.cells = {} self.cells_draw = [] self.surface = None for x, y in GRID_SET: cell = Cell((x, y)) self.cells[(x, y)] = cell self.cells_draw += cell.draw def build(self, disp): self.surface = Surface((WIDTH, HEIGHT), HWSURFACE) draw.rect(self.surface, WHITE, Rect(0, 0, WIDTH - WALLWIDTH, HEIGHT - WALLWIDTH), WALLWIDTH) for wall in self.cells_draw: draw.line(self.surface, WHITE, wall[0], wall[1], WALLWIDTH) # if cell.matrix_index == (0, 0): # self.surface.fill( # RED, # Rect( # cell.pos[0]+int(CELLSIZE*0.1), # cell.pos[1]+int(CELLSIZE*0.1), # int(CELLSIZE*0.8), # int(CELLSIZE*0.8) # ) # ) # elif cell.matrix_index == (WIDTH/CELLSIZE-1, HEIGHT/CELLSIZE-1): # self.surface.fill( # BLUE, # Rect( # cell.pos[0]+int(CELLSIZE*0.1), # cell.pos[1]+int(CELLSIZE*0.1), # int(CELLSIZE*0.8), # int(CELLSIZE*0.8) # ) # ) self.surface.convert(disp) def draw(self, disp): if not self.surface: self.build(disp) rect = self.surface.get_rect() rect.center = (WIDTH / 2, HEIGHT / 2) if self.batch: self.batch.add_to_batch(disp.blit(self.surface, rect)) # self.batch.add_to_batch(disp.fill((0,0,0))) else: disp.blit(self.surface, rect) def get_cell(self, pos): if checkpos(pos): return self.cells[pos] return None def get_accessible_cells(self, pos): # for each key in pos_dict create a new key in cells with value equals to the cell in # that pos actual_cell = self.get_cell(pos) pos_dict = { 'top': [0, -1], 'left': [-1, 0], 'right': [1, 0], 'bottom': [0, 1] } cells = {} for i in pos_dict: test_cell = self.get_cell( (pos[0] + pos_dict[i][0], pos[1] + pos_dict[i][1])) if test_cell: if test_cell.check_enter(i) and actual_cell.check_leave(i): cells[i] = test_cell return cells