class Meteor (Sprite): coord_x = 0 coord_y = 0 size = (1,1) falltime = 60 COLOR = 255,0,0 def __init__(self,loc, bounds, falltime): Sprite.__init__(self) self.image = Surface(self.size) self.rect = self.image.get_rect() self.rect.bottomleft = loc self.image.fill(self.color) self.bounds = bounds self.falltime = falltime def update(): self.falltime -= 1 if falltime <= 0: self.coord_x, self.coord_y = self.rect.center self.impact() self.kill() def impact(): #self.explode = Surface(self.size) print "impact!"
def window_init(width, height, color, caption): display = (width, height) # Группируем ширину и высоту в одну переменную screen = pygame.display.set_mode(display) # Создаем окошко pygame.display.set_caption(caption) # Пишем в шапку bg = Surface((width,height)) # Создание видимой поверхности, будем использовать как фон bg.fill(Color(color)) # Заливаем поверхность сплошным цветом return bg, screen
def highlight(self): if not self.highlighted: (x, y) = self.pos() (w, h) = self.rect.size (lw, lh) = (round(w * 1.5), round(h * 1.5)) img = Surface((lw, lh), pygame.SRCALPHA) img.fill(COLOR_WHITE) a = surfa.pixels_alpha(img) d = max(lw, lh) / 2 (cx, cy) = (lw // 2, lh // 2) for i in range(len(a)): for j in range(len(a[i])): k = math.sqrt(sqr(100.0 * (i - cx) / cx) + sqr(100.0 * (j - cy) / cy)) if k > 100: a[i][j] = 0 else: a[i][j] = 255 - round(k / 100.0 * 255.0) a = None img.blit(self.image, ((lw - w) // 2, (lh - h) // 2)) self.image = img self.set_pos(x - (lw - w) // 2, y - (lh - h) // 2) self.highlighted = True
def __init__(self, txt="Hello, World!"): self.text = txt self.__height = 15 self.__width = self.__height * (12.0 / 20.0) self.__cols = 50 self.__rows = 7 self.__accentSize= 10 self.__lineBuff = 2 self.__lineHeight = self.__height + self.__lineBuff self.__buffer = (self.__accentSize + 4,self.__accentSize + 4) self.__size = ((self.__buffer[0] * 2) + self.__cols * self.__width + 1, (self.__buffer[1] * 2) + self.__rows * self.__lineHeight) self.__canvas = Surface(self.__size) self.__box = Surface(self.__size) self.__myFont = font.SysFont("courier", self.__height) self.__color = (255,255,0) self.__bgColor = (0,0,100) self.__edgeColor = (255,255,200) self.__transparent = (255,0,255) self.__cursor = 0 self.__nextCue = "(Press Space)" self.__canvas.set_colorkey(self.__transparent) self.__box.set_colorkey(self.__transparent) self.__preDrawBox()
def makebackground(self, surface): surface.fill((0,0,0)) template = Surface(2*(min(self.zoom.width, self.zoom.height),)) template.fill((0,0,0,255)) width,height = template.get_size() ylim = surface.get_height()/height xlim = surface.get_width()/width data = self._data noise = [[pnoise2(self._selected[1][0]+x, self._selected[0][0]+y, 4, 0.85) * 50 for x in range(xlim)] for y in range(ylim)] hmin = hmax = 0 for y in range(ylim): for x in range(xlim): yd = len(data)*float(y)/ylim xd = len(data[0])*float(x)/xlim h = self._height(data, yd, xd) n = noise[y][x] if h < 0: h += -n if n > 0 else n else: h += n if n > 0 else -n if h < hmin: hmin = h if h > hmax: hmax = h self.rects = [] for y in range(ylim): for x in range(xlim): block = template.copy() yd = len(data)*float(y)/ylim xd = len(data[0])*float(x)/xlim h = self._height(data, yd, xd) n = noise[y][x] if h < 0: h += -n if n > 0 else n else: h += n if n > 0 else -n if h < 0: color = 0, 0, int(255 * (1 - h/hmin)) else: color = 0, int(255 * h/hmax), 0 block.fill(color) if self.selection: if self.selection[0][0] <= yd <= self.selection[0][1]: if self.selection[1][0] <= xd <= self.selection[1][1]: block.fill((255,0,0,32), special_flags = BLEND_ADD) rect = Rect(x*width, y*height, width, height) surface.blit(block, rect.topleft) self.rects.append((rect, (yd, xd)))
class Ship(Sprite): width = 20 height = 20 def __init__(self, x, y, vx, vy, bounds, color): Sprite.__init__(self) self.vx = vx self.vy = vy self.bounds = bounds self.color = color self.rect = Rect(x, y, self.width, self.height) self.image = Surface(self.rect.size) self.draw_image() def draw_image(self): self.image.fill(self.color) def update(self, dt): dt /= 1000.0 dx = int(self.vx * dt) dy = int(self.vy * dt) self.rect.x += dx self.rect.y += dy
def draw_grid(self, tileset): """Returns an image of a tile-based grid""" img = Surface((self.xsize * SIZE, self.ysize * SIZE)) for pos, char in self: rect = get_tile_rect(pos) img.blit(tileset.image, rect, tileset.positions[char]) return img
def block(self, color, shadow = False): colors = {'blue': (27, 34, 224), 'yellow': (225, 242, 41), 'pink': (242, 41, 195), 'green': (22, 181, 64), 'red': (204, 22, 22), 'orange': (245, 144, 12), 'cyan': (10, 255, 226)} if shadow: end = [40] # end is the alpha value else: end = [] # Adding this to the end will not change the array, thus no alpha value border = Surface((self.blocksize, self.blocksize), pygame.SRCALPHA, 32) border.fill(map(lambda c: c*0.5, colors[color]) + end) borderwidth = 2 box = Surface((self.blocksize-borderwidth*2, self.blocksize-borderwidth*2), pygame.SRCALPHA, 32) boxarr = pygame.PixelArray(box) for x in range(len(boxarr)): for y in range(len(boxarr)): boxarr[x][y] = tuple(map(lambda c: min(255, int(c*random.uniform(0.8, 1.2))), colors[color]) + end) del boxarr # deleting boxarr or else the box surface will be 'locked' or something like that and won't blit border.blit(box, Rect(borderwidth, borderwidth, 0, 0)) return border
class Coche(Rect): coche0 = image.load(os.path.join(imagesrep,'button0.png')) coche1 = image.load(os.path.join(imagesrep,'button1.png')) font = font.Font(os.path.join(thisrep,'MonospaceTypewriter.ttf'),8) def __init__(self,label='',fgcolor=(255,255,255),font=None): if not font: font = Coche.font Rect.__init__(self,Coche.coche0.get_rect()) self.scr = display.get_surface() self.status = False label = Coche.font.render(label,1,fgcolor) Rlabel = label.get_rect() Rlabel.midleft = self.midright self.label = Surface(self.union(Rlabel).size,SRCALPHA) self.label.blit(label,Rlabel) def update(self,ev): if ev.type == MOUSEBUTTONUP and self.collidepoint(ev.pos): self.status ^= 1 return True def screen(self): self.scr.blit(Coche.coche1 if self.status else Coche.coche0,self) self.scr.blit(self.label,self)
def join_files(target, sources, images_per_line): lines = len(sources) / images_per_line if len(sources) % images_per_line != 0: lines += 1 first = pygame.image.load(sources[0]) w, h = first.get_width(), first.get_height() result = Surface((w * images_per_line, h * lines)).convert_alpha() result.fill((255, 255, 255, 0)) for i, source in enumerate(sources): im = pygame.image.load(source) im.convert_alpha() if im.get_width() != w or im.get_height() != h: print 'Image %s is not of the same size as the first' exit() x = w * (i % images_per_line) y = h * (i / images_per_line) result.blit(im, (x, y)) # bg = Surface((640, 480), depth=32) # bg.convert_alpha() # bg.fill((255, 0, 0)) # bg.blit(result, (0, 0)) # d.blit(bg, (0, 0)) # pygame.display.flip() # raw_input() pygame.image.save(result, target)
def draw_rectangle(width, height, colour, position, window): rectangle = Surface((width, height)) pixels = surfarray.pixels3d(rectangle) pixels[:][:] = colour del pixels rectangle.unlock() window.blit(rectangle, position)
def create_tag_image( tags, output, size=(500,500), background=(255, 255, 255), layout=LAYOUT_MIX, fontname=DEFAULT_FONT, rectangular=False): """ Create a png tag cloud image """ if not len(tags): return sizeRect, tag_store = _draw_cloud(tags, layout, size=size, fontname=fontname, rectangular=rectangular) image_surface = Surface((sizeRect.w, sizeRect.h), SRCALPHA, 32) image_surface.fill(background) for tag in tag_store: image_surface.blit(tag.image, tag.rect) pygame.image.save(image_surface, output)
class RoboImages(Sprite): color = 0,0,0 size = 60,60 def __init__(self, parent): Sprite.__init__(self) self.parent = parent self.name = parent.name if parent.name == "baby": self.size = 40,40 self.color = parent.color self.image = Surface(self.size) self.rect = self.image.get_rect() self.rect.centerx = self.parent.rect.centerx self.rect.centery = self.parent.rect.centery self.dir = dir try: self.image = load_image(self.name+'bot') print "found family sprite" except: self.image.fill(self.color) print "failed to load family image" self.image = pygame.transform.scale(self.image, self.size) self.image.set_colorkey((255,255,255)) def update(self): self.rect.center = self.parent.rect.center if not self.parent.alive(): self.kill()
def _makebackground(self, size): self._renderer = TextRenderer(self._font, size[0]) bg = Surface(size, flags=SRCALPHA) bg.fill((0,0,0)) dy = 0 bg, dy = self._addline(bg, self._creature.physical(), (255,255,255), dy) appetites = self._creature.appetitereport() if appetites: bg, dy = self._addline(bg, appetites, (255,255,255), dy) inventory = self._creature.inventoryreport() if inventory: bg, dy = self._addline(bg, inventory, (255,255,255), dy) self._background = Surface(size, flags = bg.get_flags()) self._scroll.draw(self._background, bg)
class Bomb(Sprite): width = 10 height = 10 color = 0,200,255 fuse = 3000 def __init__(self, pos): self.image = Surface((self.width, self.height)) self.image.fill(self.color) self.rect = Rect(0,0,self.width, self.height) self.rect.center = pos self.time = fuse def update(self, dt): self.time -= dt step = self.time / 500 if step % 2 == 0: color = 255,255,0 else: color = 255,0,0 self.image.fill(color, self.rect.inflate(-self.width/2, self.height/2))
class Impact(Meteor): size = (100,100) COLOR = 0,140,0 duration = 5 def __init__(self,loc, bounds, duration, kind): #print "explosion!" # Ice should have moving impacts Sprite.__init__(self) self.image = Surface(self.size) self.rect = self.image.get_rect() self.rect.center = loc self.image.fill(self.COLOR) self.bounds = bounds self.duration = duration self.kind = kind if kind == "rock": self.duration = 10 def update(self): self.duration -= 1 if self.duration <= 0: self.coord_x, self.coord_y = self.rect.center self.kill() #def collision(self, robot): def kill (self): Sprite.kill(self)
def _blit_to_block(self, text_array, text_color=(255, 255, 255), block_color=(0, 0, 0)): """ Takes an array of strings with optional text and background colors, creates a Surface to house them, blits the text and returns the Surface. """ rendered_text = [] font_width = [] font_height = [] for text in text_array: ren = self.__font.render(text, True, text_color) rendered_text.append(ren) fw, fh = ren.get_size() font_width.append(fw) font_height.append(fh) block = Surface((max(font_width) + 20, sum(font_height) + 20)) block.fill(block_color) h = 10 for text in rendered_text: block.blit(text, (10, h)) h += font_height[0] return block
def __init__(self, posX, posY, picture, size, resourcePath): self.picture = picture self.size = size self.resourcePath = resourcePath self.maxHealth = 100 * self.size self.health = self.maxHealth self.preimage = image.load(self.resourcePath + "img/" + self.picture + "_buffalo.png") self.image = scale(self.preimage, (int(self.preimage.get_width() * self.size), int(self.preimage.get_height() * self.size))) self.healthFont = font.Font(None, 20) self.healthBarContainer = Surface((int(75 * self.size), int(12 * self.size))).convert() self.healthBarShader = Surface((self.healthBarContainer.get_width() + 6, self.healthBarContainer.get_height() + 6)).convert() self.healthNumber = self.healthFont.render(str(self.health), 1, (0, 0, 0)) self.healthBarShader.fill((175, 175, 175)) self.healthBar = Surface(self.healthBarContainer.get_size()).convert() self.healthColour = () if (self.health >= 50): self.healthColour = (float((self.maxHealth - self.health) * 2 / self.maxHealth * 255), 255, 0) else: self.healthColour = (255, float(self.health * 2 / self.maxHealth * 255), 0) try: self.healthBar.fill(self.healthColour) except TypeError: self.healthBar.fill((0, 0, 0)) self.healthBarContainer.blit(self.healthBar, (0, 0)) self.value = 20 * self.size self.rect = Rect((0, 0), self.image.get_size()) self.rect.x = posX self.rect.y = posY self.status = "alive" self.targetY = posY
class Player(Sprite): def __init__(self, x, y): Sprite.__init__(self) self.image = Surface((22, 32)) self.image.fill((150, 150, 150)) self.xvel = 0 self.yvel = 0 self.x = x self.y = y self.onGroung = False def update(self, left, right): if left: self.xvel = -MOVE_SPEED if right: self.xvel = MOVE_SPEED if not(left or right): self.xvel = 0 if not self.onGroung: self.yvel += GRAVITY self.x += self.xvel self.y += self.yvel def draw(self, surf): surf.blit(self.image, (self.x, self.y))
class Enemy(Sprite): size = width,height = 50,50 color = 255,0,0 vx, vy = 6,6 def __init__(self,loc,bounds): Sprite.__init__(self) self.image = Surface(self.size) self.rect = self.image.get_rect() self.bounds = bounds self.image.fill(self.color) self.rect.bottomleft = loc self.vx = randrange(4,8) direction = 2 * randrange(2)- 1 self.vx *= direction def update(self): self.rect.x += self.vx self.rect.y += self.vy if self.rect.left < self.bounds.left or self.rect.right > self.bounds.right: self.rect.x -= 2 * self.vx self.vx = -self.vx if self.rect.top > self.bounds.bottom: self.kill()
def __init__(self): scrsize = self.w, self.h = display.get_surface().get_size() Surface.__init__(self, scrsize) self.foo = 0 self.l0 = [] self.l1 = [] self.l2 = []
class Player(Sprite): color = 255,25,69 size = 20,20 def __init__(self, loc, bounds): Sprite.__init__(self) #makes player a sprite object self.image = Surface(self.size) self.rect = self.image.get_rect() self.rect.center = loc self.bounds = bounds self.image.fill(self.color) self.bullets = Group() def update(self): self.rect.center = pygame.mouse.get_pos() #player moves/stays with mouse self.rect.clamp_ip(self.bounds) #cant leave screen bounds def shoot(self): if not self.alive(): return #stop doing anything in this function bullet = Bullet(self.bounds) bullet.rect.midbottom = self.rect.midtop self.bullets.add(bullet)
class Player(Sprite): color = 255, 255, 0 size = 20, 20 def __init__(self, loc, bounds): Sprite.__init__(self) self.image = Surface(self.size) self.rect = self.image.get_rect() self.rect.center = loc self.bounds = bounds self.image.fill(self.color) self.bullets = Group() def update(self): self.rect.center = pygame.mouse.get_pos() self.rect.clamp_ip(self.bounds) def shoot(self): if not self.alive(): return bullet = Bullet(self.bounds) bullet.rect.midbottom = self.rect.midtop self.bullets.add(bullet)
def get_surface(self): W, H = functions.get_screen_size() if isinstance(self.img_path, str): # load image surface = load_image(self.img_path) else: # take image surface = self.img_path if 0 < self.alpha < 255: surface.set_alpha(self.alpha, RLEACCEL) if self.mode == "scale to screen": surface = scale(surface, (W, H)) self.size = (W, H) elif self.mode == "cut to screen": new_surface = Surface((W, H)) new_surface.blit(surface, (0, 0)) self.size = (W, H) elif self._resized: surface = scale(surface, self._resized) elif self.mode: functions.debug_msg("Unrecognized mode : ", self.mode) ## elif self._resized: ## surface = scale(surface, self._resized) if self.colorkey: surface.set_colorkey(self.colorkey, RLEACCEL) surface.set_clip(self.clip) if self.alpha < 255: return surface.convert_alpha() else: return surface.convert()
def __init__(self, move_time, nodes): sprite.Sprite.__init__(self) self.nodes = nodes self.orig_nodes = nodes self.move_time = move_time self.spawn_time = time.time() self.image = Surface((40, 40)).convert() self.image_inside = Surface((38, 38)).convert() self.image_inside.fill((0, 255, 0)) self.image.blit(self.image_inside, (1, 1)) self.pos = (80, 40) self.real_pos = (80, 40) self.rect = Rect(self.pos, self.image.get_size()) self.speed = 2 self.speed_mod = 1 self.diag_speed = 2 self.target_pos = (880, 560) self.value = 1 self.cost = 0 self.health = 100 self.damage_mod = 1 self.counter = 0 self.cur_node = self.nodes[0] self.the_dir = (0, 0) self.can_move = False self.name = "Monster" self.description = "A basic monster with slow movement speed and moderate health."
class Bullet(GameObj): def __init__(self): super(Bullet, self).__init__() self.r = config.bulletR self.m = config.bulletM self.shape = ShapeCircle(self.r) self.t = 0 self.length = 0 self.I = 0 self.damage = 0 # image self.image = Surface(Size).convert_alpha() self.image.fill((0, 0, 0, 0)) self.rect = Rect((0, 0), Size) draw.circle(self.image, (0, 0, 0, 0xff), self.rect.center, self.r) def size(self): return (self.r*2, self.r*2) def apply(self): self.length += self.v.length * self.dt self.dt = 0 def update(self): self.rect.center = self.pos def boom(self): self.I = 5000000 self.active = 0
def render(self, text, color): words = text.split() lines = [] h = 0 i = 0 j = 1 while i < len(words): found = False if j == len(words): found = True elif self._font.size(' '.join(words[i:j]))[0] >= self._width: j = max(1, j-1) found = True if found: line = self._font.render(' '.join(words[i:j]), True, color) lines.append(line) h += line.get_height() i = j else: j += 1 image = Surface((self._width, h), flags=SRCALPHA) h = 0 for line in lines: image.blit(line, (0, h)) h += line.get_height() return image
def draw_equipment_item(self, pane): equip_item_pane = Surface((EQUIPMENT_ITEM_WIDTH, EQUIPMENT_ITEM_HEIGHT)) self.draw_border(equip_item_pane) items = [] equipment = self.player.inventory.items_of_type(Equipment) current_equipment = self.selected_party_member.equipment_set.equipment for e in equipment: if not e.equippable_in_slot(self.selected_equip_slot): continue if self.selected_party_member.party_class not in e.compatible_classes: continue if e.equipped and not e in current_equipment.values(): continue if self.selected_equip_slot == "left_hand" and e.equipped and e.equip_slot != self.selected_equip_slot and not e.left_equipped: continue if self.selected_equip_slot == "right_hand" and e.equipped and e.left_equipped: continue items.append(e) self.current_equip_items = items page_index = self.equipment_item_index/EQUIPMENT_PAGE_SIZE start = page_index*EQUIPMENT_PAGE_SIZE end = min(len(items), start + EQUIPMENT_PAGE_SIZE) for i in range(start, end): item = items[i] text = item.name if item.equipped: text += item.equip_tag() text_image = self.ui_font.render(text, True, WHITE) equip_item_pane.blit(text_image, (28, 8 + 40*(i%EQUIPMENT_PAGE_SIZE))) index = self.equipment_item_index%EQUIPMENT_PAGE_SIZE self.draw_pane_pointer(equip_item_pane, index) # TODO: multiple pages of equipment. Navigate w/ left and right arrow keys self.draw_equipment_page_numbers(equip_item_pane) pane.blit(equip_item_pane, (EQUIPMENT_ITEM_X, EQUIPMENT_ITEM_Y))
class Sprite(DirtySprite): """The base sprite class that all sprites inherit.""" def __init__(self, scene, size, color): DirtySprite.__init__(self) self.scene = scene self.image = Surface(size).convert_alpha() self.image.fill(color) self.rect = self.image.get_rect() self.x, self.y = 0, 0 self.facing = [0,2] def move(self): """Move the sprite and set it to dirty for the current frame.""" self.dirty = 1 self.rect.move_ip([self.x, self.y]) def update(self): """Update the sprite each frame.""" if (self.x or self.y): self.facing = [self.x, self.y] self.move() self.collide()
class MortarTower(Tower): def __init__(self, pos): Tower.__init__(self, pos) self.name = "Mortar Tower" self.image = Surface((40, 40)).convert() self.image.fill((0, 0, 255)) self.projectile = Surface((15, 15)).convert() self.projectile.fill((255, 150, 0)) self.projectile_speed = 3 self.radius = 300 self.fire_rate = 3 self.damage = 15 self.description = "A long-range tower that fires mortars which " \ "explode on impact, dealing damage to all nearby enemies." self.cost = 75 self.frame = TowerFrame(self) def update_info(self): self.frame = TowerFrame(self) def upgrade(self): if self.level < 5: self.damage += 5 self.radius += 10 self.projectile_speed += 0.25 self.level += 1 self.update_info() return True return False
# -*- coding:utf-8 -*- __author__ = 'veles' from pygame import display, Surface, draw, KEYDOWN, K_ESCAPE,\ event, time, FULLSCREEN, NOFRAME, font, mouse import sys from math import sin, cos, pi window = display.set_mode((0, 0), FULLSCREEN | NOFRAME) SIZE = window.get_size() screen = Surface(SIZE) def drawing(pos=[0, 0], angle=0, line_size=0): draw.aaline(screen, (0, 255, 0), pos, (sin(angle + 120 * (pi / 180)) * line_size + pos[0], cos(angle + 120 * (pi / 180)) * line_size + pos[1]), 1) draw.aaline(screen, (0, 255, 0), pos, (sin(angle + 240 * (pi / 180)) * line_size + pos[0], cos(angle + 240 * (pi / 180)) * line_size + pos[1]), 1) draw.aaline(screen, (0, 255, 0), pos, (sin(angle + 0 * (pi / 180)) * line_size + pos[0], cos(angle + 0 * (pi / 180)) * line_size + pos[1]), 1) font.init() ff = font.Font(None, int(SIZE[0] / 100 * 12.5)) figure_line_size = SIZE[0] / 100 * 3.125 angle = 0 # angle of rotation
def render(self, ui_screen): super().render(ui_screen) player_manager = self.get_manager(Manager.PLAYER) game_screen = Surface((RESOLUTION_WIDTH, RESOLUTION_HEIGHT), SRCALPHA, 32) game_screen.fill(clear_color[Team.RED]) game_screen.blit(spr_title_text, (self.root_x - spr_title_text.get_width() // 2, 24)) # Render a minimap preview of the current map minimap = draw_map_preview(menu_width - 24, 144, self.bitmap, self.pieces, self.team_data) game_screen.blit(minimap, (self.root_x - minimap.get_width() - 24, self.root_y)) # Render the current lobby status-- open and filled teams for network games, human and AI teams for local if self.is_network_game(): filled_teams = self.get_manager(Manager.NETWORK).filled_teams ai_teams = [] else: filled_teams = dict([(team, get_string(label_strings, "HUMAN_TEAM")) for team in player_manager.human_teams]) ai_teams = player_manager.ai_teams row_y = 0 for team in self.teams: position_x, position_y = self.root_x, self.root_y + row_y * 24 + 1 is_filled = team in filled_teams.keys() x_offset = 0 if is_filled else 16 game_screen.fill(light_color, (position_x - 24 - 1 + x_offset, position_y - 1, menu_width + 3 - x_offset, 24)) game_screen.fill( light_team_color[team] if is_filled else shadow_color[team], (position_x - 24 + x_offset, position_y, menu_width - x_offset, 21)) if team in filled_teams: game_screen.blit( draw_text(filled_teams[team], light_color, dark_color), (position_x + 8, position_y + 4)) elif team in ai_teams: personality_type = player_manager.get_ai_player( team).personality.personality_type game_screen.blit( get_text(personality_strings, personality_type), (position_x + 8, position_y + 4)) else: game_screen.blit(get_text(label_strings, "OPEN_TEAM"), (position_x + 8, position_y + 4)) row_y += 1 if self.lobby_menu: self.lobby_menu.render(game_screen, ui_screen) return game_screen
def set_bar_image(self, unfilled_image: pygame.Surface, filled_image: pygame.Surface, stretch_type: int = STRETCH): """ Sets the bar filled and unfilled images to a custom one with a custom fill/stretch type :param unfilled_image: pygame.Surface object :param filled_image: pygame.Surface object :param stretch_type: int of stretch types (0-3 or run PySliders.show_stretch_types() to see the names) """ if stretch_type == STRETCH: self.sliderUnfilledBar = pygame.transform.scale( unfilled_image, [self.barWidth, self.barThickness]) self.sliderFilledBar = pygame.transform.scale( filled_image, [self.barWidth, self.barThickness]) elif stretch_type == DUPLICATE: y = 0 unfilled_image_dimensions = unfilled_image.get_size() self.sliderUnfilledBar = pygame.Surface( (self.barWidth, self.barThickness), pygame.SRCALPHA, 32) while y is not None: x = 0 while x is not None: self.sliderUnfilledBar.blit(unfilled_image, [x, y]) x += unfilled_image_dimensions[0] if x > self.sliderUnfilledBar.get_width(): x = None y += unfilled_image_dimensions[1] if y > self.sliderUnfilledBar.get_height(): y = None y = 0 filled_image_dimensions = filled_image.get_size() self.sliderFilledBar = pygame.Surface( (self.barWidth, self.barThickness), pygame.SRCALPHA, 32) while y is not None: x = 0 while x is not None: self.sliderFilledBar.blit(filled_image, [x, y]) x += filled_image_dimensions[0] if x > self.sliderFilledBar.get_width(): x = None y += filled_image_dimensions[1] if y > self.sliderFilledBar.get_height(): y = None elif stretch_type == FIT: resized_bar = aspect_resize(unfilled_image, [self.barWidth, self.barThickness]) self.sliderUnfilledBar = pygame.Surface( (self.barWidth, self.barThickness), pygame.SRCALPHA, 32) self.sliderUnfilledBar.blit(resized_bar, [ int((self.barXWidth / 2) - (resized_bar.get_width() / 2)), int((self.barThickness / 2) - (resized_bar.get_height() / 2)) ]) resized_bar = aspect_resize(filled_image, [self.barWidth, self.barThickness]) self.sliderFilledBar = pygame.Surface( (self.barWidth, self.barThickness), pygame.SRCALPHA, 32) self.sliderFilledBar.blit(resized_bar, [ int((self.barXWidth / 2) - (resized_bar.get_width() / 2)), int((self.barThickness / 2) - (resized_bar.get_height() / 2)) ]) elif stretch_type == CENTER: self.sliderUnfilledBar = pygame.Surface( (self.barWidth, self.barThickness), pygame.SRCALPHA, 32) self.sliderUnfilledBar.blit(unfilled_image, [ int((self.barWidth / 2) - (unfilled_image.get_width() / 2)), int((self.barThickness / 2) - (unfilled_image.get_height() / 2)) ]) self.sliderFilledBar = pygame.Surface( (self.barWidth, self.barThickness), pygame.SRCALPHA, 32) self.sliderFilledBar.blit(filled_image, [ int((self.barWidth / 2) - (filled_image.get_width() / 2)), int((self.barThickness / 2) - (filled_image.get_height() / 2)) ]) else: raise ValueError( "set_bar_image() expected a stretch_type of value 0-3 but got: {}, " .format(stretch_type) + "run help({}) to see the names of the presets".format(__name__) )
('o', 1, 0), # crate (' ', 0, 1), # floor ('x', 1, 1), # exit ('.', 2, 0), # dot ('*', 3, 0), # player ] SIZE = 32 def get_tile_rect(x, y): """Converts tile indices to a pygame.Rect""" return Rect(x * SIZE, y * SIZE, SIZE, SIZE) def load_tiles(): """Load tiles and returns a tuple of (image, tile_dict) """ tile_image = image.load('../../images/tiles.xpm') tiles = {} for symbol, x, y in TILE_POSITIONS: tiles[symbol] = get_tile_rect(x, y) return tile_image, tiles if __name__ == '__main__': tile_img, tiles = load_tiles() m = Surface((96, 32)) m.blit(tile_img, get_tile_rect(0, 0), tiles['#']) m.blit(tile_img, get_tile_rect(1, 0), tiles[' ']) m.blit(tile_img, get_tile_rect(2, 0), tiles['*']) image.save(m, 'tile_combo.png')
class menuItemSprite(Sprite): """The menu item class is used to generate the items with hotkeys, coloring and a return value.""" def __init__(self, name, colors, data): Sprite.__init__(self) self.font = menuDefaultFont #pygame.font.Font('freesansbold.ttf', 18) self.hotKey = [] index = name.find('&') if index >= 0: self.imageRenderText = (name[:index], name[index + 1], name[index + 2:]) self.name = str(name[:index] + name[index + 1] + name[index + 2:]) self.hotKey.append(eval('K_' + str(name[index + 1].lower()))) else: self.name = name self.imageRenderText = (name, '', '') self.returnValue = data[0] if len(data) > 1: for rd in data[1:]: self.hotKey.append(eval(str(rd))) self.hilight = False self.disabled = False self.cleanSurface = Surface( self.font.size(self.imageRenderText[0] + self.imageRenderText[1] + self.imageRenderText[2])).convert_alpha() self.cleanSurface.fill((0, ) * 4) self.image = self.cleanSurface.copy() self.rect = self.image.get_rect() self.hiColor = colors[0] self.hkColor = colors[1] self.gray = colors[2] self.darkGray = colors[3] def update(self): self.image = self.cleanSurface.copy() sizeSoFar = 0 if self.disabled: self.image.blit( self.font.render( self.imageRenderText[0] + self.imageRenderText[1] + self.imageRenderText[2], 1, self.darkGray), (0, 0)) elif self.hilight: if self.imageRenderText[0] != '': self.image.blit( self.font.render(self.imageRenderText[0], 1, self.hiColor), (0, 0)) sizeSoFar += self.font.size(self.imageRenderText[0])[0] if self.imageRenderText[1] != '': self.image.blit( self.font.render(self.imageRenderText[1], 1, self.hkColor), (sizeSoFar, 0)) sizeSoFar += self.font.size(self.imageRenderText[1])[0] if self.imageRenderText[2] != '': self.image.blit( self.font.render(self.imageRenderText[2], 1, self.hiColor), (sizeSoFar, 0)) pygame.draw.aaline(self.image, (32, 96, 192), (2, self.rect.h - 2), (self.rect.w - 2, self.rect.h - 2)) else: if self.imageRenderText[0] != '': self.image.blit( self.font.render(self.imageRenderText[0], 1, self.gray), (0, 0)) sizeSoFar += self.font.size(self.imageRenderText[0])[0] if self.imageRenderText[1] != '': self.image.blit( self.font.render(self.imageRenderText[1], 1, self.hkColor), (sizeSoFar, 0)) sizeSoFar += self.font.size(self.imageRenderText[1])[0] if self.imageRenderText[2] != '': self.image.blit( self.font.render(self.imageRenderText[2], 1, self.gray), (sizeSoFar, 0))
class menuGroup(Group): """A class for a menu, mostly encapsulated, semi-dynamic with subclass menuItemSprites generated from a series of tuples in the form: (&Name, reutrn value, optional hotkeys, ...), ... e.g. menu = menuGroup(('&Resume', 'play', 'K_ESCAPE'), None, ('&New game', 'new game'), ('&Quit', 'quit'))""" class titleSprite(Sprite): """The title class of the menu, on the top, text is changable through menu.title.string.""" def __init__(self): Sprite.__init__(self) self.rect = Rect(0, 0, 1, 1) self.font = menuTitleFont #pygame.font.Font('freesansbold.ttf', 24) self.color = (255, ) * 3 self.string = 'Paused' self.image = self.font.render(self.string, 1, self.color) self.rect = self.image.get_rect() self.rect.top = 5 def __setattr__(self, name, value): Sprite.__setattr__(self, name, value) if name == 'string': oldCenterX = self.rect.centerx self.image = self.font.render(self.string, 1, self.color) self.rect = self.image.get_rect() self.rect.centerx = oldCenterX self.rect.top = 5 class versionSprite(Sprite): """A subscript in lower right corner of the menu - generally used for version number.""" def __init__(self, text='menu'): Sprite.__init__(self) self.subscript = text self.font = menuSubFont #pygame.font.Font('freesansbold.ttf', 10) self.color = (255, ) * 3 self.redraw() def redraw(self): self.image = self.font.render(self.subscript, 1, self.color) self.rect = self.image.get_rect() class menuItemSprite(Sprite): """The menu item class is used to generate the items with hotkeys, coloring and a return value.""" def __init__(self, name, colors, data): Sprite.__init__(self) self.font = menuDefaultFont #pygame.font.Font('freesansbold.ttf', 18) self.hotKey = [] index = name.find('&') if index >= 0: self.imageRenderText = (name[:index], name[index + 1], name[index + 2:]) self.name = str(name[:index] + name[index + 1] + name[index + 2:]) self.hotKey.append(eval('K_' + str(name[index + 1].lower()))) else: self.name = name self.imageRenderText = (name, '', '') self.returnValue = data[0] if len(data) > 1: for rd in data[1:]: self.hotKey.append(eval(str(rd))) self.hilight = False self.disabled = False self.cleanSurface = Surface( self.font.size(self.imageRenderText[0] + self.imageRenderText[1] + self.imageRenderText[2])).convert_alpha() self.cleanSurface.fill((0, ) * 4) self.image = self.cleanSurface.copy() self.rect = self.image.get_rect() self.hiColor = colors[0] self.hkColor = colors[1] self.gray = colors[2] self.darkGray = colors[3] def update(self): self.image = self.cleanSurface.copy() sizeSoFar = 0 if self.disabled: self.image.blit( self.font.render( self.imageRenderText[0] + self.imageRenderText[1] + self.imageRenderText[2], 1, self.darkGray), (0, 0)) elif self.hilight: if self.imageRenderText[0] != '': self.image.blit( self.font.render(self.imageRenderText[0], 1, self.hiColor), (0, 0)) sizeSoFar += self.font.size(self.imageRenderText[0])[0] if self.imageRenderText[1] != '': self.image.blit( self.font.render(self.imageRenderText[1], 1, self.hkColor), (sizeSoFar, 0)) sizeSoFar += self.font.size(self.imageRenderText[1])[0] if self.imageRenderText[2] != '': self.image.blit( self.font.render(self.imageRenderText[2], 1, self.hiColor), (sizeSoFar, 0)) pygame.draw.aaline(self.image, (32, 96, 192), (2, self.rect.h - 2), (self.rect.w - 2, self.rect.h - 2)) else: if self.imageRenderText[0] != '': self.image.blit( self.font.render(self.imageRenderText[0], 1, self.gray), (0, 0)) sizeSoFar += self.font.size(self.imageRenderText[0])[0] if self.imageRenderText[1] != '': self.image.blit( self.font.render(self.imageRenderText[1], 1, self.hkColor), (sizeSoFar, 0)) sizeSoFar += self.font.size(self.imageRenderText[1])[0] if self.imageRenderText[2] != '': self.image.blit( self.font.render(self.imageRenderText[2], 1, self.gray), (sizeSoFar, 0)) class separatorSprite(Sprite): """A sprite for (visually) separating menu items.""" def __init__(self, *args): Sprite.__init__(self, *args) self.disabled = True self.image = pygame.Surface((60, 6)).convert_alpha() self.image.fill((0, ) * 4) self.image.fill((64, 64, 64, 224), Rect(0, 3, 60, 2)) self.rect = self.image.get_rect() class selectorSprite(Sprite): """Little image on the left and right bounding the active menu item.""" def __init__(self, parent, flipped, *args): Sprite.__init__(self, *args) self.parent = parent self.flipped = flipped self.image = pygame.Surface((3, 3)) self.image.fill(self.parent.borderColor) if self.flipped: self.image.fill((160, ) * 3, Rect(0, 0, 1, 3)) else: self.image.fill((160, ) * 3, Rect(2, 0, 1, 3)) self.rect = self.image.get_rect() self.parent.add(self) def update(self): if self.flipped: self.rect.left = self.parent.active.rect.right + 8 self.rect.bottom = self.parent.active.rect.bottom - 8 else: self.rect.right = self.parent.active.rect.left - 8 self.rect.bottom = self.parent.active.rect.bottom - 8 def __init__(self, menuItemSet): self.visible = False self.maxX = 0 self.maxY = 0 Group.__init__(self) self.title = self.titleSprite() self.add(self.title) self.maxY += 48 + 5 self.active = None self.bgColor = (8, 24, 34, 224) self.borderColor = (32, 96, 192) # hilight - hotkey - normal - disabled self.menuItemColors = (128, 192, 255), (24, 128, 255), (192, ) * 3, (64, ) * 3 self.enterSurface = None self.offsetOnSurface = (0, 0) self.orderList = [] self.generate(menuItemSet) self.redraw() self.clearBg = Surface(self.bg.get_size()) self.getFirst() self.selectorSprite(self, False) self.selectorSprite(self, True) def get_size(self): return self.bg.get_size() def generate(self, items): c = 1 for i in items: if i == None: thisSprite = self.separatorSprite() else: thisSprite = self.menuItemSprite(i[0], self.menuItemColors, i[1:]) thisSprite.order = c c += 1 if thisSprite.image.get_width() > self.maxX: self.maxX = thisSprite.image.get_width() + 64 self.maxY += thisSprite.rect.h + 2 self.add(thisSprite) self.orderList.append(thisSprite) self.maxY += 32 self.bg = Surface( (max(self.title.rect.w + 20, self.maxX + 20), self.maxY + 20)).convert_alpha() def redraw(self): self.bg.fill(self.bgColor) # img? self.rect = self.bg.get_rect() pygame.draw.rect(self.bg, self.borderColor, self.rect, 1) self.title.rect.centerx = int(self.bg.get_width() / 2) self.title.rect.top = 10 yDrawCounter = self.title.rect.h + 10 for i in self.orderList: i.rect.centerx = int(self.bg.get_width() / 2) i.rect.top = yDrawCounter + 6 yDrawCounter += 6 + i.rect.h #~ for i in self: #~ if isinstance(i, self.versionSprite): #~ i.rect.right = self.rect.right - 3 #~ i.rect.bottom = self.rect.bottom - 2 #~ break def execute(self, item): for i in self: if isinstance(i, self.menuItemSprite): if i.name == item: if i.disabled: return None else: self.visible = False self.active.hilight = False if self.enterSurface is not None: self.enterSurface.blit(self.clearBg, self.offsetOnSurface) #~ self.backupSurface = self.enterSurface.subsurface(Rect(self.backupOffset, (self.rect.w, self.rect.h))) self.enterSurface = None return i.returnValue else: return None def enter(self, enterSurface): self.clearBg = Surface((self.rect.w, self.rect.h)) self.clearBg.blit(enterSurface, (0, 0), self.rect) self.enterSurface = enterSurface #~ self.backupSurface = Surface((self.rect.w, self.rect.h)) self.offsetOnSurface = self.rect.left, self.rect.top self.visible = True self.itemName = '' if self.active is None or self.active.disabled: self.getFirst() print 'menu active:', self.active def tick(self, eventList): rValue = None for event in eventList: #~ if event.type == QUIT: #~ rValue = 'quit' #~ break if event.type == KEYDOWN: rValue = self.execute(self.checkKeys(event.key)) if event.type == MOUSEBUTTONDOWN: self.itemName = self.checkMouse(event.pos) elif event.type == MOUSEBUTTONUP and self.itemName != '': if self.itemName == self.checkMouse(event.pos): rValue = self.execute(self.itemName) elif event.type == MOUSEMOTION: self.checkMouse(event.pos) self.clear() self.update() self.draw() return rValue def disable(self, item): for i in self: if isinstance(i, self.menuItemSprite): if i.name == item: i.disabled = True if item == self.active: self.getFirst() break def enable(self, item): for i in self: if isinstance(i, self.menuItemSprite): if i.name == item: i.disabled = False break def draw(self): Group.draw(self, self.bg) if self.enterSurface is not None: self.enterSurface.blit(self.bg, self.rect) def get_rect(self): return self.bg.get_rect() def clear(self): Group.clear(self, self.bg, self.clear_callback) if self.enterSurface is not None: self.enterSurface.blit(self.clearBg, self.rect) def getByName(self, item): for i in self: if isinstance(i, self.menuItemSprite): if i.name == item: return i def getFirst(self): first = None for i in self.orderList: if isinstance(i, self.menuItemSprite): if not i.disabled: first = i break if first != None: first.hilight = True self.active = first def getLast(self): last = None for i in reversed(self.orderList): if isinstance(i, self.menuItemSprite): if not i.disabled: last = i break if last != None: last.hilight = True self.active = last def checkKeys(self, key): self.active.hilight = False if self.active == None or self.active.disabled: self.getFirst() return None if key == K_RETURN or key == K_KP_ENTER or key == K_SPACE: return self.active.name activeIndex = self.orderList.index(self.active) if key == K_UP: if activeIndex > 0: while activeIndex >= 0: activeIndex -= 1 thisItem = self.orderList[activeIndex] if not thisItem.disabled: self.active = thisItem break else: self.getLast() elif key == K_DOWN: try: while activeIndex < len(self.orderList): activeIndex += 1 thisItem = self.orderList[activeIndex] if not thisItem.disabled: self.active = thisItem break except IndexError: self.getFirst() elif key == K_HOME or key == K_PAGEUP: self.getFirst() elif key == K_END or key == K_PAGEDOWN: self.getLast() else: for i in self: if isinstance(i, self.menuItemSprite): if key in i.hotKey and not i.disabled: return i.name if self.active != None: self.active.hilight = True return None def checkMouse(self, pos): x, y = pos x -= self.rect.left y -= self.rect.top rName = '' for item in self: if isinstance(item, self.menuItemSprite): if item.rect.collidepoint(x, y) and not item.disabled: if self.active != None: self.active.hilight = False self.active = item item.hilight = True rName = item.name return rName def subscript(self, text=None): for i in self: if isinstance(i, self.versionSprite): self.remove(i) break if text is not None: i = self.versionSprite(text) i.rect.right = self.rect.right - 3 i.rect.bottom = self.rect.bottom - 2 self.add(i) print i.rect def clear_callback(self, surf, rect): surf.fill(self.bgColor, rect)
from Bonus import Bonus from Camera import Camera from Menu import Menu from Target import Target from pygame import display, Surface, init, sprite, mixer, time, font, Rect,\ Color, event, QUIT, KEYDOWN, KEYUP,\ K_UP, K_RIGHT, K_ESCAPE, K_LEFT init() # Инициализация pygame window = display.set_mode(WINDOW) # Создание окна display.set_caption("Dakota`s run") # Название окна screen = Surface(DISPLAY) # Создание видимой поверхности # Строка состояния info_string = Surface((640, 30)) # Шрифты font.init() inf_font = font.Font(None, 32) # Создание героя hero = Player(320, 1320) left = right = up = False # Создание уровня with open(LEVEL_1, 'r') as level1:
class PygameView: def __init__(self, evManager): self.evManager = evManager self.evManager.RegisterListener(self) self.window = display.set_mode((720, 420)) self.winsize = self.window.get_size() display.set_caption("Blokus") self.background = Surface(self.window.get_size()) self.background.fill((255, 255, 255)) self.window.blit(self.background, (0, 0)) sbLoc = (len(o.board.matrix) * 20 + 5, 0) self.scorebox = {"surf": Surface((100, 200)), "loc": sbLoc} self.scorebox["surf"].fill((255, 255, 255)) self.font = font.Font(None, 40) pbLoc = (sbLoc[0] + 100, 0) self.piecebox = self.window.subsurface(Rect(pbLoc, (200, 420))) self.piecebox.fill((255, 255, 255)) self.drawBoard() self.drawPiece() self.drawScores() self.drawPlayerPieces() display.flip() def drawBoard(self): csize = o.board.csize space = image.load(join("sprites", "space.png")) pieceImg = image.load(join("sprites", "piece.jpg")) pieceArray = surfarray.array3d(pieceImg) for row in o.board.matrix: for cell in row: self.window.blit(space, (cell.x * csize, cell.y * csize)) if cell.color: piece = n.array(pieceArray) if cell.color == "r": piece[:, :, 1:] = 0 elif cell.color == "g": piece[:, :, [0, 2]] = 0 elif cell.color == "b": piece[:, :, :2] = 0 elif cell.color == "y": piece[:, :, 2] = 0 surfarray.blit_array(pieceImg, piece) self.window.blit(pieceImg, (cell.x * csize + 1, cell.y * csize + 1)) def drawPiece(self): csize = o.board.csize pieceImg = image.load(join("sprites", "piece.jpg")) p = o.players.cur pieceArray = surfarray.array3d(pieceImg) if p.c == "r": pieceArray[:, :, 1:] = 0 elif p.c == "g": pieceArray[:, :, [0, 2]] = 0 elif p.c == "b": pieceArray[:, :, :2] = 0 elif p.c == "y": pieceArray[:, :, 2] = 0 surfarray.blit_array(pieceImg, pieceArray) pieceImg.set_alpha(175) bpos = n.array((p.pos[0] * csize + 1, p.pos[1] * csize + 1)) for r in range(len(p.curPiece.m)): for c in range(len(p.curPiece.m[0])): if p.curPiece.m[r][c] == 1: pos = n.array((c * csize, r * csize)) self.window.blit(pieceImg, bpos + pos) def drawScores(self): self.scorebox["surf"].fill((255, 255, 255)) scores = [] for player in o.players.players: scores.append( self.font.render(player.c + ": " + str(player.score), True, (0, 0, 0))) for s in range(len(scores)): self.scorebox["surf"].blit(scores[s], (0, s * 50)) self.window.blit(self.scorebox["surf"], self.scorebox["loc"]) def drawPlayerPieces(self): self.piecebox.fill((255, 255, 255)) pieceImg = image.load(join("sprites", "piecesmall.jpg")) pieceArrays = { "r": surfarray.array3d(pieceImg), "g": surfarray.array3d(pieceImg), "b": surfarray.array3d(pieceImg), "y": surfarray.array3d(pieceImg) } pieceArrays["r"][:, :, 1:] = 0 pieceArrays["g"][:, :, [0, 2]] = 0 pieceArrays["b"][:, :, :2] = 0 pieceArrays["y"][:, :, 2] = 0 bpos = n.array((0, 0)) for player in o.players.players: surfarray.blit_array(pieceImg, pieceArrays[player.c]) for size in player.pieces.keys(): for p in player.pieces[size]: if len(p.m) < len(p.m[0]): isTaller = True h = len(p.m) psize = (9 * len(p.m[0]), 9 * len(p.m)) else: isTaller = False h = len(p.m[0]) psize = (9 * len(p.m), 9 * len(p.m[0])) pieceImg.set_alpha(100) if player is o.players.cur: pieceRect = self.piecebox.subsurface(Rect(bpos, psize)) o.players.pieces.append((pieceRect, size, p)) if p is player.curPiece: pieceImg.set_alpha(255) for r in range(len(p.m)): for c in range(len(p.m[0])): if isTaller: x = c y = r else: x = r y = c if p.m[r][c] == 1: pos = n.array((x * 9, y * 9)) if player.c == o.players.cur.c: pieceRect.blit(pieceImg, pos) else: self.piecebox.blit(pieceImg, bpos + pos) bpos[1] += h * 9 + 1 bpos[0] += 50 bpos[1] = 0 def Notify(self, event): if isinstance( event, (e.GetPiece, e.RotPiece, e.NextPiece, e.MovePiece, e.SwitchPiece)): self.drawBoard() self.drawPiece() if isinstance(event, (e.GetPiece, e.NextPiece, e.SwitchPiece)): self.drawPlayerPieces() display.update() if isinstance(event, e.NextTurn): self.drawBoard() self.drawPiece() self.drawPlayerPieces() self.drawScores() display.update()
def __draw_bar(surface: Surface, width: int, height: int, x: int, y: int): img = Surface((width, 1)) img.fill(color) surface.blit(img, (x, y - height - bar_height))
def create_label(self, font_color, box_color): label_box = Surface((self.label_text.get_rect().width + 40, self.label_text.get_rect().height + 10)) label_box.fill(box_color) self.set_font_color(font_color) label_box.blit(self.label_text, (20, 5)) return label_box
def draw_tt(expr: sympy.Symbol): """...""" font: pygame.font.Font = style.get('.tt-font', 'font') color = style.get('.tt-font', 'font-color') background = style.get('.tt-item', 'background') indent, _, cell_width, _ = style.get('.tt-item', 'rect') _, _, width, height = style.get('.infobar-page-tt', 'rect') _, sy = style.get('.tt-items', 'shift') variables, truth_table = calculate_tt(expr) result = Surface((width, height), pygame.SRCALPHA) back = Surface((width, (len(truth_table) + 1) * sy)) back.fill(background) result.blit(back, (0, 0)) for i, var in enumerate(variables + ('RES', )): letter = font.render(str(var), True, color << 8) result.blit(letter, (indent + i * cell_width, 0)) # lts = { # '0': font.render('0', True, color << 8), # '1': font.render('1', True, color << 8) # } lts = { '0': style.get('.tt-false', 'icon'), '1': style.get('.tt-true', 'icon') } ix, iy, _, _ = style.get('.tt-false', 'icon-rect') for i, res in enumerate(truth_table): for j, char in enumerate( bin((i << 1) + bool(res))[2:].zfill(len(variables) + 1)): result.blit(lts[char], (indent + ix + j * cell_width, iy + (i + 1) * sy)) return result
def draw(self, screen: Surface): return screen.blit(self.surface, self._get_final_position())
class Button(Sprite): def __init__(self, x=0, y=0, width=10, height=10, text='', text_size=0, color=(10, 10, 120), alt_text=''): Sprite.__init__(self) self.image = Surface((width, height)) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.PL_W = width self.PL_H = height self.text = text self.alt_text = alt_text if text_size == 0: self.font = font.Font(None, width) elif text_size > 0: self.font = font.Font(None, text_size) self.color = color def update(self, plitki=[]): if len(plitki) > 1: for pl in plitki: if self != pl: if collide_rect(self, pl): if self.rect.x < pl.rect.x: self.rect.x -= 1 pl.rect.x += 1 elif self.rect.x > pl.rect.x: self.rect.x += 1 pl.rect.x -= 1 if self.rect.y < pl.rect.y: self.rect.y -= 1 pl.rect.y += 1 elif self.rect.y > pl.rect.y: self.rect.y += 1 pl.rect.y -= 1 surf = get_surface() if self.rect.x <= 0: self.rect.x += 1 if self.rect.y <= 0: self.rect.y += 1 if self.rect.x + self.rect.w >= surf.get_width(): self.rect.x -= 1 if self.rect.y + self.rect.h >= surf.get_height(): self.rect.y -= 1 if self.mouse_on_button(): self.image.fill((255 - self.color[0], 255 - self.color[1], 255 - self.color[2])) rect(self.image, (125, 125, 125), (0, 0, self.PL_W, self.PL_H), 1) self.image.blit(self.font.render(self.text, 1, self.color), (3, 3)) else: self.image.fill(self.color) rect(self.image, (255, 255, 255), (0, 0, self.PL_W, self.PL_H), 1) self.image.blit( self.font.render(self.text, 1, (255 - self.color[0], 255 - self.color[1], 255 - self.color[2])), (3, 3)) def onClick(self, mouse_click=False): mx, my = get_pos() if self.rect.x < mx and self.rect.x + self.PL_W > mx and self.rect.y < my and self.rect.y + self.PL_H > my and mouse_click: return 1 else: return 0 def mouse_on_button(self): mx, my = get_pos() if self.rect.x < mx and self.rect.x + self.PL_W > mx and self.rect.y < my and self.rect.y + self.PL_H > my: return 1 else: return 0
def draw_expr(expression: t_Expr, brackets_everywhere: bool = False): """Возвращает изображение выражения в математическом виде""" bar_height = style.get('.viewer-expression', 'bar') font: pygame.font.Font = style.get('.viewer-expression', 'font') color = style.get('.viewer-expression', 'font-color') interval = style.get('.viewer-expression', 'font-spacing') def __priority(operation: int): return int(operation == T_AND) def __draw_bar(surface: Surface, width: int, height: int, x: int, y: int): img = Surface((width, 1)) img.fill(color) surface.blit(img, (x, y - height - bar_height)) def __draw_symbol(surface: t.Optional[Surface], symbol: str, x: int, y: int): img = font.render(symbol, True, color << 8) rect = img.get_rect() if surface: rect.bottomleft = x, y surface.blit(img, rect) return rect.size def __draw_constant(surface: t.Optional[Surface], expr: Constant, x: int, y: int) -> (int, int): return __draw_symbol(surface, style.EXPR_CONSTANT_MAPPING[expr.value], x, y) def __draw_variable(surface: t.Optional[Surface], expr: Variable, x: int, y: int) -> (int, int): return __draw_symbol(surface, style.EXPR_VARIABLE_MAPPING[expr.type], x, y) def __draw_operation(surface: t.Optional[Surface], expr: Expression, x: int, y: int) -> (int, int): return __draw_symbol(surface, style.EXPR_OPERATION_MAPPING[expr.operation], x, y) def __draw_open_bracket(surface: t.Optional[Surface], x: int, y: int) -> (int, int): return __draw_symbol(surface, style.EXPR_BRACKETS[0], x, y) def __draw_close_bracket(surface: t.Optional[Surface], x: int, y: int) -> (int, int): return __draw_symbol(surface, style.EXPR_BRACKETS[1], x, y) def __draw_expr(surface: t.Optional[Surface], expr: t_Expr, x: int, y: int, brackets: bool): if type(expr) is Constant: width, height = __draw_constant(surface, expr, x, y) return width, height if type(expr) is Variable: width, height = __draw_variable(surface, expr, x, y) if expr.is_inverted and surface: __draw_bar(surface, width, height, x, y) return width, height + bar_height * expr.is_inverted total = 0 ob_height = 0 if brackets: width, ob_height = __draw_open_bracket(surface, x, y) total += width needs_brackets = brackets_everywhere or type( expr.operand_1) is Expression and __priority( expr.operation) > __priority(expr.operand_1.operation) width1, height1 = __draw_expr(surface, expr.operand_1, x + total, y, needs_brackets) total += width1 + interval width, op_height = __draw_operation(surface, expr, x + total, y) total += width + interval needs_brackets = brackets_everywhere or type( expr.operand_1) is Expression and __priority( expr.operation) > __priority(expr.operand_1.operation) width2, height2 = __draw_expr(surface, expr.operand_2, x + total, y, needs_brackets) total += width2 oc_height = 0 if brackets: width, oc_height = __draw_close_bracket(surface, x + total, y) total += width height = max(ob_height, height1, op_height, height2, oc_height) if expr.is_inverted and surface: __draw_bar(surface, total, height, x, y) return total, height + bar_height * expr.is_inverted size = __draw_expr(None, expression, 0, 0, False) result = Surface(size, pygame.SRCALPHA) __draw_expr(result, expression, 0, size[1], False) return result
def __(pos: Tuple[int, int], surface: pg.Surface) -> Tuple[Union[int, float], Union[int, float]]: return pos[0], surface.get_height() - pos[1]
def draw_scheme(expression: t_Expr): """Возвращает изображение выражения в виде схемы""" _, _, block_width, block_height = style.get('.board-gates', 'item-rect') pad_x, pad_y = style.get('.board-gates', 'shift') color = style.get('.board-gates-and', 'outline') shift = 10 def __draw_line(surface: Surface, pos1: (int, int), pos2: (int, int)): x1, y1 = pos1 x2, y2 = pos2 pygame.draw.line(surface, color, (x1, y1), (x1 - shift, y1), 2) pygame.draw.line(surface, color, (x2, y2), (x2 + shift, y2), 2) pygame.draw.line(surface, color, (x1 - shift, y1), (x2 + shift, y2), 2) def __draw_block(surface: Surface, element: str, rect: (int, int, int, int)): style.blit_button(surface, element, rect) def __draw_block_constant(surface: Surface, expr: Constant, x: int, y: int): element = f'.board-gates-{style.CONSTANT_MAPPING[expr.value]}' __draw_block(surface, element, (x, y, block_width, block_height)) def __draw_block_variable(surface: Surface, expr: Variable, x: int, y: int): element = f'.board-gates-{style.VARIABLE_MAPPING[(expr.type, expr.is_inverted)]}' __draw_block(surface, element, (x, y, block_width, block_height)) def __draw_block_operation(surface: Surface, expr: Expression, x: int, y: int): element = f'.board-gates-{style.OPERATION_MAPPING[(expr.operation, expr.is_inverted)]}' __draw_block(surface, element, (x, y, block_width, block_height)) def __draw_scheme(surface: t.Optional[Surface], expr: t_Expr, x: int, y: int): if type(expr) is Constant: if surface: __draw_block_constant(surface, expr, x, y) return block_width, block_height if type(expr) is Variable: if surface: __draw_block_variable(surface, expr, x, y) return block_width, block_height if surface: __draw_line(surface, (x, y + block_height // 3), (x - pad_x, y + block_height // 2)) width1, height1 = __draw_scheme(surface, expr.operand_1, x - block_width - pad_x, y) if surface: __draw_line(surface, (x, y + block_height * 2 // 3), (x - pad_x, y + height1 + pad_y + block_height // 2)) width2, height2 = __draw_scheme(surface, expr.operand_2, x - block_width - pad_x, y + height1 + pad_y) if surface: __draw_block_operation(surface, expr, x, y) return block_width + pad_x + max(width1, width2), height1 + pad_y + height2 size = __draw_scheme(None, expression, 0, 0) result = Surface(size) result.fill(style.get('.projectbar-page-board', 'background')) result.set_colorkey(style.get('.projectbar-page-board', 'background')) __draw_scheme(result, expression, size[0] - block_width, 0) return result
def draw(self, canvas: pygame.Surface): if self.has_rect: pygame.draw.rect(canvas, self.rect_color, self.lbl_box) canvas.blit(self.lbl_obj, self.lbl_box)
def random_circle(screen: pg.Surface, radius: Union[int, float]=1) -> 'Circle': x, y = randrange(0, screen.get_width()), randrange(0, screen.get_height()) return Circle((x, y), radius, screen)
def create_body(size, color): surface = Surface(size, pygame.SRCALPHA) surface.fill((color[0], color[1], color[2], 155)) pygame.draw.rect(surface, color, Rect((0, 0), (size[0] - 1, size[1] - 1)), 4) return surface
def draw(self, screen: pygame.Surface): x, y = pygame.mouse.get_pos() piece_rect = self.piece.get_sprite_rect() coords = x - piece_rect.width / 2, y - piece_rect.height / 2 screen.blit(Piece.SPRITE, coords, self.piece.get_sprite_rect())
def draw_to_surface(self, surface : pygame.Surface, x_offset, y_offset): if self.active: surface.blit(self.image, (self.x+x_offset, self.y+y_offset))
class Status_bar: def __init__(self, x, y): self.x = x self.y = y self.surface = Surface((360, 60)) self.surface.fill((65, 56, 231)) self.surface.set_colorkey((65, 56, 231)) self.surface.set_alpha(200) self.image = load("images/status_bar/status_bar.png") self.hp_image = load('images/status_bar/hp.png') self.friend_image = load('images/tanks/player_up_1.png') self.friend_image.set_colorkey((255, 255, 255)) self.enemy_image = load('images/tanks/enemy_up_1.png') self.enemy_image.set_colorkey((255, 255, 255)) self.font = font.Font('fonts/ComicTalecopy.ttf', 32) def show(self, hp, friends, enemies, lvl, scr, scr_w): self.surface.blit(self.image, (0, 0)) self.surface.blit(self.hp_image, (10, 10)) self.surface.blit(self.font.render('X' + str(hp), 1, (255, 255, 255)), (55, 15)) self.surface.blit(self.friend_image, (110, 10)) self.surface.blit( self.font.render('X' + str(friends - 1), 1, (255, 255, 255)), (155, 15)) self.surface.blit(self.enemy_image, (210, 10)) self.surface.blit( self.font.render('X' + str(enemies), 1, (255, 255, 255)), (255, 15)) scr.blit(self.surface, (0, 0)) scr.blit(self.font.render('Stage ' + str(lvl), 1, (255, 255, 255)), (1366 - self.font.size('stage' + str(lvl))[0] - 20, 10))
def info_surf(self): textcolor = (255, 255, 255) font = pygame.font.Font(None, 30) width = (WIDTH-(MATRIS_OFFSET+BLOCKSIZE*MATRIX_WIDTH+BORDERWIDTH*2)) - MATRIS_OFFSET*2 def renderpair(text, val): text = font.render(text, True, textcolor) val = font.render(str(val), True, textcolor) surf = Surface((width, text.get_rect().height + BORDERWIDTH*2), pygame.SRCALPHA, 32) surf.blit(text, text.get_rect(top=BORDERWIDTH+10, left=BORDERWIDTH+10)) surf.blit(val, val.get_rect(top=BORDERWIDTH+10, right=width-(BORDERWIDTH+10))) return surf scoresurf = renderpair("Score", self.matris.score) levelsurf = renderpair("Level", self.matris.level) linessurf = renderpair("Lines", self.matris.lines) combosurf = renderpair("Combo", "x{}".format(self.matris.combo)) height = 20 + (levelsurf.get_rect().height + scoresurf.get_rect().height + linessurf.get_rect().height + combosurf.get_rect().height ) area = Surface((width, height)) area.fill(BORDERCOLOR) area.fill(BGCOLOR, Rect(BORDERWIDTH, BORDERWIDTH, width-BORDERWIDTH*2, height-BORDERWIDTH*2)) area.blit(levelsurf, (0,0)) area.blit(scoresurf, (0, levelsurf.get_rect().height)) area.blit(linessurf, (0, levelsurf.get_rect().height + scoresurf.get_rect().height)) area.blit(combosurf, (0, levelsurf.get_rect().height + scoresurf.get_rect().height + linessurf.get_rect().height)) return area
def rotozoom(surface: pygame.Surface, angle, scale): width, height = surface.get_rect().size new_surface = pygame.transform.scale( surface, (floor(width * scale), floor(height * scale))) new_surface = pygame.transform.rotate(new_surface, angle) return new_surface
class Matris(object): def __init__(self, size=(MATRIX_WIDTH, MATRIX_HEIGHT), blocksize=BLOCKSIZE): self.size = {'width': size[0], 'height': size[1]} self.blocksize = blocksize self.surface = Surface((self.size['width'] * self.blocksize, (self.size['height']-2) * self.blocksize)) self.matrix = dict() for y in range(self.size['height']): for x in range(self.size['width']): self.matrix[(y,x)] = None self.next_tetromino = random.choice(list_of_tetrominoes) self.set_tetrominoes() self.tetromino_rotation = 0 self.downwards_timer = 0 self.base_downwards_speed = 0.4 # Move down every 400 ms self.movement_keys = {'left': 0, 'right': 0} self.movement_keys_speed = 0.05 self.movement_keys_timer = (-self.movement_keys_speed)*2 self.level = 1 self.score = 0 self.lines = 0 self.combo = 1 # Combo will increase when you clear lines with several tetrominos in a row self.paused = False self.gameover = False self.highscore = load_score() self.played_highscorebeaten_sound = False self.levelup_sound = get_sound("levelup.wav") self.gameover_sound = get_sound("gameover.wav") self.linescleared_sound = get_sound("linecleared.wav") self.highscorebeaten_sound = get_sound("highscorebeaten.wav") def set_tetrominoes(self): self.current_tetromino = self.next_tetromino self.next_tetromino = random.choice(list_of_tetrominoes) self.surface_of_next_tetromino = self.construct_surface_of_next_tetromino() self.tetromino_position = (0,4) if len(self.current_tetromino.shape) == 2 else (0, 3) self.tetromino_rotation = 0 self.tetromino_block = self.block(self.current_tetromino.color) self.shadow_block = self.block(self.current_tetromino.color, shadow=True) def hard_drop(self): amount = 0 while self.request_movement('down'): amount += 1 self.lock_tetromino() self.score += 10*amount def update(self, timepassed): pressed = lambda key: event.type == pygame.KEYDOWN and event.key == key unpressed = lambda key: event.type == pygame.KEYUP and event.key == key events = pygame.event.get() for event in events: if pressed(pygame.K_p): self.surface.fill((0,0,0)) self.paused = not self.paused elif event.type == pygame.QUIT: self.prepare_and_execute_gameover(playsound=False) exit() elif pressed(pygame.K_ESCAPE): self.prepare_and_execute_gameover(playsound=False) if self.paused: return for event in events: if pressed(pygame.K_SPACE): self.hard_drop() elif pressed(pygame.K_UP) or pressed(pygame.K_w): self.request_rotation() elif pressed(pygame.K_LEFT) or pressed(pygame.K_a): self.request_movement('left') self.movement_keys['left'] = 1 elif pressed(pygame.K_RIGHT) or pressed(pygame.K_d): self.request_movement('right') self.movement_keys['right'] = 1 elif unpressed(pygame.K_LEFT) or unpressed(pygame.K_a): self.movement_keys['left'] = 0 self.movement_keys_timer = (-self.movement_keys_speed)*2 elif unpressed(pygame.K_RIGHT) or unpressed(pygame.K_d): self.movement_keys['right'] = 0 self.movement_keys_timer = (-self.movement_keys_speed)*2 self.downwards_speed = self.base_downwards_speed ** (1 + self.level/10.) self.downwards_timer += timepassed downwards_speed = self.downwards_speed*0.10 if any([pygame.key.get_pressed()[pygame.K_DOWN], pygame.key.get_pressed()[pygame.K_s]]) else self.downwards_speed if self.downwards_timer > downwards_speed: if not self.request_movement('down'): self.lock_tetromino() self.downwards_timer %= downwards_speed if any(self.movement_keys.values()): self.movement_keys_timer += timepassed if self.movement_keys_timer > self.movement_keys_speed: result = self.request_movement('right' if self.movement_keys['right'] else 'left') self.movement_keys_timer %= self.movement_keys_speed with_shadow = self.place_shadow() try: with_tetromino = self.blend(self.rotated(), allow_failure=False, matrix=with_shadow) except BrokenMatrixException: self.prepare_and_execute_gameover() return for y in range(self.size['height']): for x in range(self.size['width']): # I hide the 2 first rows by drawing them outside of the surface block_location = Rect(x*self.blocksize, (y*self.blocksize - 2*self.blocksize), self.blocksize, self.blocksize) if with_tetromino[(y,x)] is None: self.surface.fill(BGCOLOR, block_location) else: if with_tetromino[(y,x)][0] == 'shadow': self.surface.fill(BGCOLOR, block_location) self.surface.blit(with_tetromino[(y,x)][1], block_location) def prepare_and_execute_gameover(self, playsound=True): if playsound: self.gameover_sound.play() write_score(self.score) self.gameover = True def place_shadow(self): posY, posX = self.tetromino_position while self.blend(position=(posY, posX)): posY += 1 position = (posY-1, posX) return self.blend(position=position, block=self.shadow_block, shadow=True) or self.matrix # If the blend isn't successful just return the old matrix. The blend will fail later in self.update, it's game over. def fits_in_matrix(self, shape, position): posY, posX = position for x in range(posX, posX+len(shape)): for y in range(posY, posY+len(shape)): if self.matrix.get((y, x), False) is False and shape[y-posY][x-posX]: # outside matrix return False return position def request_rotation(self): rotation = (self.tetromino_rotation + 1) % 4 shape = self.rotated(rotation) y, x = self.tetromino_position position = (self.fits_in_matrix(shape, (y, x)) or self.fits_in_matrix(shape, (y, x+1)) or self.fits_in_matrix(shape, (y, x-1)) or self.fits_in_matrix(shape, (y, x+2)) or self.fits_in_matrix(shape, (y, x-2))) # ^ Thats how wall-kick is implemented if position and self.blend(shape, position): self.tetromino_rotation = rotation self.tetromino_position = position return self.tetromino_rotation else: return False def request_movement(self, direction): posY, posX = self.tetromino_position if direction == 'left' and self.blend(position=(posY, posX-1)): self.tetromino_position = (posY, posX-1) return self.tetromino_position elif direction == 'right' and self.blend(position=(posY, posX+1)): self.tetromino_position = (posY, posX+1) return self.tetromino_position elif direction == 'up' and self.blend(position=(posY-1, posX)): self.tetromino_position = (posY-1, posX) return self.tetromino_position elif direction == 'down' and self.blend(position=(posY+1, posX)): self.tetromino_position = (posY+1, posX) return self.tetromino_position else: return False def rotated(self, rotation=None): if rotation is None: rotation = self.tetromino_rotation return rotate(self.current_tetromino.shape, rotation) def block(self, color, shadow=False): colors = {'blue': (27, 34, 224), 'yellow': (225, 242, 41), 'pink': (242, 41, 195), 'green': (22, 181, 64), 'red': (204, 22, 22), 'orange': (245, 144, 12), 'cyan': (10, 255, 226)} if shadow: end = [40] # end is the alpha value else: end = [] # Adding this to the end will not change the array, thus no alpha value border = Surface((self.blocksize, self.blocksize), pygame.SRCALPHA, 32) border.fill(map(lambda c: c*0.5, colors[color]) + end) borderwidth = 2 box = Surface((self.blocksize-borderwidth*2, self.blocksize-borderwidth*2), pygame.SRCALPHA, 32) boxarr = pygame.PixelArray(box) for x in range(len(boxarr)): for y in range(len(boxarr)): boxarr[x][y] = tuple(map(lambda c: min(255, int(c*random.uniform(0.8, 1.2))), colors[color]) + end) del boxarr # deleting boxarr or else the box surface will be 'locked' or something like that and won't blit. border.blit(box, Rect(borderwidth, borderwidth, 0, 0)) return border def lock_tetromino(self): self.matrix = self.blend() lines_cleared = self.remove_lines() self.lines += lines_cleared if lines_cleared: if lines_cleared >= 4: self.linescleared_sound.play() self.score += 100 * (lines_cleared**2) * self.combo if not self.played_highscorebeaten_sound and self.score > self.highscore: if self.highscore != 0: self.highscorebeaten_sound.play() self.played_highscorebeaten_sound = True if self.lines >= self.level*10: self.levelup_sound.play() self.level += 1 self.combo = self.combo + 1 if lines_cleared else 1 self.set_tetrominoes() def remove_lines(self): lines = [] for y in range(self.size['height']): line = (y, []) for x in range(self.size['width']): if self.matrix[(y,x)]: line[1].append(x) if len(line[1]) == self.size['width']: lines.append(y) for line in sorted(lines): for x in range(self.size['width']): self.matrix[(line,x)] = None for y in range(0, line+1)[::-1]: for x in range(self.size['width']): self.matrix[(y,x)] = self.matrix.get((y-1,x), None) return len(lines) def blend(self, shape=None, position=None, matrix=None, block=None, allow_failure=True, shadow=False): if shape is None: shape = self.rotated() if position is None: position = self.tetromino_position copy = dict(self.matrix if matrix is None else matrix) posY, posX = position for x in range(posX, posX+len(shape)): for y in range(posY, posY+len(shape)): if (copy.get((y, x), False) is False and shape[y-posY][x-posX] # shape is outside the matrix or # coordinate is occupied by something else which isn't a shadow copy.get((y,x)) and shape[y-posY][x-posX] and copy[(y,x)][0] != 'shadow'): if allow_failure: return False else: raise BrokenMatrixException("Tried to blend a broken matrix. This should mean game over, if you see this it is certainly a bug. (or you are developing)") elif shape[y-posY][x-posX] and not shadow: copy[(y,x)] = ('block', self.tetromino_block if block is None else block) elif shape[y-posY][x-posX] and shadow: copy[(y,x)] = ('shadow', block) return copy def construct_surface_of_next_tetromino(self): shape = self.next_tetromino.shape surf = Surface((len(shape)*self.blocksize, len(shape)*self.blocksize), pygame.SRCALPHA, 32) for y in range(len(shape)): for x in range(len(shape)): if shape[y][x]: surf.blit(self.block(self.next_tetromino.color), (x*self.blocksize, y*self.blocksize)) return surf
def render(self, surface: pg.Surface): surface.fill(BLACK) for object in self.objects.values(): pg.draw.lines(surface, WHITE, True, object) self.mask = pg.mask.from_threshold(surface, WHITE, (1, 1, 1, 255))
def render(self, target_surf: pygame.Surface, offset: Optional[List[int]] = None): """ The core rendering function that renders the lighting within the lightbox. The offset is used to specify the terrain offset (aka camera offset or scroll) of the game relative to the viewed area. The `target_surface` is the `pygame.Surface` that will have the lighting rendered onto it. If it is a black surface, you get the internal lighting mask. This can be useful for static lighting. However, normally the main display surface should be used. """ # avoid mutable default if offset is None: offset = [0, 0] assert isinstance(offset, list) # get the max light radius to determine which lights need to be rendered # if a light center is farther away from the viewing range than its radius, it's off the screen # if the light's modifications don't reach onto the screen, then its shadows won't have an effect, # so it's not necessary to process max_radius = self._get_max_light_radius() # define an updated render_box rect with respect to the terrain offset and the light range to determine which # walls needs to be processed render_box_r = pygame.Rect( -max_radius + offset[0], -max_radius + offset[1], self.vision_box_r.width + max_radius * 2, self.vision_box_r.height + max_radius * 2, ) # get all visible walls by using the chunk indexes valid_wall_dict = {} for y in range(self.vision_box_r.height // self.chunk_size + self.chunk_overshoot * 2 + 1): for x in range(self.vision_box_r.width // self.chunk_size + self.chunk_overshoot * 2 + 1): chunk_str = ( str(int(x - self.chunk_overshoot // 2 + offset[0] // self.chunk_size)) + ";" + str(int(y - self.chunk_overshoot // 2 + offset[1] // self.chunk_size)) ) if chunk_str in self.chunk_walls: valid_wall_dict.update(self.chunk_walls[chunk_str]) valid_walls = list(valid_wall_dict.values()) for group in self.dynamic_walls: valid_walls += self.dynamic_walls[group] # adjust for offset to get the "shown position" valid_walls = [ wall.clone_move([-offset[0], -offset[1]]) for wall in valid_walls if wall.rect.colliderect(render_box_r) ] # redefine the render_box rect with the terrain offset removed since the walls have been moved render_box_r = pygame.Rect( -max_radius, -max_radius, self.vision_box_r.width + max_radius * 2, self.vision_box_r.height + max_radius * 2, ) # generate a Surface to render the lighting mask onto rendered_mask = pygame.Surface(self.vision_box_r.size) # iterate through all of the lights for light in self.lights.values(): # apply the terrain offset light_pos = [light.position[0] - offset[0], light.position[1] - offset[1]] # check for visibility (don't forget that the current rect is adjusted for the radii of the lights) if render_box_r.collidepoint(light_pos): # apply lighting image light_instance_surf = light.light_img.copy() light_offset = [light_pos[0] - light.radius, light_pos[1] - light.radius] # draw over the light image with the shadows of each wall (the draw_shadow function only draws if # applicable, so a polygon isn't drawn every time) for wall in valid_walls: wall.draw_shadow(light_instance_surf, light_pos, render_box_r, (0, 0, 0), light_offset) # blit lighting mask onto main surface with RGBA_ADD so that the lighting can accumulate rendered_mask.blit(light_instance_surf, light_offset, special_flags=BLEND_RGBA_ADD) # update the light light.update() # blit the final lighting mask onto the target surface target_surf.blit(rendered_mask, (0, 0), special_flags=self.blit_flags) # return the list of visible walls in case they need to be used for anything return valid_walls
def main(self, screen): clock = pygame.time.Clock() background = Surface(screen.get_size()) background.blit(construct_nightmare(background.get_size()), (0,0)) self.matris = Matris() matris_border = Surface((MATRIX_WIDTH*BLOCKSIZE+BORDERWIDTH*2, VISIBLE_MATRIX_HEIGHT*BLOCKSIZE+BORDERWIDTH*2)) matris_border.fill(BORDERCOLOR) while 1: dt = clock.tick(45) self.matris.update((dt / 1000.) if not self.matris.paused else 0) if self.matris.gameover: return tricky_centerx = WIDTH-(WIDTH-(MATRIS_OFFSET+BLOCKSIZE*MATRIX_WIDTH+BORDERWIDTH*2))/2 background.blit(matris_border, (MATRIS_OFFSET,MATRIS_OFFSET)) background.blit(self.matris.surface, (MATRIS_OFFSET+BORDERWIDTH, MATRIS_OFFSET+BORDERWIDTH)) nextts = self.next_tetromino_surf(self.matris.surface_of_next_tetromino) background.blit(nextts, nextts.get_rect(top=MATRIS_OFFSET, centerx=tricky_centerx)) infos = self.info_surf() background.blit(infos, infos.get_rect(bottom=HEIGHT-MATRIS_OFFSET, centerx=tricky_centerx)) screen.blit(background, (0, 0)) pygame.display.flip()
class Image: def __init__(self, size=(0, 0), blend_flag=None, context=None): self.blend_flag = blend_flag self.surface = None self.paintSurface = None self.linkedImages = {} # linked images self.blitOrder = [] self.superImage = None #The parent image self.painters = {} if not context: self.contextData = Context() else: self.contextData = context self.contextData.init_context_vars({ "pos": (0, 0), "absolutePos": (0, 0), "size": size, "scroll": (0, 0) }) self.contextData.addContextListner("pos", self.onPosChange) self.contextData.addContextListner("size", self.onSizeChange) self.queReblit = True def getSuperImage(self): return self.superImage def getRootImage(self): if self.superImage: return self.superImage.getRootImage() return self def getDepth(self): if (self.superImage): return self.superImage.getDepth() + 1 return 0 def dumpRenderTree(self): depth = self.getDepth() for e in self.blitOrder: print(depth * "=", e) self.linkedImages[e].dumpRenderTree() def getContext(self): return self.contextData def getImageSize(self): return self.size def linkImage(self, imageID, image): if (image not in self.linkedImages): self.linkedImages[imageID] = image print(self.getDepth() * "~", self) if (imageID not in self.blitOrder): self.blitOrder += [imageID] image.superImage = self else: print("Image already linked, cannot link again") def unlinkImage(self, imageID): if (imageID in self.linkedImages): del self.linkedImages[imageID] self.blitOrder.remove(imageID) image.superImage = None else: print("Image not linked, cannot unlink") def getLinkedImage(self, imageID): if (imageID in self.linkedImages): return self.linkedImages[imageID] def addPainter(self, id, painter: Painter): self.painters[id] = painter painter.boundImage = self return painter def getPainter(self, id): if (id in self.painters): return self.painters[id] def onSizeChange(self, old, new): pass def removePainter(self, id): del self.painters[id] def create_image(self): try: self.surface = Surface(self.contextData.size).convert_alpha() self.surface.fill((0, 0, 0, 0)) self.paintSurface = self.surface.copy() except ValueError as e: print(self.contextData.size) raise e def getSurface(self): if (self.contextData.hasChanged): self.contextData.clearChange() return self.surface def blitLayers(self): if not (pygame.display.get_init()): return if not (self.queReblit): return #depth = self.getDepth() #print("-"*depth,"blitting: ",self) if not (self.surface): self.create_image() self.surface.fill((0, 0, 0, 0)) self.surface.blit(self.paintSurface, (0, 0)) for e in self.blitOrder: img = self.linkedImages[e] if (img.getSurface()): self.surface.blit(img.getSurface(), img.getContext().absolutePos) self.queReblit = False def applyPainters(self): #depth = self.getDepth() #print("-"*depth,"painting: ",self) self.paintSurface.fill((0, 0, 0, 0)) for i, e in self.painters.items(): #print("-"*(depth+1),"painter: ",i) e.apply(self.paintSurface) def onPosChange(self, old, new): self.reblit() pass def reblit(self): self.queReblit = True if (self.superImage): self.superImage.reblit() def repaint(self): #print("repaint", self) if not (self.surface): return self.applyPainters() self.reblit() pass def render(self): if not (pygame.display.get_init()): return #depth = self.getDepth() #print("-"*depth,"rendering: ",self.contextData) self.create_image() self.applyPainters() for e, i in self.linkedImages.items(): i.render() self.blitLayers() def maintain(self): for e, i in self.linkedImages.items(): if (i.queReblit): i.maintain() self.blitLayers()
def reset_screen(self, screen: pygame.Surface): """Shows a screen containing only a grid of blocks""" screen.fill(Colors.BLACK) self.display_borders(screen)