Example #1
0
    def draw_ellipse(self,
                     x,
                     y,
                     width,
                     height,
                     fill=None,
                     outline=None,
                     outline_thickness=1,
                     anti_alias=False,
                     frame=None):
        """Draw an ellipse on the sprite.

        Arguments:

        - ``x`` -- The horizontal location relative to the sprite to
          position the imaginary rectangle containing the ellipse.
        - ``y`` -- The vertical location relative to the sprite to
          position the imaginary rectangle containing the ellipse.
        - ``width`` -- The width of the ellipse.
        - ``height`` -- The height of the ellipse.
        - ``fill`` -- The color of the fill of the ellipse.
        - ``outline`` -- The color of the outline of the ellipse.
        - ``outline_thickness`` -- The thickness of the outline of the
          ellipse.
        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        outline_thickness = abs(outline_thickness)
        if outline_thickness == 0:
            outline = None

        if fill is None and outline is None:
            # There's no point in trying in this case.
            return

        rect = pygame.Rect(x, y, width, height)

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if fill is not None:
                    c = sge._get_pygame_color(fill)
                    pygame.draw.ellipse(self._baseimages[i], c, rect)

                if outline is not None:
                    c = sge._get_pygame_color(outline)
                    pygame.draw.ellipse(self._baseimages[i], c, rect,
                                        outline_thickness)

        self._refresh()
Example #2
0
    def draw_rectangle(self,
                       x,
                       y,
                       width,
                       height,
                       fill=None,
                       outline=None,
                       outline_thickness=1,
                       frame=None):
        """Draw a rectangle on the sprite.

        Arguments:

        - ``x`` -- The horizontal location relative to the sprite to
          draw the rectangle.
        - ``y`` -- The vertical location relative to the sprite to draw
          the rectangle.
        - ``width`` -- The width of the rectangle.
        - ``height`` -- The height of the rectangle.
        - ``fill`` -- The color of the fill of the rectangle.
        - ``outline`` -- The color of the outline of the rectangle.
        - ``outline_thickness`` -- The thickness of the outline of the
          rectangle.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        outline_thickness = abs(outline_thickness)
        if outline_thickness == 0:
            outline = None

        if fill is None and outline is None:
            # There's no point in trying in this case.
            return

        rect = pygame.Rect(x, y, width, height)

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if fill is not None:
                    pygame.draw.rect(self._baseimages[i],
                                     sge._get_pygame_color(fill), rect, 0)

                if outline is not None:
                    pygame.draw.rect(self._baseimages[i],
                                     sge._get_pygame_color(outline), rect,
                                     outline_thickness)

        self._refresh()
Example #3
0
    def draw_circle(self,
                    x,
                    y,
                    radius,
                    fill=None,
                    outline=None,
                    outline_thickness=1,
                    anti_alias=False,
                    frame=None):
        """Draw a circle on the sprite.

        Arguments:

        - ``x`` -- The horizontal location relative to the sprite to
          position the center of the circle.
        - ``y`` -- The vertical location relative to the sprite to
          position the center of the circle.
        - ``radius`` -- The radius of the circle.
        - ``fill`` -- The color of the fill of the circle.
        - ``outline`` -- The color of the outline of the circle.
        - ``outline_thickness`` -- The thickness of the outline of the
          circle.
        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        outline_thickness = abs(outline_thickness)
        if outline_thickness == 0:
            outline = None

        if fill is None and outline is None:
            # There's no point in trying in this case.
            return

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if fill is not None:
                    c = sge._get_pygame_color(fill)
                    pygame.draw.circle(self._baseimages[i], c, (x, y), radius)

                if outline is not None:
                    c = sge._get_pygame_color(outline)
                    pygame.draw.circle(self._baseimages[i], c, (x, y), radius,
                                       outline_thickness)

        self._refresh()
    def _get_image(self, num, xscale=1, yscale=1, rotation=0, alpha=255, blend=None):
        num %= len(self._images)
        # Return the properly sized surface.
        if (xscale, yscale, rotation, alpha, blend) in self._images[num]:
            return self._images[num][(xscale, yscale, rotation, alpha, blend)]
        else:
            # Hasn't been scaled to this size yet
            if xscale != 0 and yscale != 0:
                img = self._set_transparency(self._baseimages[num])
                xflip = xscale < 0
                yflip = yscale < 0
                img = pygame.transform.flip(img, xflip, yflip)
                img = sge._scale(img, self.width * abs(xscale), self.height * abs(yscale))

                if rotation != 0:
                    img = pygame.transform.rotate(img, rotation)

                if alpha < 255:
                    if img.get_flags() & pygame.SRCALPHA:
                        # Have to do this the more difficult way.
                        img.fill((0, 0, 0, 255 - alpha), None, pygame.BLEND_RGBA_SUB)
                    else:
                        img.set_alpha(alpha, pygame.RLEACCEL)

                if blend is not None:
                    img.fill(sge._get_pygame_color(blend), None, pygame.BLEND_RGB_MULT)
            else:
                img = pygame.Surface((1, 1))
                img.set_colorkey((0, 0, 0), pygame.RLEACCEL)

            self._images[num][(xscale, yscale, rotation, alpha, blend)] = img
            return img
    def draw_line(self, x1, y1, x2, y2, color, thickness=1, anti_alias=False, frame=None):
        """Draw a line segment on the sprite.

        Arguments:

        - ``x1`` -- The horizontal location relative to the sprite of
          the first end point of the line segment.
        - ``y1`` -- The vertical location relative to the sprite of the
          first end point of the line segment.
        - ``x2`` -- The horizontal location relative to the sprite of
          the second end point of the line segment.
        - ``y2`` -- The vertical location relative to the sprite of the
          second end point of the line segment.
        - ``color`` -- The color of the line segment.
        - ``thickness`` -- The thickness of the line segment.
        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        color = sge._get_pygame_color(color)
        thickness = abs(thickness)

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if anti_alias and thickness == 1:
                    pygame.draw.aaline(self._baseimages[i], color, (x1, y1), (x2, y2))
                else:
                    pygame.draw.line(self._baseimages[i], color, (x1, y1), (x2, y2), thickness)

        self._refresh()
    def draw_ellipse(
        self, x, y, width, height, fill=None, outline=None, outline_thickness=1, anti_alias=False, frame=None
    ):
        """Draw an ellipse on the sprite.

        Arguments:

        - ``x`` -- The horizontal location relative to the sprite to
          position the imaginary rectangle containing the ellipse.
        - ``y`` -- The vertical location relative to the sprite to
          position the imaginary rectangle containing the ellipse.
        - ``width`` -- The width of the ellipse.
        - ``height`` -- The height of the ellipse.
        - ``fill`` -- The color of the fill of the ellipse.
        - ``outline`` -- The color of the outline of the ellipse.
        - ``outline_thickness`` -- The thickness of the outline of the
          ellipse.
        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        outline_thickness = abs(outline_thickness)
        if outline_thickness == 0:
            outline = None

        if fill is None and outline is None:
            # There's no point in trying in this case.
            return

        rect = pygame.Rect(x, y, width, height)

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if fill is not None:
                    c = sge._get_pygame_color(fill)
                    pygame.draw.ellipse(self._baseimages[i], c, rect)

                if outline is not None:
                    c = sge._get_pygame_color(outline)
                    pygame.draw.ellipse(self._baseimages[i], c, rect, outline_thickness)

        self._refresh()
Example #7
0
    def draw_rectangle(self, x, y, width, height, fill=None, outline=None,
                       outline_thickness=1, frame=None):
        """Draw a rectangle on the sprite.

        Arguments:
        - ``x`` -- The horizontal location relative to the sprite to
          draw the rectangle.
        - ``y`` -- The vertical location relative to the sprite to draw
          the rectangle.
        - ``width`` -- The width of the rectangle.
        - ``height`` -- The height of the rectangle.
        - ``fill`` -- The color of the fill of the rectangle.
        - ``outline`` -- The color of the outline of the rectangle.
        - ``outline_thickness`` -- The thickness of the outline of the
          rectangle.
        - ``frame`` -- The frame of the sprite to draw on, where 0 is
          the first frame; set to None to draw on all frames.

        """
        outline_thickness = abs(outline_thickness)
        if outline_thickness == 0:
            outline = None

        if fill is None and outline is None:
            # There's no point in trying in this case.
            return

        rect = pygame.Rect(x, y, width, height)

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if fill is not None:
                    pygame.draw.rect(self._baseimages[i],
                                     sge._get_pygame_color(fill), rect, 0)

                if outline is not None:
                    pygame.draw.rect(self._baseimages[i],
                                     sge._get_pygame_color(outline), rect,
                                     outline_thickness)

        self._refresh()
    def draw_circle(self, x, y, radius, fill=None, outline=None, outline_thickness=1, anti_alias=False, frame=None):
        """Draw a circle on the sprite.

        Arguments:

        - ``x`` -- The horizontal location relative to the sprite to
          position the center of the circle.
        - ``y`` -- The vertical location relative to the sprite to
          position the center of the circle.
        - ``radius`` -- The radius of the circle.
        - ``fill`` -- The color of the fill of the circle.
        - ``outline`` -- The color of the outline of the circle.
        - ``outline_thickness`` -- The thickness of the outline of the
          circle.
        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        outline_thickness = abs(outline_thickness)
        if outline_thickness == 0:
            outline = None

        if fill is None and outline is None:
            # There's no point in trying in this case.
            return

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if fill is not None:
                    c = sge._get_pygame_color(fill)
                    pygame.draw.circle(self._baseimages[i], c, (x, y), radius)

                if outline is not None:
                    c = sge._get_pygame_color(outline)
                    pygame.draw.circle(self._baseimages[i], c, (x, y), radius, outline_thickness)

        self._refresh()
Example #9
0
    def draw_dot(self, x, y, color, frame=None):
        """Draw a single-pixel dot on the sprite.

        Arguments:
        - ``x`` -- The horizontal location relative to the sprite to
          draw the dot.
        - ``y`` -- The vertical location relative to the sprite to draw
          the dot.
        - ``color`` -- The color of the dot.
        - ``frame`` -- The frame of the sprite to draw on, where 0 is
          the first frame; set to None to draw on all frames.

        """
        color = sge._get_pygame_color(color)
        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                self._baseimages[i].set_at((x, y), color)

        self._refresh()
Example #10
0
    def draw_line(self,
                  x1,
                  y1,
                  x2,
                  y2,
                  color,
                  thickness=1,
                  anti_alias=False,
                  frame=None):
        """Draw a line segment on the sprite.

        Arguments:

        - ``x1`` -- The horizontal location relative to the sprite of
          the first end point of the line segment.
        - ``y1`` -- The vertical location relative to the sprite of the
          first end point of the line segment.
        - ``x2`` -- The horizontal location relative to the sprite of
          the second end point of the line segment.
        - ``y2`` -- The vertical location relative to the sprite of the
          second end point of the line segment.
        - ``color`` -- The color of the line segment.
        - ``thickness`` -- The thickness of the line segment.
        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        color = sge._get_pygame_color(color)
        thickness = abs(thickness)

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                if anti_alias and thickness == 1:
                    pygame.draw.aaline(self._baseimages[i], color, (x1, y1),
                                       (x2, y2))
                else:
                    pygame.draw.line(self._baseimages[i], color, (x1, y1),
                                     (x2, y2), thickness)

        self._refresh()
Example #11
0
    def _get_image(self,
                   num,
                   xscale=1,
                   yscale=1,
                   rotation=0,
                   alpha=255,
                   blend=None):
        num %= len(self._images)
        # Return the properly sized surface.
        if (xscale, yscale, rotation, alpha, blend) in self._images[num]:
            return self._images[num][(xscale, yscale, rotation, alpha, blend)]
        else:
            # Hasn't been scaled to this size yet
            if xscale != 0 and yscale != 0:
                img = self._set_transparency(self._baseimages[num])
                xflip = xscale < 0
                yflip = yscale < 0
                img = pygame.transform.flip(img, xflip, yflip)
                img = sge._scale(img, self.width * abs(xscale),
                                 self.height * abs(yscale))

                if rotation != 0:
                    img = pygame.transform.rotate(img, rotation)

                if alpha < 255:
                    if img.get_flags() & pygame.SRCALPHA:
                        # Have to do this the more difficult way.
                        img.fill((0, 0, 0, 255 - alpha), None,
                                 pygame.BLEND_RGBA_SUB)
                    else:
                        img.set_alpha(alpha, pygame.RLEACCEL)

                if blend is not None:
                    img.fill(sge._get_pygame_color(blend), None,
                             pygame.BLEND_RGB_MULT)
            else:
                img = pygame.Surface((1, 1))
                img.set_colorkey((0, 0, 0), pygame.RLEACCEL)

            self._images[num][(xscale, yscale, rotation, alpha, blend)] = img
            return img
Example #12
0
    def draw_dot(self, x, y, color, frame=None):
        """Draw a single-pixel dot on the sprite.

        Arguments:

        - ``x`` -- The horizontal location relative to the sprite to
          draw the dot.
        - ``y`` -- The vertical location relative to the sprite to draw
          the dot.
        - ``color`` -- The color of the dot.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        color = sge._get_pygame_color(color)
        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                self._baseimages[i].set_at((x, y), color)

        self._refresh()
Example #13
0
    def draw_text(
        self,
        font,
        text,
        x,
        y,
        width=None,
        height=None,
        color="black",
        halign=sge.ALIGN_LEFT,
        valign=sge.ALIGN_TOP,
        anti_alias=True,
        frame=None,
    ):
        """Draw text on the sprite.

        Arguments:

        - ``font`` -- The font to use to draw the text.
        - ``text`` -- The text (as a string) to draw.
        - ``x`` -- The horizontal location relative to the sprite to
          draw the text.
        - ``y`` -- The vertical location relative to the sprite to draw
          the text.
        - ``width`` -- The width of the imaginary rectangle the text is
          drawn in; set to :const:`None` to make the rectangle as wide
          as needed to contain the text without additional line breaks.
          If set to something other than :const:`None`, a line which
          does not fit will be automatically split into multiple lines
          that do fit.
        - ``height`` -- The height of the imaginary rectangle the text
          is drawn in; set to :const:`None` to make the rectangle as
          tall as needed to contain the text.
        - ``color`` -- The color of the text.
        - ``halign`` -- The horizontal alignment of the text and the
          horizontal location of the origin of the imaginary rectangle
          the text is drawn in.  Can be set to one of the following:

          - :data:`sge.ALIGN_LEFT` -- Align the text to the left of the
            imaginary rectangle the text is drawn in.  Set the origin of
            the imaginary rectangle to its left edge.
          - :data:`sge.ALIGN_CENTER` -- Align the text to the center of
            the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its center.
          - :data:`sge.ALIGN_RIGHT` -- Align the text to the right of
            the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its right edge.

        - ``valign`` -- The vertical alignment of the text and the
          vertical location of the origin of the imaginary rectangle the
          text is drawn in.  Can be set to one of the following:

          - :data:`sge.ALIGN_TOP` -- Align the text to the top of the
            imaginary rectangle the text is drawn in.  Set the origin of
            the imaginary rectangle to its top edge.  If the imaginary
            rectangle is not tall enough to contain all of the text, cut
            text off from the bottom.
          - :data:`sge.ALIGN_MIDDLE` -- Align the the text to the middle
            of the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its middle.  If the
            imaginary rectangle is not tall enough to contain all of the
            text, cut text off equally from the top and bottom.
          - :data:`sge.ALIGN_BOTTOM` -- Align the text  to the bottom of
            the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its top edge.  If the
            imaginary rectangle is not tall enough to contain all of the
            text, cut text off from the top.

        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        if not isinstance(font, sge.Font):
            font = sge.game.fonts[font]

        lines = font._split_text(text, width)
        width, height = font.get_size(text, width, height)
        fake_height = font.get_size(text, width)[1]
        color = sge._get_pygame_color(color)

        text_surf = pygame.Surface((width, fake_height), pygame.SRCALPHA)
        box_surf = pygame.Surface((width, height), pygame.SRCALPHA)
        text_rect = text_surf.get_rect()
        box_rect = box_surf.get_rect()

        for i in xrange(len(lines)):
            rendered_text = font._font.render(lines[i], anti_alias, color)
            rect = rendered_text.get_rect()
            rect.top = i * font._font.get_linesize()

            if halign == sge.ALIGN_LEFT:
                rect.left = text_rect.left
            elif halign == sge.ALIGN_RIGHT:
                rect.right = text_rect.right
            elif halign == sge.ALIGN_CENTER:
                rect.centerx = text_rect.centerx

            text_surf.blit(rendered_text, rect)

        if valign == sge.ALIGN_TOP:
            text_rect.top = box_rect.top
        elif valign == sge.ALIGN_BOTTOM:
            text_rect.bottom = box_rect.bottom
        elif valign == sge.ALIGN_MIDDLE:
            text_rect.centery = box_rect.centery

        box_surf.blit(text_surf, text_rect)

        if halign == sge.ALIGN_LEFT:
            box_rect.left = x
        elif halign == sge.ALIGN_RIGHT:
            box_rect.right = x
        elif halign == sge.ALIGN_CENTER:
            box_rect.centerx = x
        else:
            box_rect.left = x

        if valign == sge.ALIGN_TOP:
            box_rect.top = y
        elif valign == sge.ALIGN_BOTTOM:
            box_rect.bottom = y
        elif valign == sge.ALIGN_MIDDLE:
            box_rect.centery = y
        else:
            box_rect.top = y

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                self._baseimages[i].blit(box_surf, box_rect)

        self._refresh()
    def _get_background(self):
        # Return the static background this frame.
        background = pygame.Surface((round(sge.game.width * sge.game._xscale),
                                     round(sge.game.height * sge.game._yscale)))
        background.fill(sge._get_pygame_color(self.color))

        for view in sge.game.current_room.views:
            view_x = int(round(view.x * sge.game._xscale))
            view_y = int(round(view.y * sge.game._yscale))
            view_xport = max(0, min(int(round(view.xport * sge.game._xscale)),
                                    background.get_width() - 1))
            view_yport = max(0, min(int(round(view.yport * sge.game._yscale)),
                                    background.get_height() - 1))
            view_w = min(view.width * sge.game._xscale,
                         background.get_width() - view_xport)
            view_h = min(view.height * sge.game._yscale,
                         background.get_height() - view_yport)
            surf = background.subsurface(view_xport, view_yport, view_w,
                                         view_h)
            for layer in self.layers:
                image = layer._get_image()
                x = int(round(
                    (sge.game.current_room.background_x + layer.x -
                     (view.x * layer.xscroll_rate)) *
                    sge.game._xscale))
                y = int(round(
                    (sge.game.current_room.background_y + layer.y -
                     (view.y * layer.yscroll_rate)) *
                    sge.game._yscale))
                image_w = max(1, image.get_width())
                image_h = max(1, image.get_height())

                # These equations bring the position to the largest
                # values possible while still being less than the
                # location we're getting the surface at.  This is to
                # minimize the number of repeat blittings.
                if layer.xrepeat:
                    x = (x % image_w) - image_w
                if layer.yrepeat:
                    y = (y % image_h) - image_h

                # Apply the origin so the positions are as expected.
                x -= int(round(layer.sprite.origin_x * sge.game._xscale))
                y -= int(round(layer.sprite.origin_y * sge.game._yscale))

                if layer.xrepeat and layer.yrepeat:
                    xstart = x
                    while y < surf.get_height():
                        x = xstart
                        while x < surf.get_width():
                            surf.blit(image, (x, y))
                            x += image_w
                        y += image_h
                elif (layer.xrepeat and y < view_y + view_h and
                      y + image_h > view_y):
                    while x < surf.get_width():
                        surf.blit(image, (x, y))
                        x += image_w
                elif (layer.yrepeat and x < view_x + view_w and
                      x + image_w > view_x):
                    while y < surf.get_height():
                        surf.blit(image, (x, y))
                        y += image_h
                elif (x < surf.get_width() and x + image_w > 0 and
                      y < surf.get_height() and y + image_h > 0):
                    surf.blit(image, (x, y))

        return background
Example #15
0
    def draw_text(self,
                  font,
                  text,
                  x,
                  y,
                  width=None,
                  height=None,
                  color="black",
                  halign=sge.ALIGN_LEFT,
                  valign=sge.ALIGN_TOP,
                  anti_alias=True,
                  frame=None):
        """Draw text on the sprite.

        Arguments:

        - ``font`` -- The font to use to draw the text.
        - ``text`` -- The text (as a string) to draw.
        - ``x`` -- The horizontal location relative to the sprite to
          draw the text.
        - ``y`` -- The vertical location relative to the sprite to draw
          the text.
        - ``width`` -- The width of the imaginary rectangle the text is
          drawn in; set to :const:`None` to make the rectangle as wide
          as needed to contain the text without additional line breaks.
          If set to something other than :const:`None`, a line which
          does not fit will be automatically split into multiple lines
          that do fit.
        - ``height`` -- The height of the imaginary rectangle the text
          is drawn in; set to :const:`None` to make the rectangle as
          tall as needed to contain the text.
        - ``color`` -- The color of the text.
        - ``halign`` -- The horizontal alignment of the text and the
          horizontal location of the origin of the imaginary rectangle
          the text is drawn in.  Can be set to one of the following:

          - :data:`sge.ALIGN_LEFT` -- Align the text to the left of the
            imaginary rectangle the text is drawn in.  Set the origin of
            the imaginary rectangle to its left edge.
          - :data:`sge.ALIGN_CENTER` -- Align the text to the center of
            the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its center.
          - :data:`sge.ALIGN_RIGHT` -- Align the text to the right of
            the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its right edge.

        - ``valign`` -- The vertical alignment of the text and the
          vertical location of the origin of the imaginary rectangle the
          text is drawn in.  Can be set to one of the following:

          - :data:`sge.ALIGN_TOP` -- Align the text to the top of the
            imaginary rectangle the text is drawn in.  Set the origin of
            the imaginary rectangle to its top edge.  If the imaginary
            rectangle is not tall enough to contain all of the text, cut
            text off from the bottom.
          - :data:`sge.ALIGN_MIDDLE` -- Align the the text to the middle
            of the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its middle.  If the
            imaginary rectangle is not tall enough to contain all of the
            text, cut text off equally from the top and bottom.
          - :data:`sge.ALIGN_BOTTOM` -- Align the text  to the bottom of
            the imaginary rectangle the text is drawn in.  Set the
            origin of the imaginary rectangle to its top edge.  If the
            imaginary rectangle is not tall enough to contain all of the
            text, cut text off from the top.

        - ``anti_alias`` -- Whether or not anti-aliasing should be used.
        - ``frame`` -- The frame of the sprite to draw on, where ``0``
          is the first frame; set to :const:`None` to draw on all
          frames.

        """
        if not isinstance(font, sge.Font):
            font = sge.game.fonts[font]

        lines = font._split_text(text, width)
        width, height = font.get_size(text, width, height)
        fake_height = font.get_size(text, width)[1]
        color = sge._get_pygame_color(color)

        text_surf = pygame.Surface((width, fake_height), pygame.SRCALPHA)
        box_surf = pygame.Surface((width, height), pygame.SRCALPHA)
        text_rect = text_surf.get_rect()
        box_rect = box_surf.get_rect()

        for i in xrange(len(lines)):
            rendered_text = font._font.render(lines[i], anti_alias, color)
            rect = rendered_text.get_rect()
            rect.top = i * font._font.get_linesize()

            if halign == sge.ALIGN_LEFT:
                rect.left = text_rect.left
            elif halign == sge.ALIGN_RIGHT:
                rect.right = text_rect.right
            elif halign == sge.ALIGN_CENTER:
                rect.centerx = text_rect.centerx

            text_surf.blit(rendered_text, rect)

        if valign == sge.ALIGN_TOP:
            text_rect.top = box_rect.top
        elif valign == sge.ALIGN_BOTTOM:
            text_rect.bottom = box_rect.bottom
        elif valign == sge.ALIGN_MIDDLE:
            text_rect.centery = box_rect.centery

        box_surf.blit(text_surf, text_rect)

        if halign == sge.ALIGN_LEFT:
            box_rect.left = x
        elif halign == sge.ALIGN_RIGHT:
            box_rect.right = x
        elif halign == sge.ALIGN_CENTER:
            box_rect.centerx = x
        else:
            box_rect.left = x

        if valign == sge.ALIGN_TOP:
            box_rect.top = y
        elif valign == sge.ALIGN_BOTTOM:
            box_rect.bottom = y
        elif valign == sge.ALIGN_MIDDLE:
            box_rect.centery = y
        else:
            box_rect.top = y

        for i in xrange(len(self._baseimages)):
            if frame is None or frame % len(self._baseimages) == i:
                self._baseimages[i].blit(box_surf, box_rect)

        self._refresh()
Example #16
0
    def _get_background(self):
        # Return the static background this frame.
        background = pygame.Surface(
            (round(sge.game.width * sge.game._xscale),
             round(sge.game.height * sge.game._yscale)))
        background.fill(sge._get_pygame_color(self.color))

        for view in sge.game.current_room.views:
            view_x = int(round(view.x * sge.game._xscale))
            view_y = int(round(view.y * sge.game._yscale))
            view_xport = max(
                0,
                min(int(round(view.xport * sge.game._xscale)),
                    background.get_width() - 1))
            view_yport = max(
                0,
                min(int(round(view.yport * sge.game._yscale)),
                    background.get_height() - 1))
            view_w = min(view.width * sge.game._xscale,
                         background.get_width() - view_xport)
            view_h = min(view.height * sge.game._yscale,
                         background.get_height() - view_yport)
            surf = background.subsurface(view_xport, view_yport, view_w,
                                         view_h)
            for layer in self.layers:
                image = layer._get_image()
                x = int(
                    round((sge.game.current_room.background_x + layer.x -
                           (view.x * layer.xscroll_rate)) * sge.game._xscale))
                y = int(
                    round((sge.game.current_room.background_y + layer.y -
                           (view.y * layer.yscroll_rate)) * sge.game._yscale))
                image_w = max(1, image.get_width())
                image_h = max(1, image.get_height())

                # These equations bring the position to the largest
                # values possible while still being less than the
                # location we're getting the surface at.  This is to
                # minimize the number of repeat blittings.
                if layer.xrepeat:
                    x = (x % image_w) - image_w
                if layer.yrepeat:
                    y = (y % image_h) - image_h

                # Apply the origin so the positions are as expected.
                x -= int(round(layer.sprite.origin_x * sge.game._xscale))
                y -= int(round(layer.sprite.origin_y * sge.game._yscale))

                if layer.xrepeat and layer.yrepeat:
                    xstart = x
                    while y < surf.get_height():
                        x = xstart
                        while x < surf.get_width():
                            surf.blit(image, (x, y))
                            x += image_w
                        y += image_h
                elif (layer.xrepeat and y < view_y + view_h
                      and y + image_h > view_y):
                    while x < surf.get_width():
                        surf.blit(image, (x, y))
                        x += image_w
                elif (layer.yrepeat and x < view_x + view_w
                      and x + image_w > view_x):
                    while y < surf.get_height():
                        surf.blit(image, (x, y))
                        y += image_h
                elif (x < surf.get_width() and x + image_w > 0
                      and y < surf.get_height() and y + image_h > 0):
                    surf.blit(image, (x, y))

        return background