def __draw_bar(self, camera, arg_rect, fraction, col_back, col_0, col_1): """ Draw a progress bar """ # The background self.__renderer.add_job_rect(arg_rect, colour=col_back, coords=Renderer.COORDS_SCREEN, level=Renderer.LEVEL_FORE, brightness=0.2) # The empty portion. rect = Rect(arg_rect) rect.inflate_ip(-4, -4) self.__renderer.add_job_rect(rect, colour=col_0, coords=Renderer.COORDS_SCREEN, level=Renderer.LEVEL_FORE, brightness=0.2) # The full portion. rect.width = int(fraction * rect.width) self.__renderer.add_job_rect(rect, colour=col_1, coords=Renderer.COORDS_SCREEN, level=Renderer.LEVEL_FORE, brightness=0.2)
def hscrollbar_rect(self): # Get the distance between the scroll buttons (d) slr, slt = self.scroll_left_rect().topright d = self.scroll_right_rect().left - slr # The predefined step value _s = self.cell_size[1] # Get the total step number n = float(self.virtual_width) / _s # Get the visible step number v = float(self.width) / _s s = float(d) / n w = s * v if isinstance(w, float): if w - int(w) > 0: w += 1 left = max( slr, slr + (d * (float(self.hscroll) / self.virtual_width)) + self.hscroll_rel) r = Rect(left, slt, w, self.scroll_button_size) r.right = min(r.right, d + slr) r.inflate_ip(-4, -4) if r.w < 1: r.w = int(w) return r
def scrollbar_rect(self): # Get the distance between the scroll buttons (d) sub = self.scroll_up_rect().bottom t = self.scroll_down_rect().top d = t - sub # Get the total row number (n). n = self.num_items() / getattr(getattr(self, 'parent', None), 'num_cols', lambda: 1)() # Get the displayed row number (v) v = self.num_rows() if n: s = float(d) / n else: s = 0 h = s * v if type(h) == float: if h - int(h) > 0: h += 1 top = max(sub, sub + (s * self.scroll) + self.scroll_rel) r = Rect(0, top, self.scroll_button_size, h) m = self.margin r.right = self.width - m r.bottom = min(r.bottom, t) r.inflate_ip(-4, -4) if r.h < 1: r.h = int(h) return r
def scroll_left_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.bottom = self.height - m r.left = m r.inflate_ip(-4, -4) return r
def scroll_down_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.bottom = self.height - m r.right = self.width - m r.inflate_ip(-4, -4) return r
def scroll_up_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.top = m r.right = self.width - m r.inflate_ip(-4, -4) return r
def get_margin_rect(self) -> Rect: """ Returns a Rect in local coordinates representing the content area of the widget, as determined by its margin property. Returns: The rect of the content area """ r = Rect((0, 0), self.size) d = -2 * self.margin r.inflate_ip(d, d) return r
class ThrowedGrenade(Bullet): def __init__(self, creator, x, y, speedX, speedY, throwDistance): Bullet.__init__(self, creator, x, y, speedX, speedY, "items-1small.png", None, Rect(110, 120, 9, 11)) self.rect = Rect(x, y, 0, 0) self.speedX = speedX self.speedY = speedY # Important if you want pinpoint accuracy self.floatX = float(self.rect.x) self.floatY = float(self.rect.y) if throwDistance > MAX_THROW_DISTANCE: throwDistance = MAX_THROW_DISTANCE self.timeToStop = throwDistance / GRENADE_SPEED self.timeToBoom = TIME_TO_BOOM self.atk = 70 def update(self, time, scene): self.floatX += self.speedX * time * GRENADE_SPEED self.floatY += self.speedY * time * GRENADE_SPEED self.rect.x = roundToInt(self.floatX) self.rect.y = roundToInt(self.floatY) self.timeToBoom -= time if self.timeToBoom <= 0: scene.bulletGroup.remove(self) scene.bulletGroup.add(Explosion(self.rect.x, self.rect.y)) # Kill people! originalRect = self.rect.copy() self.rect.inflate_ip(80, 80) # 80x80 area damage enemies_hit = sprite.spritecollide(self, scene.enemyGroup, False) for enemy in enemies_hit: # Friendly fire if self.creator.__class__.__name__ == enemy.__class__.__name__: continue enemy.receive_attack(self.atk) if sprite.collide_rect(self, scene.player): scene.player.receive_attack(self.atk) self.rect = originalRect # Restore the real rect self.timeToStop -= time if self.timeToStop <= 0: self.speedX = 0 self.speedY = 0
class ThrowedGrenade(Bullet): def __init__(self,creator, x, y, speedX, speedY, throwDistance): Bullet.__init__(self, creator, x, y, speedX, speedY, "items-1small.png", None, Rect(110, 120, 9, 11)) self.rect = Rect(x, y, 0, 0) self.speedX = speedX self.speedY = speedY # Important if you want pinpoint accuracy self.floatX = float(self.rect.x) self.floatY = float(self.rect.y) if throwDistance > MAX_THROW_DISTANCE: throwDistance = MAX_THROW_DISTANCE self.timeToStop = throwDistance / GRENADE_SPEED self.timeToBoom = TIME_TO_BOOM self.atk = 70 def update(self, time, scene): self.floatX += self.speedX * time * GRENADE_SPEED self.floatY += self.speedY * time * GRENADE_SPEED self.rect.x = roundToInt(self.floatX) self.rect.y = roundToInt(self.floatY) self.timeToBoom -= time if self.timeToBoom <= 0: scene.bulletGroup.remove(self) scene.bulletGroup.add(Explosion(self.rect.x, self.rect.y)) # Kill people! originalRect = self.rect.copy() self.rect.inflate_ip(80, 80) # 80x80 area damage enemies_hit = sprite.spritecollide(self, scene.enemyGroup, False) for enemy in enemies_hit: # Friendly fire if self.creator.__class__.__name__ == enemy.__class__.__name__: continue enemy.receive_attack(self.atk) if sprite.collide_rect(self, scene.player): scene.player.receive_attack(self.atk) self.rect = originalRect # Restore the real rect self.timeToStop -= time if self.timeToStop <= 0: self.speedX = 0 self.speedY = 0
def test_inflate_ip__smaller( self ): "The inflate method inflates around the center of the rectangle" r = Rect( 2, 4, 6, 8 ) r2 = Rect( r ) r2.inflate_ip( -4, -6 ) self.assertEqual( r.center, r2.center ) self.assertEqual( r.left+2, r2.left ) self.assertEqual( r.top+3, r2.top ) self.assertEqual( r.right-2, r2.right ) self.assertEqual( r.bottom-3, r2.bottom ) self.assertEqual( r.width-4, r2.width ) self.assertEqual( r.height-6, r2.height )
def test_inflate_ip__smaller(self): "The inflate method inflates around the center of the rectangle" r = Rect(2, 4, 6, 8) r2 = Rect(r) r2.inflate_ip(-4, -6) self.assertEqual(r.center, r2.center) self.assertEqual(r.left + 2, r2.left) self.assertEqual(r.top + 3, r2.top) self.assertEqual(r.right - 2, r2.right) self.assertEqual(r.bottom - 3, r2.bottom) self.assertEqual(r.width - 4, r2.width) self.assertEqual(r.height - 6, r2.height)
def _DrawTextLines(self, lines): linepadding =1 textlines = [] totalrect = Rect(0,0,0,0) for line in lines: text = self.font.render(line, 1, (255,255,255)) rect = text.get_rect() totalrect.inflate_ip(0, rect.height + linepadding) if rect.width > totalrect.width: totalrect.width = rect.width textlines.append(text) textsurf = Surface(totalrect.size, pygame.SRCALPHA) topoffset = 0 for linesurf in textlines: textsurf.blit(linesurf,(0,topoffset)) topoffset += linesurf.get_rect().height return textsurf
def _DrawTextLines(self, lines): linepadding = 1 textlines = [] totalrect = Rect(0, 0, 0, 0) for line in lines: text = self.font.render(line, 1, (255, 255, 255)) rect = text.get_rect() totalrect.inflate_ip(0, rect.height + linepadding) if rect.width > totalrect.width: totalrect.width = rect.width textlines.append(text) textsurf = Surface(totalrect.size, pygame.SRCALPHA) topoffset = 0 for linesurf in textlines: textsurf.blit(linesurf, (0, topoffset)) topoffset += linesurf.get_rect().height return textsurf
def hscrollbar_rect(self): # Get the distance between the scroll buttons (d) slr, slt = self.scroll_left_rect().topright d = self.scroll_right_rect().left - slr # The predefined step value _s = self.cell_size[1] # Get the total step number n = float(self.virtual_width) / _s # Get the visible step number v = float(self.width) / _s s = float(d) / n w = s * v if type(w) == float: if w - int(w) > 0: w += 1 left = max(slr, slr + (d * (float(self.hscroll) / self.virtual_width)) + self.hscroll_rel) r = Rect(left, slt, w, self.scroll_button_size) r.right = min(r.right, d + slr) r.inflate_ip(-4, -4) return r
def get_bullet_rect(self, surf, lvl): r = Rect(0, 0, self.bullet_size, self.bullet_size) r.left = self.bullet_size * lvl r.inflate_ip(-4, -4) return r
def inflate_ip(self, x, y): Rect.inflate_ip(self, x, y) self.ring = geo.Polygon([(self.left, self.top), (self.left + self.w, self.top), (self.left + self.w, self.top + self.h), (self.left, self.top + self.h)])
class Entity(Paintable, Updateable): entityBehaviors = Personality() attributes = Genotype() def __init__(self, world, family = None, position = None): if position == None: offsets = (int(dimension/5.0) for dimension in RESOLUTION) position = tuple(randint(offset, dimension - offset) for offset, dimension in zip(offsets, RESOLUTION)) Paintable.__init__(self, position) self.boundingBox = Rect(position, self.attributes.dimensions) self.age = 0 self.health = self.attributes.health self.growthFactor = self.attributes.growthFactor self.carriedEntity = None self.beingCarried = False if family: self.family = family else: self.family = Family(world) self.family.boundingBox = self.boundingBox # self.family.addMember(self) # self.behavior = ComplexBehavior(self, world) world.register(self) def getSpecies(self): return self.__class__.__name__ def getFamily(self): return self.family def getDimensions(self): return [self.boundingBox.w, self.boundingBox.h] def getPosition(self): return self.boundingBox.center def getStride(self): return round(self.getDimensions()[0] / 2.) def isCarryingEntity(self, type = None): if type: return self.carriedEntity.__class__ == type else: return self.carriedEntity != None def paint(self, screen): draw.rect(screen, self.attributes.color, self.boundingBox) def update(self, delay, world): if self.__class__.entityBehaviors: for behavior in self.__class__.entityBehaviors: behavior.do(self, world) self.age += 1 def grow(self, growthArea): growthFactor = self.growthFactor self.boundingBox.inflate_ip(growthArea[0] * growthFactor, growthArea[1] * growthFactor) gain = growthArea[0] * growthArea[1] # print 'Gained %s health' % gain self.health += gain def carryEntity(self, entity): entity.beingCarried = True self.carriedEntity = entity def dropEntity(self): if self.carriedEntity: self.carriedEntity.beingCarried = False self.carriedEntity = None def hasBehavior(self, behavior): return self.behavior in behavior def addBehavior(self, behavior): # self.behavior.add(behavior) pass def removeBehavior(self, behavior): # self.behavior.removeBehavior(behavior) pass def __str__(self): return '%s (%s, %s)' % (self.__class__.__name__, self.boundingBox.x, self.boundingBox.y)
def get_margin_rect(self): r = Rect((0, 0), self.size) d = -2 * self.margin r.inflate_ip(d, d) return r
def get_tile_images_by_rect( self, rect: pygame.Rect ) -> Iterator[Tuple[int, int, int, pygame.surface.Surface]]: """ Speed up data access More efficient because data is accessed and cached locally """ x1, y1, x2, y2 = pyscroll.common.rect_to_bb(rect) images = self.tmx.images layers = self.tmx.layers at = self._animated_tile tracked_gids = self._tracked_gids anim_map = self._animation_map track = bool(self._animation_queue) for l in self.visible_tile_layers: if l not in self.base_tile_layers: l -= self.overlay_layer_offset if not isinstance(layers[l], pytmx.pytmx.TiledTileLayer): continue for y in range(y1, y2 + 1): row = layers[l].data[min(max(0, y - self.image_pad_tiles[1]), self.tmx.height - 1)] for x in range(x1, x2 + 1): gid = row[min(max(0, x - self.image_pad_tiles[0]), self.tmx.width - 1)] if not gid: continue if self.object_group_to_bound_rendering is not None: render_tile = False for obj in self.tmx.layers[ self.object_group_to_bound_rendering]: rect = pygame.Rect( obj.x / self.tmx.tilewidth, obj.y / self.tmx.tileheight, obj.width / self.tmx.tilewidth, obj.height / self.tmx.tileheight) rect.inflate_ip(2, 2) if rect.collidepoint(x - self.image_pad_tiles[0], y - self.image_pad_tiles[1]): render_tile = True break if not render_tile: yield x, y, l, images[-1] continue if track and gid in tracked_gids: anim_map[gid].positions.add((x, y, l)) try: # animated, so return the correct frame yield x, y, l, at[(x, y, l)] except KeyError: # not animated, so return surface from data, if any yield x, y, l, images[gid]