Exemple #1
0
def compileSVASheet(sheet, color):
    color = tuple([255-c for c in color])
    
    width = sheet.get_width()
    height = sheet.get_height() / 3
    
    colorSurf = Surface((width, height))
    colorSurf.fill(color)
    
    colorSurf.blit(sheet, (0, 0), None, BLEND_MULT)
    
    # Now create a white surface so we can invert the Saturation map
    result = Surface((width, height), SRCALPHA)
    result.fill((255, 255, 255))
    
    result.blit(colorSurf, (0, 0), None, BLEND_RGB_SUB)
    
    # Multiply this with the Value Map
    result.blit(sheet, (0, -height), None, BLEND_MULT)
    
    # copy the alpha mask from the spritesheet
    alpha = Surface((width, height))
    alpha.blit(sheet, (0, -2 * height))
    
    #convert the (nearly done) Surface to per pixel alpha
    result.convert_alpha()
    
    # Use Numpy here
    numWhite = surfarray.pixels_alpha( result )
    
    numAlpha = surfarray.pixels3d( alpha )
    
    numWhite[ :, : ] = numAlpha[ :, :, 0 ]
    
    return result.copy()
Exemple #2
0
def smart_convert(
    original: pygame.Surface,
    colorkey: Optional[ColorLike],
    pixelalpha: bool,
) -> pygame.Surface:
    """
    Return new pygame Surface with optimal pixel/data format

    This method does several interactive_tests on a surface to determine the optimal
    flags and pixel format for each tile surface.

    Parameters:
        original: tile surface to inspect
        colorkey: optional colorkey for the tileset image
        pixelalpha: if true, prefer per-pixel alpha surfaces

    Returns:
        new tile surface

    """
    # tiled set a colorkey
    if colorkey:
        tile = original.convert()
        tile.set_colorkey(colorkey, pygame.RLEACCEL)
        # TODO: if there is a colorkey, count the colorkey pixels to determine if RLEACCEL should be used

    # no colorkey, so use a mask to determine if there are transparent pixels
    else:
        tile_size = original.get_size()
        threshold = 254  # the default

        try:
            # count the number of pixels in the tile that are not transparent
            px = pygame.mask.from_surface(original, threshold).count()
        except:
            # pygame_sdl2 will fail because the mask module is not included
            # in this case, just convert_alpha and return it
            return original.convert_alpha()

        # there are no transparent pixels in the image
        if px == tile_size[0] * tile_size[1]:
            tile = original.convert()

        # there are transparent pixels, and set for perpixel alpha
        elif pixelalpha:
            tile = original.convert_alpha()

        # there are transparent pixels, and we won't handle them
        else:
            tile = original.convert()

    return tile
Exemple #3
0
    def render(self, text, antialias, forecolor, backcolor=(0, 0, 0, 255)):
        size = self.size(text)
        img = NSImage.alloc().initWithSize_(size)
        img.lockFocus()

        NSString.drawAtPoint_withAttributes_(
            text, (0.0, 0.0), {
                NSFontAttributeName:
                self._font,
                NSUnderlineStyleAttributeName:
                self._isUnderline and 1.0 or None,
                NSBackgroundColorAttributeName:
                backcolor and _getColor(backcolor) or None,
                NSForegroundColorAttributeName:
                _getColor(forecolor),
            })

        rep = NSBitmapImageRep.alloc().initWithFocusedViewRect_(
            ((0.0, 0.0), size))
        img.unlockFocus()
        if rep.samplesPerPixel() == 4:
            s = Surface(size, SRCALPHA | SWSURFACE, 32,
                        [-1 << 24, 0xff << 16, 0xff << 8, 0xff])

            a = Numeric.reshape(
                Numeric.fromstring(rep.bitmapData(), typecode=Numeric.Int32),
                (size[1], size[0]))
            blit_array(s, Numeric.swapaxes(a, 0, 1))
            return s.convert_alpha()
Exemple #4
0
    def work_text(self, timer=None, size=1):
        color = (255, 255, 255)
        string = self.disp_score(timer)
        background = (0, 0, 0, 0.4 * 255)
        font_size = 15 * size
        font = py.font.SysFont("monospace", int(font_size), bold=True)
        line_width = 25
        lines = string.split('/ ')
        labels = []

        for line in lines:
            render = font.render(line, 1, color)
            labels.append(render)

        width = max([f.get_width() for f in labels])
        height = 0
        ys = [0]
        for f in labels:
            height += f.get_height() + 3
            ys += [height]

        surface = Surface((width, height), SRCALPHA, 32)
        surface = surface.convert_alpha()
        if background != None:
            surface.fill(background)

        y = 0
        for label in labels:
            surface.blit(label, (0, ys[y]))
            y += 1

        return surface
Exemple #5
0
    def __init__(self,
                 relative_rect: pygame.Rect,
                 image_surface: pygame.Surface,
                 manager: IUIManagerInterface,
                 container: Union[IContainerLikeInterface, None] = None,
                 parent_element: UIElement = None,
                 object_id: Union[str, None] = None,
                 anchors: Dict[str, str] = None):

        super().__init__(relative_rect,
                         manager,
                         container,
                         starting_height=1,
                         layer_thickness=1,
                         anchors=anchors)

        self._create_valid_ids(container=container,
                               parent_element=parent_element,
                               object_id=object_id,
                               element_id='image')

        self.original_image = None
        image_surface = image_surface.convert_alpha(
        )  # GUI images must support an alpha channel
        if (image_surface.get_width() != self.rect.width
                or image_surface.get_height() != self.rect.height):
            self.original_image = image_surface
            self.set_image(
                pygame.transform.smoothscale(self.original_image,
                                             self.rect.size))
        else:
            self.set_image(image_surface)
def set_alpha_from_intensity(surface, alpha_factor, decay_mode, color):
    if not HAS_PIL:
        raise Exception("PIL was not found on this machine.")
    if not HAS_NUMPY:
        raise Exception("NumPy was not found on this machine.")
    rect = surface.get_rect()
    newsurf = Surface(rect.size, SRCALPHA, depth=surface.get_bitsize())
    newsurf = newsurf.convert_alpha()
    newsurf.blit(surface, (0, 0))
    arrayrgb = surfarray.pixels3d(newsurf)
    arraya = surfarray.pixels_alpha(newsurf)
    bulk_color = tuple(color)
    for x in range(rect.left, rect.right):
        for y in range(rect.top, rect.bottom):
            color = tuple(arrayrgb[x][y])
            light = square_color_norm(color)
            alpha = float(light)/MAX_NORM * 255
            arrayrgb[x][y][0] = bulk_color[0]
            arrayrgb[x][y][1] = bulk_color[1]
            arrayrgb[x][y][2] = bulk_color[2]
            if decay_mode == "linear":
                actual_alpha = int(255 - alpha)
            elif decay_mode == "exponential":
                tuning_factor = 1.03
                actual_alpha = int(255*tuning_factor**-alpha)
##            elif decay_mode == "quadratic":
##                pass
            else:
                raise Exception("decay_mode not recognized: " + decay_mode)
            actual_alpha *= alpha_factor
            arraya[x][y] = actual_alpha
    return newsurf
Exemple #7
0
def make_new_transparent_surface(surf: Surface):
    """
    make a new transparent surface with the same size as the passed in one
    """
    surf = Surface((surf.get_width(), surf.get_height()), SRCALPHA, 32)
    surf = surf.convert_alpha()
    return surf
def set_alpha_from_intensity(surface, alpha_factor, decay_mode, color):
    if not HAS_PIL:
        raise Exception("PIL was not found on this machine.")
    if not HAS_NUMPY:
        raise Exception("NumPy was not found on this machine.")
    rect = surface.get_rect()
    newsurf = Surface(rect.size, SRCALPHA, depth=surface.get_bitsize())
    newsurf = newsurf.convert_alpha()
    newsurf.blit(surface, (0, 0))
    arrayrgb = surfarray.pixels3d(newsurf)
    arraya = surfarray.pixels_alpha(newsurf)
    bulk_color = tuple(color)
    for x in range(rect.left, rect.right):
        for y in range(rect.top, rect.bottom):
            color = tuple(arrayrgb[x][y])
            light = square_color_norm(color)
            alpha = float(light) / MAX_NORM * 255
            arrayrgb[x][y][0] = bulk_color[0]
            arrayrgb[x][y][1] = bulk_color[1]
            arrayrgb[x][y][2] = bulk_color[2]
            if decay_mode == "linear":
                actual_alpha = int(255 - alpha)
            elif decay_mode == "exponential":
                tuning_factor = 1.03
                actual_alpha = int(255 * tuning_factor**-alpha)
##            elif decay_mode == "quadratic":
##                pass
            else:
                raise Exception("decay_mode not recognized: " + decay_mode)
            actual_alpha *= alpha_factor
            arraya[x][y] = actual_alpha
    return newsurf
Exemple #9
0
 def create_blank_base_image(self):
     # Give the agent a larger Surface (by sqrt(2)) to work with since it may rotate.
     blank_base_image = Surface(
         (self.rect.w * Agent.SQRT_2, self.rect.h * Agent.SQRT_2))
     # This was important, but I don't remember why.
     blank_base_image = blank_base_image.convert_alpha()
     blank_base_image.fill((0, 0, 0, 0))
     return blank_base_image
Exemple #10
0
    def __init__(self):
        """Initialize the core variables."""
        self.change_to = ""
        self.running = True

        surface = Surface([960, 1024], SRCALPHA, 32)
        self.windows = {"main": surface.convert_alpha()}

        self.musics = None
    def create_base(self):
        surf = Surface((64, 32), pygame.SRCALPHA, 32)

        pygame.draw.rect(surf, self.color, Rect(0, 8, 44, 16))
        pygame.draw.polygon(surf, self.color, [(44, 0), (64, 16), (44, 32)])

        # noinspection PyArgumentList
        self.base_image = surf.convert_alpha()
        self.drawable = Drawable(self.base_image.copy(), self.position, True,
                                 True)
Exemple #12
0
 def create_blank_base_image(self):
     # Give the agent a larger Surface (by sqrt(2)) to work with since it may rotate.
     blank_base_image = Surface(
         (self.rect.w * Agent.SQRT_2, self.rect.h * Agent.SQRT_2))
     # This sets the rectangle to be transparent.
     # Otherwise it would be black and would cover nearby agents.
     # Even though it's a method of Surface, it can also take a Surface parameter.
     # If the Surface parameter is not given, PyCharm complains.
     # noinspection PyArgumentList
     blank_base_image = blank_base_image.convert_alpha()
     blank_base_image.fill((0, 0, 0, 0))
     return blank_base_image
 def CreateClassesSurface(self, classes):
     print('CreateClassesSurface')
     if classes:
         timeSurfaceText = ConvertMilitaryToStd(classes[0]['LEC']['Start'])
     else:
         timeSurfaceText = 'No More Classes Today'
     timeSurfaceFont = font.Font(*self.timeSlotFont)
     timeSurface = timeSurfaceFont.render(timeSurfaceText, True,
                                          (51, 51, 51))
     classSurfaceHeight = (self.height -
                           (timeSurface.get_rect().height * 2) -
                           ((self.scheduleDisplay_numberOfClasses - 1) *
                            self.classSurface_heightBuffer)
                           ) / self.scheduleDisplay_numberOfClasses
     classesSurfaceHeight = timeSurface.get_rect().height + (
         len(classes) *
         (classSurfaceHeight + self.classSurface_heightBuffer))
     classesSurface = Surface(
         (self.width -
          (self.classSurface_widthBuffer * 2), classesSurfaceHeight),
         SRCALPHA, 32)
     classesSurface.blit(timeSurface, (self.classSurface_widthBuffer, 0))
     for i, meeting in enumerate(classes):
         nextClass = self.CreateClassSurface(
             meeting, self.classSurface_bgColors[i % 2],
             self.width - (2 * self.classSurface_widthBuffer),
             classSurfaceHeight)
         classesSurface.blit(nextClass,
                             (0, timeSurface.get_rect().height +
                              (nextClass.get_rect().height +
                               self.classSurface_heightBuffer) * i))
     classesSurface.convert_alpha()
     if timeSurfaceText != 'No More Classes Today':
         currentTime = datetime.now()
         timeSlot = datetime.combine(
             currentTime.date(),
             datetime.strptime(timeSurfaceText, '%I:%M %p').time())
         timeSlot = timeSlot + timedelta(minutes=self.timeSlotDisplayBuffer)
         self.classesSurfacesAndTimes.append((classesSurface, timeSlot))
     return classesSurface
Exemple #14
0
class Cell(sprite.Sprite):
    def __init__(self, x, y, r=BG[0], g=BG[1], b=BG[2], a=BG[3]):
        sprite.Sprite.__init__(self)

        self.posx = x
        self.posy = y
        self.color = (r, g, b, a)
        self.image = None
        self.rect = None

    def set(self, w, h):
        self.image = Surface([w, h])
        self.image.convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.topleft = (self.posx, self.posy)

    def fill(self, r, g, b, a, color=(-1, -1, -1)):
        if color != (-1, -1, -1):
            self.color = (r, g, b, a)
        else:
            self.color = color

    def update(self):
        self.image.fill(self.color)
Exemple #15
0
def pad(source: Surface, margins: tuple, background_color=None) -> Surface:
    '''
    Pads the source Surface by margins, a quintuple on the
    form (top, right, bottom, left), or a Margins object.
    '''
    margins = Margins(*margins)
    source_rect = source.get_rect()
    padded_rect = Rect(source_rect)
    padded_rect.w += margins.left + margins.right
    padded_rect.h += margins.top + margins.bottom
    padded_surface = Surface(padded_rect.size, pygame.SRCALPHA, 32)
    padded_surface = padded_surface.convert_alpha()
    if background_color:
        padded_surface.fill(background_color)
    padded_surface.blit(source, (margins.left, margins.top))
    return padded_surface
Exemple #16
0
    def get_image(self,
                  x: int,
                  y: int,
                  width: int,
                  height: int,
                  alpha: bool = False) -> Surface:
        """
        Extracts sprite of given point (x, y) (left, top) and width and height.

        Alpha boolean keyword argument for converting the sprite in alpha or non-alpha.
        """
        image = Surface((width, height))
        image.blit(self.spritesheet, (0, 0), (x, y, width, height))
        image.set_colorkey((0, 0, 0))
        image.set_alpha(255)

        if alpha:
            return image.convert_alpha()
        return image.convert()
    def render(self, text, antialias, forecolor, backcolor=(0,0,0,255)):
        size = self.size(text)
        img = NSImage.alloc().initWithSize_(size)
        img.lockFocus()

        NSString.drawAtPoint_withAttributes_(text, (0.0, 0.0), {
            NSFontAttributeName: self._font,
            NSUnderlineStyleAttributeName: self._isUnderline and 1.0 or None,
            NSBackgroundColorAttributeName: backcolor and _getColor(backcolor) or None,
            NSForegroundColorAttributeName: _getColor(forecolor),
        })

        rep = NSBitmapImageRep.alloc().initWithFocusedViewRect_(((0.0, 0.0), size))
        img.unlockFocus()
        if rep.samplesPerPixel() == 4:
            s = Surface(size, SRCALPHA|SWSURFACE, 32, [-1<<24,0xff<<16,0xff<<8,0xff])
            
            a = Numeric.reshape(Numeric.fromstring(rep.bitmapData(), typecode=Numeric.Int32), (size[1], size[0]))
            blit_array(s, Numeric.swapaxes(a,0,1))
            return s.convert_alpha()
Exemple #18
0
    def tick(self, dt):
        if self.engine.gameMgr.game_status == 'IN_GAME' or self.engine.gameMgr.game_status == 'ENTRY_ANIMATION':
            if self.show_fps:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_fps(), (10, 0))
            if self.show_grounded:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_is_grounded(), (300, 0))
            if self.show_jumps_left:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_show_jumps(), (600, 0))
            if self.show_bullet_count:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_bullet_count(), (900, 0))
            if self.show_platforms_rendered:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_platforms_rendered(), (10, 50))
            if self.show_total_enemy_count:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_enemy_count(), (300, 50))
            if self.show_total_enemy_rendered:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_enemy_rendered_count(),
                    (600, 50))
            if self.show_game_status:
                self.engine.gfxMgr.uiScreen.blit(
                    self.engine.gfxMgr.update_game_status(), (900, 50))

            self.engine.gfxMgr.uiScreen.blit(
                self.engine.gfxMgr.update_player_lives_left(), (10, 100))

        elif self.engine.gameMgr.game_status == 'MENU':
            transparent_background = Surface(
                (self.engine.config.window_size[0],
                 self.engine.config.window_size[1]))
            transparent_background = transparent_background.convert_alpha()
            transparent_background.fill((0, 0, 0, 60))
            self.engine.gfxMgr.uiScreen.blit(transparent_background, (0, 0))

            for button in self.main_menu_buttons:
                button.draw()
Exemple #19
0
    def get_label(self,
                  string,
                  break_char="",
                  *,
                  width=None,
                  height=None,
                  scale=1,
                  color=(255, 255, 0),
                  background=None):
        """
        Generates text in a given area, wrapped at :break_char:
        Returns PyGame surface
        """

        # Scaling
        if width:
            width = int(width * (scale**-1))
        if height:
            height = int(height * (scale**-1))

        # Get labels
        labels = self.get_lines(string, break_char, width, scale, color)

        # Generate blank surface
        if not width:
            width = max([f.get_width() for f in labels])
        if not height:
            height = sum([f.get_height() + 2 for f in labels])
        surface = Surface((width, height), SRCALPHA, 32)
        surface = surface.convert_alpha()
        if background:
            surface.fill(background)

        # Add lines
        y = 0
        for label in labels:
            surface.blit(label, (0, y))
            y += label.get_height() + 2

        return surface
Exemple #20
0
class Creature(Sprite):
    '''
        Class represents a 
    '''
    def __init__(self, x=0, y=0, theta=0):
        self.y = x
        self.y = y
        self.theta = theta
        self.v = 1
        self.energy = 5000 + abs(50 * randn())
        self.brain = createEmpty(10, 10)
        self.width = CREATURE_WIDTH
        self.height = CREATURE_HEIGHT
        
        self.senses = []
        
        self.base_image = Surface((self.width, self.height), pygame.SRCALPHA, 32)
        self.base_image = self.base_image.convert_alpha()
        
        self.brain_data = None
        
        self.rect = (0, 0, self.width, self.height)
        self._render()
        self.image = pygame.transform.rotate(self.base_image, theta)
        
    ''' updates the creature for the next round '''
    def tick(self):
        self.brain.elapseTime(10, [(randrange(1, 1000) * 1.0)/ 1000 for _ in xrange(10)])
        self.y -= math.sin(deg2rad(self.theta)) * self.v
        self.y += math.cos(deg2rad(self.theta)) * self.v 
        self.theta += (random.randrange(60)) - 30
        self.image = pygame.transform.rotate(self.base_image, self.theta)
        
    ''' rendering for the basic, ugly creature '''
    def _render(self):
        pygame.draw.circle(self.base_image, pygame.Color(0, 128, 64), (self.width/2, self.height/2), self.width/2, self.width/2)
        s = sqrt(2) * 12
        pygame.draw.rect(self.base_image, pygame.Color(0, 128, 64), (round(12.5 - s/2), round(12.5 - s/2), s, s))
        pygame.draw.line(self.base_image, pygame.Color(255, 10, 10), (12, 12), (24, 12), 1)
 def add_image(self,
               name=DEFAULT,
               img_surface: pygame.Surface = None,
               rotate_point=None):
     self._img_dict[name] = (img_surface.convert_alpha(), rotate_point)
def load_pygame(filename):
    """
    load a tiled TMX map for use with pygame
    """

    from pygame import Surface
    import pygame, os

    tiledmap = load_tmx(filename)

    # cache will find duplicate tiles to reduce memory usage
    # mostly this is a problem in the blank areas of a tilemap
    cache = {}

    # just a precaution to make sure tileset images are added in the correct order
    for firstgid, t in sorted([(t.firstgid, t) for t in tiledmap.tilesets]):
        path = os.path.join(os.path.dirname(tiledmap.filename), t.source)

        image = pygame.image.load(path)

        w, h = image.get_rect().size

        tile_size = (t.tilewidth, t.tileheight)

        # some tileset images may be slightly larger than the tiles area
        # ie: may include a banner, copyright, etc.  this compensates for that
        for y in range(0, int(h / t.tileheight) * t.tileheight, t.tileheight):
            for x in range(0, int(w / t.tilewidth) * t.tilewidth, t.tilewidth):

                # somewhat handle transparency, though colorkey handling is not tested
                if t.trans is None:
                    tile = Surface(tile_size, pygame.SRCALPHA)
                else:
                    tile = Surface(tile_size)

                # blit the smaller portion onto a new image from the larger one
                tile.blit(image, (0, 0), ((x, y), tile_size))

                # make a unique id for this image, not sure if this is the best way, but it works
                key = pygame.image.tostring(tile, "RGBA")

                # make sure we don't have a duplicate tile
                try:
                    tile = cache[key]
                except KeyError:
                    if t.trans is None:
                        tile = tile.convert_alpha()
                    else:
                        tile = tile.convert()
                        tile.set_colorkey(t.trans)

                    # update the cache
                    cache[key] = tile

                tiledmap.images.append(tile)

    # correctly handle transformed tiles.  currently flipped tiles
    # work by creating a new gid for the flipped tile and changing the gid
    # in the layer to the new gid.
    for layer in tiledmap.tilelayers:
        for x, y, gid, trans in layer.flipped_tiles:
            fx = trans & FLIP_X == FLIP_X
            fy = trans & FLIP_Y == FLIP_Y

            tile = pygame.transform.flip(tiledmap.images[gid], fx, fy)
            tiledmap.images.append(tile)

            # change the original gid in the layer data to the new gid
            layer.data[y][x] = len(tiledmap.images) - 1

        del layer.flipped_tiles
    del cache

    return tiledmap
Exemple #23
0
class GroundSurface:
    def __init__(self, **kwargs):
        scale = 1.0
        if "mode" in kwargs:
            mode = kwargs["mode"]
            if mode == "auto":
                surface = Surface(
                    (WIDTH,
                     HEIGHT))  # pygame.display.set_mode((WIDTH, HEIGHT))
                self.rect = surface.get_rect()
            elif mode == "copy":
                surface = kwargs["surface"]
                if type(surface) is GroundSurface:
                    surface = surface.surface
                self.rect = surface.get_rect()
            elif mode == "custom":
                if "x" not in kwargs:
                    kwargs["x"] = 0
                if "y" not in kwargs:
                    kwargs["y"] = 0
                surface = Surface((int(kwargs["w"]), int(kwargs["h"])))
                rect = surface.get_rect()
                rect.left = kwargs["x"]
                rect.top = kwargs["y"]
                if "scale" in kwargs:
                    scale = kwargs["scale"]
                self.rect = rect
            else:  # default:
                surface = Surface((WIDTH, HEIGHT))
                WriteLog.error(__name__, "GroundSurface错误,提供的mode不存在")
                self.rect = surface.get_rect()
        else:
            surface = Surface((WIDTH, HEIGHT))
            WriteLog.error(__name__, "GroundSurface错误,未提供mode参数")
            self.rect = surface.get_rect()

        self.block_size = BLOCK_UNIT

        self.w = self.rect.w
        self.h = self.rect.h
        self.surface = surface
        self.scale = scale
        self.parent = None
        self.layer = 0
        self.children = []
        self.group = Group()
        # 当前画布占用情况 无记忆 不考虑缝隙等复杂情况 指定的是一个“可绘制矩形范围”
        self.curpos = {"left": 0, "top": 0, "right": 0, "bottom": 0, "mid": 0}
        self.priority = 0
        if "priority" in kwargs:
            self.priority = kwargs["priority"]

        self.active = True

    # 增加子画布 这类画布可以是别的独立画布 也可以给出参数创建
    def add_child(self, *args):
        if len(args) == 1:
            # 插入别的画布到自适应的左上角 这样做由于对齐问题只能插一行 并且导致自适应混乱 多行需要手动重定位curpos
            ground_surface = args[0]
            rect = ground_surface.rect
            rect.left = self.curpos['left']
            rect.top = self.curpos['top']
            self.curpos['left'] += rect.w
        elif len(args) == 2:  # 自适应画布 贴边或者定在中心 第一个指定类型 第二个指定大小
            ground_surface = self.create_adaptive_surface(*args)
        elif len(args) == 3:  # 插入别的画布到指定坐标 无视碰撞
            ground_surface = args[0]
            ground_surface.rect.left = args[1]
            ground_surface.rect.top = args[2]
        else:  # 用Ground方式创建画布
            ground_surface = GroundSurface(*args)

        ground_surface.layer = self.layer + 1
        ground_surface.parent = self
        ground_surface.scale *= self.scale
        self.children.append(ground_surface)
        self.children.sort(key=lambda it: it.priority, reverse=False)

        return ground_surface

    # 自适应矩形
    def create_adaptive_surface(self, type, value):
        if type not in self.curpos:
            WriteLog.error(__name__, "错误的ground类型")
            return
        w = self.rect.w
        h = self.rect.h
        t = self.curpos["top"]
        r = self.curpos["right"]
        l = self.curpos["left"]
        b = self.curpos["bottom"]
        op = {
            "left":
            Rect(l, t, value, h - t - b),
            "top":
            Rect(l, t, w - l - r, value),
            "right":
            Rect(w - value - r, t, value, h - t - b),
            "bottom":
            Rect(l, h - value - b, w - l - r, value),
            "mid":
            Rect(max(l, int((w - value) / 2)), max(r, int((h - value) / 2)),
                 min(w - l - r, value), min(h - t - b, value))
        }
        rect = op[type]
        ground_surface = GroundSurface(mode="copy",
                                       surface=Surface([rect.w, rect.h]))
        ground_surface.rect.left = rect.left
        ground_surface.rect.top = rect.top
        self.curpos[type] += value
        return ground_surface

    # 填充一个surface到画布上,以变形/重复等方式 fill_rect指定填充范围 默认全图
    def fill_surface(self, surface: Surface, mode="scale", fill_rect=None):
        rect = surface.get_rect()
        if fill_rect is None:
            fill_rect = self.rect
            rect.left = 0
            rect.top = 0
        else:
            rect.left = fill_rect.left
            rect.top = fill_rect.top

        if mode == "scale":
            self.surface.blit(scale(surface, (fill_rect.w, fill_rect.h)),
                              fill_rect)
        elif mode == "repeat":
            while rect.bottom <= fill_rect.bottom:
                while rect.right <= fill_rect.right:
                    self.surface.blit(surface, rect)
                    rect.left += rect.w
                rect.left = 0
                rect.top += rect.h

    # 填充一个sprite到画布上 这个Sprite会被添加到当前画布的精灵组
    def add_sprite(self, sprite, mode="normal", fill_rect=None):
        if fill_rect is not None:
            if mode == "scale":  # 这个对精灵基本没用 放弃吧
                sprite.image = scale(sprite.image, (fill_rect.w, fill_rect.h))
            sprite.rect.left = fill_rect.left
            sprite.rect.top = fill_rect.top
        self.group.add(sprite)

    #  重定位 - 画布的内部逻辑坐标转换为外部坐标(父类可视坐标系)
    def relocate(self, *args):
        x, y = self.trans_locate(*args)
        x += self.rect.left
        y += self.rect.top
        return x, y

    #  重新设置surface大小 其他设置不变(如果增大会向右下扩张)
    def resize(self, w, h):
        self.surface = Surface((w, h))
        self.rect.w = w
        self.rect.h = h

    # 需要被实现 逻辑坐标到物理坐标的转换:
    def trans_locate(self, *args):
        """
        逻辑转物理,默认为top left
        :param args:
        :arg[3]: "up":top centerx "down": bottom centerx

        exmaple 1: map.trans_locate(12,12,'down') # 获取坐标 然后在该位置绘制敌人
        example 2: event.move(map.trans_locate(12,12,'down')) # 移动事件到12,12位置

        :return:
        """
        x, y = args[0], args[1]
        if len(args) > 2:
            if args[2] == "up":
                return int((x + 0.5) * self.block_size), y * self.block_size
            elif args[2] == "down":
                return int(
                    (x + 0.5) * self.block_size), (y + 1) * self.block_size

        return x * self.block_size, y * self.block_size

    #  刷新函数: 可以根据变化层级刷新部分内容而不是全部一起刷新
    #  !不同画布不能有不同的刷新率,刷新率以最快为准,控制动画频率在sprite的update中自行控制
    def flush(self, screen=None):
        self.group.update(pygame.time.get_ticks())
        self.group.draw(self.surface)
        self.children.sort(key=lambda it: it.priority)
        # tempSurface = Surface()
        for c in self.children:
            if c.active:
                c.flush(screen=self.surface)
        if screen is not None:
            screen.blit(self.surface.convert_alpha(self.surface), self.rect)

    # 填充纯色(debug使用)
    def fill(self, arg):
        self.surface.fill(arg)

    # draw_text 在画布上绘制文字
    # 接受GroundSurface(画板),text(需要显示的文字),size(文字大小),color(文字颜色),x,y(xy相对坐标)
    # mode(模式,默认为画布相对方格坐标,如果mode="px"那么将为画布相对像素坐标)
    def draw_text(self, text, size, color, x, y, mode=None):
        font_name = global_var.get_value("font_name")
        font = pygame.font.Font(font_name, size)
        text_surface = font.render(text, True, color)
        text_rect = text_surface.get_rect()
        if mode == "px":
            text_rect.left = x
            text_rect.top = y
        else:
            text_rect.left = x * BLOCK_UNIT
            text_rect.top = y * BLOCK_UNIT
        self.surface.blit(text_surface, text_rect)

    # draw_bulk_text 在画布上绘制大量文字
    # 接受GroundSurface(画板),content(需要显示的内容),size(文字大小)
    # mode(模式,默认为画布相对方格坐标,如果mode="px"那么将为画布相对像素坐标)
    '''
    content = [
        {
            "x": x,
            "y": y,
            "text": text,
            "color": color
        }
    ]
    '''

    def draw_bulk_text(self, content, size, mode=None):
        font_name = global_var.get_value("font_name")
        font = pygame.font.Font(font_name, size)
        for text_obj in content:
            text_surface = font.render(text_obj["text"], True,
                                       text_obj["color"])
            text_rect = text_surface.get_rect()
            if mode == "px":
                text_rect.left = text_obj["x"]
                text_rect.top = text_obj["y"]
            else:
                text_rect.left = text_obj["x"] * BLOCK_UNIT
                text_rect.top = text_obj["y"] * BLOCK_UNIT
            self.surface.blit(text_surface, text_rect)

    # draw_stroke_text 在画布上绘制描边文字
    # 接受GroundSurface(画板),content(需要显示的内容),size(文字大小),color(文字颜色),x,y(xy相对坐标)
    # mode(模式,默认为画布相对方格坐标,如果mode="px"那么将为画布相对像素坐标)
    def draw_stroke_text(self,
                         text,
                         size,
                         text_color,
                         stroke_color,
                         x,
                         y,
                         mode=None):
        content = []
        coord = [(x + 1, y + 1), (x + 1, y - 1), (x - 1, y + 1),
                 (x - 1, y - 1), (x, y)]
        for i in range(len(coord)):
            text_obj = {}
            text_obj["x"] = coord[i][0]
            text_obj["y"] = coord[i][1]
            text_obj["text"] = text
            if i < len(coord) - 1:
                text_obj["color"] = stroke_color
            else:
                text_obj["color"] = text_color
            content.append(text_obj)
        self.draw_bulk_text(content, size, mode)

    # draw_bulk_stroke_text 在画布上绘制大量描边文字
    # 接受GroundSurface(画板),text(需要显示的文字),size(文字大小),text_color(文字颜色),stroke_color(描边颜色)
    # mode(模式,默认为画布相对方格坐标,如果mode="px"那么将为画布相对像素坐标)
    '''
    content = [
        {
            "x": x,
            "y": y,
            "text": text,
        }
    ]
    '''

    def draw_bulk_stroke_text(self, content, size, mode=None):
        result_content = []
        for i in content:
            x = i["x"]
            y = i["y"]
            coord = [(x + 1, y + 1), (x + 1, y - 1), (x - 1, y + 1),
                     (x - 1, y - 1), (x, y)]
            for j in range(len(coord)):
                text_obj = {}
                text_obj["x"] = coord[j][0]
                text_obj["y"] = coord[j][1]
                text_obj["text"] = i["text"]
                if j < len(coord) - 1:
                    text_obj["color"] = i["stroke_color"]
                else:
                    text_obj["color"] = i["text_color"]
                result_content.append(text_obj)
        self.draw_bulk_text(result_content, size, mode)

    # draw_lines 在画布上绘制(一条或多条)线段
    # 接受points(端点数组,格式[(x, y)]),width(线条宽度),color(线条颜色)
    # mode(模式,默认为画布相对方格坐标,如果mode="px"那么将为画布相对像素坐标)
    # 例子:draw_lines([(1,1),(1,100),(100,1),(1,1)], 5, WHITE) -> 一个线条宽度为5px的白色三角形
    def draw_lines(self, points, width, color, mode=None):
        if mode == "px":
            pygame.draw.lines(self.surface, color, False, points, width)
        else:
            block_points = []
            for item in points:
                block_points.append(
                    [item[0] * BLOCK_UNIT, item[1] * BLOCK_UNIT])
            pygame.draw.lines(self.surface, color, False, block_points, width)

    # draw_rect 在画布上绘制矩形
    # start_pos(矩形左上角的坐标),格式[(x, y)]),end_pos(矩形右下角的坐标)
    # width(线条宽度),color(线条颜色)
    # mode(模式,默认为画布相对方格坐标,如果mode="px"那么将为画布相对像素坐标)
    def draw_rect(self, start_pos, end_pos, width, color, mode=None):
        if mode == "px":
            Rect = (start_pos[0], start_pos[1], end_pos[0] - start_pos[0],
                    end_pos[1] - start_pos[1])
        else:
            Rect = (start_pos[0] * BLOCK_UNIT, start_pos[1] * BLOCK_UNIT,
                    end_pos[0] * BLOCK_UNIT - start_pos[0] * BLOCK_UNIT,
                    end_pos[1] * BLOCK_UNIT - start_pos[1] * BLOCK_UNIT)
        pygame.draw.rect(self.surface, color, Rect, width)

    # draw_icon 提供一个可以调用Sprite的接口
    def draw_icon(self, map_element, x, y):
        px, py = self.trans_locate(0, 0)
        rect = Rect(px, py, self.block_size, self.block_size)
        # sprite的显示需要接通group
        name = str(map_element)
        ret = get_resource(name)
        px, py = self.trans_locate(x, y, "down")
        rect.centerx = px
        rect.bottom = py
        if type(ret) is tuple:  # 属于精灵 (注意:此时不能直接导入精灵,因为先有map后有精灵)
            img = ret[0]
            img_rect = ret[1]  # 以资源本体大小显示 用以支持超过32*32的图像
            img_rect.topleft = rect.topleft
            sp = list(ret[2])
            self.add_sprite(EventSprite(name, img, sp), fill_rect=img_rect)
        elif ret is not None:
            self.fill_surface(ret, fill_rect=rect)
Exemple #24
0
 def __create_surface(size: Tuple[int, int]) -> Surface:
     """Returns a new Surface instance."""
     surface = Surface(size, pygame.SRCALPHA, 32)
     surface = surface.convert_alpha(surface)
     return surface
Exemple #25
0
class Game(object):
    def __init__(self):
        self.is_running = True
        self.grid_position = (0, 0)
        self.scrolling = (0, 0)
        self.zoom = ZOOM

        self.scroll_left = 0
        self.scroll_up = 0
        self.clock = time.Clock()

        init()

        self.screen = display.set_mode(RESOLUTION_DEFAULT)

        self.background = Surface(self.screen.get_size())
        self.background.fill(COLOR_WHITE)
        self.background = self.background.convert()

        self.make_grid()

    def make_grid(self):
        self.grid = Surface(
            (self.zoom * MAP_SIZE + 1, self.zoom * MAP_SIZE + 1))
        self.grid.fill(COLOR_WHITE)
        draw_grid(self.grid, COLOR_BLACK, self.zoom, 20, 20)
        self.grid = self.grid.convert_alpha()
        self.draw()

    def draw(self):
        self.grid_position = (self.grid_position[0] + self.scrolling[0],
                              self.grid_position[1] + self.scrolling[1])
        self.screen.blit(self.background, POSITION_ZERO)
        self.screen.blit(self.grid, self.grid_position)
        display.flip()

    def start(self):
        while self.is_running:
            self.clock.tick(FPS)
            for e in event.get():
                # handle_events_debug(e, self)
                handle_events_quit(e, self)
                self.handle_grid_scroll(e)
                self.handle_grid_zoom(e)
            self.draw()

    def handle_grid_scroll(self, event):
        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                self.scrolling = (-SCROLL_SPEED, self.scrolling[1])
            if event.key == K_LEFT:
                self.scrolling = (SCROLL_SPEED, self.scrolling[1])
            if event.key == K_UP:
                self.scrolling = (self.scrolling[0], SCROLL_SPEED)
            if event.key == K_DOWN:
                self.scrolling = (self.scrolling[0], -SCROLL_SPEED)
        elif event.type == KEYUP:
            if event.key == K_RIGHT:
                self.scrolling = (0, self.scrolling[1])
            if event.key == K_LEFT:
                self.scrolling = (0, self.scrolling[1])
            if event.key == K_UP:
                self.scrolling = (self.scrolling[0], 0)
            if event.key == K_DOWN:
                self.scrolling = (self.scrolling[0], 0)

    def handle_grid_zoom(self, event):
        if event.type == KEYDOWN:
            if event.key == K_EQUALS:
                self.zoom = self.zoom + 10
                self.make_grid()
            if event.key == K_MINUS:
                if self.zoom > 10:
                    self.zoom = self.zoom - 10
                    self.make_grid()
Exemple #26
0
 def get_image(self, component):
     surf = Surface((400, 400), SRCALPHA)
     surf = surf.convert_alpha()
     return self.blit_on(component, surf)
Exemple #27
0
class hud:

    def __init__(self, statusBarWidth=100, hpBarHeight=25, spBarHeight=10,
        screenWidth=1024, screenHeight=768, HPBarMaxColor=(50,20,20),
        SPBarMaxColor=(100,100,100), HPBarCurrentColor=(155,20,20),
        SPBarCurrentColor=(200,200,200), eventWindowColor = (20,20,20,200), nameMargin = 10):

        self.screenWidth = screenWidth
        self.screenHeight = screenHeight

        self.statusBarWidth = statusBarWidth

        self.HPBarMaxB1Dim = Rect(0,0,self.statusBarWidth,hpBarHeight)
        self.SPBarMaxB1Dim = Rect(0,hpBarHeight,self.statusBarWidth,spBarHeight)
        self.HPBarMaxB2Dim = Rect(self.screenWidth-self.statusBarWidth,0,self.statusBarWidth,hpBarHeight)
        self.SPBarMaxB2Dim = Rect(self.screenWidth-self.statusBarWidth,hpBarHeight,self.statusBarWidth,spBarHeight)

        self.HPBarCurrentB1Dim = Rect(0,0,self.statusBarWidth,hpBarHeight)
        self.SPBarCurrentB1Dim = Rect(0,hpBarHeight,self.statusBarWidth,spBarHeight)
        self.HPBarCurrentB2Dim = Rect(self.screenWidth-self.statusBarWidth,0,self.statusBarWidth,hpBarHeight)
        self.SPBarCurrentB2Dim = Rect(self.screenWidth-self.statusBarWidth,hpBarHeight,self.statusBarWidth,spBarHeight)

        self.HPBarMaxColor = HPBarMaxColor
        self.SPBarMaxColor = SPBarMaxColor
        self.HPBarCurrentColor = HPBarCurrentColor
        self.SPBarCurrentColor = SPBarCurrentColor

        self.nameMargin = nameMargin

        #self.timeDim = Rect(x,y,Width,Height)

        self.eventWindowDim = Rect(0,self.screenHeight/4*3,self.screenWidth,self.screenHeight)
        self.eventWindowSurface = Surface((int(self.screenWidth),int(self.screenHeight/4)), flags=SRCALPHA)
        self.eventWindowSurface.fill(eventWindowColor)
        self.eventWindowSurface.convert_alpha()
        self.eventWindowTextPos = (10,0)
        self.events = []

        self.timeDim = None


        self.eventWindowColor = eventWindowColor #Color(eventWindowColor[0],eventWindowColor[1],eventWindowColor[2],eventWindowColor[3],)

        self.nameFont = font.SysFont("Arial",12)
        self.timeFont = font.SysFont("Arial",20)
        self.roundFont = font.SysFont("Arial",12)
        self.eventWindowFont = font.SysFont("Arial",12)

    def updateHPBars(self, B1HPpercent, B2HPpercent):
        B1HPCurrentWidth = B1HPpercent * self.statusBarWidth
        B2HPCurrentWidth = B2HPpercent * self.statusBarWidth
        self.HPBarCurrentB1Dim.left = self.statusBarWidth-B1HPCurrentWidth
        self.HPBarCurrentB1Dim.width = B1HPCurrentWidth
        self.HPBarCurrentB2Dim.width = B2HPCurrentWidth


    def updateSPBars(self, B1SPpercent, B2SPpercent):
        B1SPCurrentWidth = B1SPpercent * self.statusBarWidth
        B2SPCurrentWidth = B2SPpercent * self.statusBarWidth

        self.SPBarCurrentB1Dim.left = self.statusBarWidth-B1SPCurrentWidth
        self.SPBarCurrentB1Dim.width = B1SPCurrentWidth
        self.SPBarCurrentB2Dim.width = B2SPCurrentWidth
    def loop_display(self, clicked, hit, miss):
        gameTime, endGame = self.timerData
        if not gameTime and self.timer:
            gameTime = -1

        # Display bg
        self.screen.blit(self.img_background, (0, 0))

        # Display holes
        for position in self.holes:
            self.screen.blit(self.img_hole, position)

        # Display moles
        for mole in self.moles:
            holes = [f for f in self.holes if f not in self.used_holes]
            mole_display = mole.do_display(holes, self.score.level,
                                           not endGame)

            # If new/old hole given
            if len(mole_display) > 1:
                if mole_display[1] == 0:  # New hole
                    self.used_holes.append(mole_display[2])
                else:  # Old hole
                    if mole_display[2] in self.used_holes:
                        self.used_holes.remove(mole_display[2])

            # If should display
            if mole_display[0]:
                # Get pos and display
                pos = mole.get_hole_pos(not endGame)
                self.screen.blit(mole.image, pos)

            # Hammer
            thisHammer = transform.rotate(self.img_mallet.copy(),
                                          (Constants.MALLETROTHIT if clicked
                                           else Constants.MALLETROTNORM))
            hammer_x, hammer_y = mole.get_hammer_pos()
            hammer_x -= thisHammer.get_width() / 5
            hammer_y -= thisHammer.get_height() / 4
            self.screen.blit(thisHammer, (hammer_x, hammer_y))

        # Fade screen if not started or has ended
        if self.timer and (endGame or gameTime == -1):
            overlay = Surface((Constants.GAMEWIDTH, Constants.GAMEHEIGHT),
                              SRCALPHA, 32)
            overlay = overlay.convert_alpha()
            overlay.fill((100, 100, 100, 0.9 * 255))
            self.screen.blit(overlay, (0, 0))

        # Debug data for readout
        debug_data = {}
        if Constants.DEBUGMODE:
            debug_data = {
                "DEBUG":
                True,
                "FPS":
                int(self.clock.get_fps()),
                "MOLES":
                "{}/{}".format(Constants.MOLECOUNT,
                               Constants.HOLEROWS * Constants.HOLECOLUMNS),
                "KEYS":
                "E[H]R[M]T[M0]Y[M+5]U[M-5]I[H0]O[H+5]P[H-5]"
            }

        # Display data readout
        data = self.score.label(timer=gameTime,
                                debug=debug_data,
                                size=(1.5 if endGame else 1))
        self.screen.blit(data, (5, 5))

        # Display hit/miss indicators
        if not endGame:

            # Hit indicator
            if hit:
                self.show_hit = time.get_ticks()
            if self.show_hit > 0 and time.get_ticks(
            ) - self.show_hit <= Constants.MOLEHITHUD:
                hit_label = self.text.get_label("BONK!",
                                                scale=3,
                                                color=(255, 50, 0))
                hit_x = (Constants.GAMEWIDTH - hit_label.get_width()) / 2
                hit_y = (Constants.GAMEHEIGHT - hit_label.get_height()) / 2
                self.screen.blit(hit_label, (hit_x, hit_y))
            else:
                self.show_hit = 0

            # Miss indicator
            if miss:
                self.show_miss = time.get_ticks()
            if self.show_miss > 0 and time.get_ticks(
            ) - self.show_miss <= Constants.MOLEMISSHUD:
                miss_label = self.text.get_label("Miss!",
                                                 scale=2,
                                                 color=(0, 150, 255))
                miss_x = (Constants.GAMEWIDTH - miss_label.get_width()) / 2
                miss_y = (Constants.GAMEHEIGHT + miss_label.get_height()) / 2
                self.screen.blit(miss_label, (miss_x, miss_y))
            else:
                self.show_miss = 0

        # Click to start indicator
        if self.timer and gameTime == -1:
            timer_label = self.text.get_label("Click to begin...",
                                              scale=2,
                                              color=(0, 255, 255))
            timer_x = (Constants.GAMEWIDTH - timer_label.get_width()) / 2
            timer_y = (Constants.GAMEHEIGHT - timer_label.get_height()) / 2
            self.screen.blit(timer_label, (timer_x, timer_y))

        # Time's up indicator
        if self.timer and endGame:
            timer_label_1 = self.text.get_label("Time's up!",
                                                scale=3,
                                                color=(0, 150, 255))
            timer_label_2 = self.text.get_label("Press space to restart...",
                                                scale=2,
                                                color=(0, 150, 255))

            timer_x_1 = (Constants.GAMEWIDTH - timer_label_1.get_width()) / 2
            timer_x_2 = (Constants.GAMEWIDTH - timer_label_2.get_width()) / 2

            timer_y_1 = (Constants.GAMEHEIGHT / 2) - timer_label_1.get_height()
            timer_y_2 = (Constants.GAMEHEIGHT / 2)

            self.screen.blit(timer_label_1, (timer_x_1, timer_y_1))
            self.screen.blit(timer_label_2, (timer_x_2, timer_y_2))
 def set_texture_atlas(self, texture: pygame.Surface):
     self.cached_texture_atlas = texture.convert_alpha()
     self.on_texture_changed()
    def loop_display(self, clicked, hit, miss):
        gameTime, endGame = self.timerData
        if not gameTime and self.timer:
            gameTime = -1

        # Display bg
        self.screen.blit(self.img_background, (0, 0))

        # Display holes
        #有一个防止栈空
        for i in range(1, Constants.HOLEROWS):
            for j in range(Constants.HOLECOLUMNS):
                if (self.vis[i][j] == False):
                    self.screen.blit(self.diamond[j % Constants.HOLECOLUMNS],
                                     self.holes[j][i])
        flag = False
        for i in range(1, Constants.HOLEROWS):
            for j in range(Constants.HOLECOLUMNS):
                if (self.change[i][j] > 0):
                    flag = True
                    self.screen.blit(
                        self.diamond_remove[j % Constants.HOLECOLUMNS],
                        self.holes[j][i])
                    self.change[i][j] -= 1

        if (flag):
            if (self.turn % 2):
                self.screen.blit(self.imagea,
                                 (0 + self.moveset, 200 + self.moveset))
            else:
                self.screen.blit(self.imageb,
                                 (250 - self.moveset, 200 - self.moveset))
            self.moveset += 0.3

        thisHammer = transform.rotate(
            self.img_mallet.copy(),
            (Constants.MALLETROTHIT if clicked else Constants.MALLETROTNORM))
        hammer_x, hammer_y = mouse.get_pos()
        hammer_x -= thisHammer.get_width() / 5
        hammer_y -= thisHammer.get_height() / 4
        self.screen.blit(thisHammer, (hammer_x, hammer_y))

        # Fade screen if not started or has ended
        if self.timer and (endGame or gameTime == -1):
            overlay = Surface((Constants.GAMEWIDTH, Constants.GAMEHEIGHT),
                              SRCALPHA, 32)
            overlay = overlay.convert_alpha()
            #rgb, opacity
            overlay.fill((100, 100, 100, 0.8 * 255))
            self.screen.blit(overlay, (0, 0))

        # Debug data for readout
        debug_data = {}
        if Constants.DEBUGMODE:
            debug_data = {
                "DEBUG":
                True,
                "FPS":
                int(self.clock.get_fps()),
                "MOLES":
                "{}/{}".format(Constants.MOLECOUNT,
                               Constants.HOLEROWS * Constants.HOLECOLUMNS),
                "KEYS":
                "E[H]R[M]T[M0]Y[M+5]U[M-5]I[H0]O[H+5]P[H-5]"
            }

        # Display data readout
        data = self.score.label(timer=gameTime,
                                turn=self.turn,
                                debug=debug_data,
                                size=(1.5 if endGame else 1.5))
        self.screen.blit(data, (5, 5))

        # Display hit/miss indicators
        if not endGame:

            # Hit indicator
            if self.a:
                self.show_hit = time.get_ticks()
                self.a = False
            if self.show_hit > 0 and time.get_ticks(
            ) - self.show_hit <= Constants.MOLEHITHUD:
                hit_label = self.text.get_label("PLAYER 1 DONE",
                                                scale=3,
                                                color=(255, 50, 0))
                hit_x = (Constants.GAMEWIDTH - hit_label.get_width()) / 2
                hit_y = (Constants.GAMEHEIGHT - hit_label.get_height()) / 2
                self.screen.blit(hit_label, (hit_x, hit_y))
            else:
                self.show_hit = 0

            # Miss indicator
            if self.b:
                self.show_miss = time.get_ticks()
                self.b = False
            if self.show_miss > 0 and time.get_ticks(
            ) - self.show_miss <= Constants.MOLEMISSHUD:
                miss_label = self.text.get_label("PLAYER 2 DONE",
                                                 scale=2,
                                                 color=(0, 150, 255))
                miss_x = (Constants.GAMEWIDTH - miss_label.get_width()) / 2
                miss_y = (Constants.GAMEHEIGHT + miss_label.get_height()) / 2
                self.screen.blit(miss_label, (miss_x, miss_y))
            else:
                self.show_miss = 0

        # Click to start indicator
        if self.timer and gameTime == -1:
            timer_label = self.text.get_label("Click to begin...",
                                              scale=2,
                                              color=(0, 255, 255))
            timer_x = (Constants.GAMEWIDTH - timer_label.get_width()) / 2
            timer_y = (Constants.GAMEHEIGHT - timer_label.get_height()) / 2
            self.screen.blit(timer_label, (timer_x, timer_y))

        # Time's up indicator
        if endGame:
            winner = ""
            if (self.time_out and self.turn % 2):
                winner = "YOU PLAY BETTER THAN CXK"
            elif (self.time_out and self.turn % 2 == 0):
                winner = "YOU PALY AS GOOD AS CXK"
            elif (self.tot_stone == 0):
                if (self.turn % 2):
                    winner = "YOU PLAY BETTER THAN CXK"
                else:
                    winner = "YOU PALY AS GOOD AS CXK"
            timer_label_1 = self.text.get_label(winner,
                                                scale=2,
                                                color=(0, 150, 255))
            timer_label_2 = self.text.get_label("Press space to restart...",
                                                scale=2,
                                                color=(0, 150, 255))

            if (self.win_show == False):
                self.win_show = True

            else:
                if (winner == "YOU PLAY BETTER THAN CXK"):
                    self.screen.blit(self.imagea, (150, 70))
                else:
                    self.screen.blit(self.imageb2, (150, 70))

            if (self.victory_play == False):
                self.victory_play = True
                pygame.mixer.music.load("assets/cxkwin.wav")
                pygame.mixer.music.play()

            timer_x_1 = (Constants.GAMEWIDTH - timer_label_1.get_width()) / 2
            timer_x_2 = (Constants.GAMEWIDTH - timer_label_2.get_width()) / 2

            timer_y_1 = (Constants.GAMEHEIGHT / 2) - timer_label_1.get_height()
            timer_y_2 = (Constants.GAMEHEIGHT / 2)

            self.screen.blit(timer_label_1, (timer_x_1, timer_y_1 + 70))
            self.screen.blit(timer_label_2, (timer_x_2, timer_y_2 + 70))
            if (self.back_on == False):
                self.screen.blit(self.i5, (120, 600))
            else:
                self.screen.blit(self.i51, (120, 600))
 def create_surfaces(self):
     self.hole = Surface((self.rect.w, self.rect.h), SRCALPHA)
     circle(self.hole, (0, 0, 0), self.rect.center, self.rect.centerx)
     circle(self.hole, (150, 75, 0), self.rect.center, self.rect.centerx, 3)
     self.sprite = Surface.convert_alpha(scale(load("face.jpg"), (self.sprite_rect.w, self.sprite_rect.w)))
Exemple #32
0
def simple_alpha_frame(size, color=constants.BRIGHT, alpha=200):
    surface = Surface(size, flags=SRCALPHA)
    color = gac(color, alpha)
    surface.fill(color)
    return surface.convert_alpha()
Exemple #33
0
class Level(object):
    """
    Main Level class, handles most of the gameplay
    """
    def __init__(self, screen, draw_offset, control_set, player_color, finish_game):
        """
        Init with... way too many parameters
        :param screen: Main PyGame surface to draw the objects/UI on
        :param draw_offset: Drawing offset used in multiplayer
        :param control_set: Key-set used to control the Paddle
        :param player_color: Color of the player's Paddle
        :param finish_game: Function passed to the constructor, triggered on
        the game end
        :return:
        """
        self.screen = screen
        self.draw_offset = draw_offset
        self.control_set = control_set
        self.prev_input_x = 0
        self.level_number = 1
        self.block_count = 0
        self.player = Player("Derp")
        self.paddle = Paddle(LEVEL_WIDTH/2 - Paddle.WIDTH/2, LEVEL_HEIGHT - 40,
                             player_color, parent=self, owner=self.player)
        self.ball = Ball(self.paddle.rect.x + Paddle.WIDTH/2 - Ball.RADIUS,
                         self.paddle.rect.y - Ball.RADIUS * 2)
        self.items = None
        self.blocks = []
        self.blocks_surface = None
        self.blocks_surface_dirty = True
        self.entities = []
        self.font = Assets.font
        self.score_label = None
        self.lives_label = None
        self.level_label = None
        self.load_level(self.level_number)
        self.finish_game = finish_game

    def handle_input(self, events):
        """
        Handles incoming input events
        :param events: input events from the main app
        :return:
        """
        BONUS_SPAWN_X = 305
        BONUS_SPAWN_Y = 200
        for event in events:
            if event.type == KEYDOWN:
                if event.key == self.control_set[0]:
                    if self.paddle.vx != 0:
                        self.prev_input_x = 1
                    self.paddle.vx = -1

                elif event.key == self.control_set[2]:
                    if self.paddle.vx != 0:
                        self.prev_input_x = -1
                    self.paddle.vx = 1

                # elif event.key == K_SPACE:
                #     self.paddle.change_size(self.paddle.rect.width+10)

                elif event.key == K_1:
                    # self.add_entity(ItemExpand(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 1)

                elif event.key == K_2:
                    # self.add_entity(ItemLaserGun(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 2)

                elif event.key == K_3:
                    # self.add_entity(ItemShrink(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 3)

                elif event.key == K_4:
                    # self.add_entity(ItemPaddleNano(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 4)

                elif event.key == K_5:
                    # self.add_entity(ItemLife(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 5)

                elif event.key == K_6:
                    # self.add_entity(ItemLife(BONUS_SPAWN_X, BONUS_SPAWN_Y))
                    self.spawn_item(BONUS_SPAWN_X, BONUS_SPAWN_Y, 6)

            elif event.type == KEYUP:
                if event.key == self.control_set[0]:
                    if self.prev_input_x < 0:
                        self.prev_input_x = 0
                    elif self.prev_input_x > 0:
                        self.paddle.vx = 1
                        self.prev_input_x = 0
                    else:
                        self.paddle.vx = 0

                elif event.key == self.control_set[2]:
                    if self.prev_input_x > 0:
                        self.prev_input_x = 0
                    elif self.prev_input_x < 0:
                        self.paddle.vx = -1
                        self.prev_input_x = 0
                    else:
                        self.paddle.vx = 0

                elif event.key == self.control_set[1]:
                    if self.ball.docked:
                        self.ball.docked = False
                        self.ball.vx = 1
                        self.ball.vy = -1
                    else:
                        self.paddle.use_attachment()

                elif event.key == K_EQUALS:
                    self.start_level(self.level_number + 1)

    def start_level(self, new_level_num):
        """
        Used to start level, checks the level bounds
        :param new_level_num:
        :return:
        """
        self.ball.docked = True
        self.ball.dead = False

        if new_level_num > get_level_count():
            self.finish_game()
        else:
            if self.level_number < new_level_num:
                self.player.score += self.player.lives * 500
            else:
                self.player.score = 0

            self.load_level(new_level_num)
            self.paddle.change_size(PADDLE_WIDTHS[PADDLE_DEFAULT_WIDTH_INDEX])
            self.paddle.attachments = []
            self.paddle.rect.x = LEVEL_WIDTH/2 - self.paddle.rect.width/2
            self.paddle.rect.y = LEVEL_HEIGHT - 40
            self.player.lives = 3
            self.blocks_surface = Surface((LEVEL_WIDTH, LEVEL_HEIGHT))
            self.blocks_surface_dirty = True

    def load_level(self, new_level_num):
        """
        Parses level from the Character array that is provided by the LevelLoader class
        :param new_level_num: Number of the level, used to construct the filename,
        compute the next level number, and viewed on the UI
        :return:
        """
        loaded_level = LevelLoader.load(LEVELDIR + str(new_level_num).zfill(2) + ".lvl")
        level = loaded_level[0]
        self.items = loaded_level[1]
        self.level_number = new_level_num
        self.blocks = []
        self.entities = []
        self.block_count = 0
        for y in xrange(0, BLOCK_NUM_HEIGHT):
            self.blocks.append([None, ] * BLOCK_NUM_WIDTH)
            for x in xrange(0, BLOCK_NUM_WIDTH):
                if level[y][x] == 'i':
                    self.blocks[y][x] = BlockIndestructible(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                                            PLAYFIELD_PADDING[1] + y * Block.HEIGHT)
                elif level[y][x] == 'm':
                    self.blocks[y][x] = BlockMultiHit(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                                      PLAYFIELD_PADDING[1] + y * Block.HEIGHT)
                    self.block_count += 1
                elif level[y][x] == 'e':
                    self.blocks[y][x] = BlockExplosive(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                                       PLAYFIELD_PADDING[1] + y * Block.HEIGHT)
                    self.block_count += 1
                elif level[y][x] != '0':
                    self.blocks[y][x] = Block(PLAYFIELD_PADDING[0] + x * Block.WIDTH,
                                              PLAYFIELD_PADDING[1] + y * Block.HEIGHT,
                                              int(level[y][x]) - 1)
                    self.block_count += 1

    def add_entity(self, entity):
        """
        Utility function to add new entities to the level. Later, might search for dead entities
        to replace them instead of expanding the list indefinitely
        :param entity:
        :return:
        """
        self.entities.append(entity)

    def spawn_item(self, x, y, item):
        """
        Function used to spawn items from blocks
        :param x: x coordinate of the play-field
        :param y: y coordinate of the play-field
        :param item: item to spawn, leave empty to make it randomly selected
        :return:
        """
        if item == 1:
            self.add_entity(ItemLife(x, y))
        elif item == 2:
            self.add_entity(ItemExpand(x, y))
        elif item == 3:
            self.add_entity(ItemShrink(x, y))
        elif item == 4:
            self.add_entity(ItemLaserGun(x, y))
        elif item == 5:
            self.add_entity(ItemPaddleNano(x, y))
        elif item == 6:
            pass
        elif randint(0, 35) == 0:
            item_type = randint(0, 4)
            if item_type == 0:
                dropped_item = ItemLife(x, y)
            elif item_type == 1:
                dropped_item = ItemExpand(x, y)
            elif item_type == 2:
                dropped_item = ItemShrink(x, y)
            elif item_type == 3:
                dropped_item = ItemLaserGun(x, y)
            else:
                dropped_item = ItemPaddleNano(x, y)
            self.add_entity(dropped_item)

    def block_destruction(self, block, item, func):
        """
        Decides what to do with the block, based on the block type (sigh), and performs
        appropriate action
        :param block: Block to operate on
        :param item: If the block has a hard-assigned item in level, it will be spawned
        :param func: Function of the block that returns its points-value
        :return:
        """
        return_v = func()
        if isinstance(block, BlockExplosive):
            rect = block.rect
            self.entities.append(Explosion(rect.x + rect.width/2 - Explosion.WIDTH/2,
                                           rect.y + rect.height/2 - Explosion.HEIGHT/2))

        if block.dead:
            self.player.add_points(return_v)
            self.block_count -= 1
            if not isinstance(block, BlockExplosive):
                self.spawn_item(block.rect.x, block.rect.y, item)
        self.blocks_surface_dirty = True

    def draw(self):
        """
        Method called each frame to (re)draw the objects and UI
        :return:
        """
        self.screen.blit(Assets.background, (self.draw_offset[0], self.draw_offset[1]))

        self.screen.blit(Assets.border, (self.draw_offset[0], self.draw_offset[1]))
        self.screen.blit(Assets.border, (self.draw_offset[0] + LEVEL_WIDTH - PLAYFIELD_PADDING[0],
                                         self.draw_offset[1]))
        if self.blocks_surface_dirty:
            self.blocks_surface = Surface((LEVEL_WIDTH, LEVEL_HEIGHT), SRCALPHA, 32)
            self.blocks_surface = self.blocks_surface.convert_alpha()
            self.blocks_surface_dirty = False
            for row in self.blocks:
                for block in row:
                    if block is not None and not block.dead:
                        block.draw(self.blocks_surface)
        self.screen.blit(self.blocks_surface, self.draw_offset)
        self.paddle.draw(self.screen, self.draw_offset)

        if not self.ball.dead:
            self.ball.draw(self.screen, self.draw_offset)

        # draw entities
        for entity in self.entities:
            if not entity.dead:
                entity.draw(self.screen, self.draw_offset)

        # draw upper bar
        draw.rect(self.screen, (0, 0, 0), (self.draw_offset[0] + PLAYFIELD_PADDING[0], self.draw_offset[1],
                                           LEVEL_WIDTH - PLAYFIELD_PADDING[0] * 2, PLAYFIELD_PADDING[1]))

        self.screen.blit(self.score_label,
                         (self.draw_offset[0] + PLAYFIELD_PADDING[0] + 10, self.draw_offset[1]))
        self.screen.blit(self.lives_label,
                         (self.draw_offset[0] + PLAYFIELD_PADDING[0] + 150, self.draw_offset[1]))
        self.screen.blit(self.level_label,
                         (self.draw_offset[0] + LEVEL_WIDTH - 100, self.draw_offset[1]))

    def update(self):
        """
        Method called each frame, to update the state of entities based on input events and
        previous state of the game
        :return:
        """
        if self.block_count <= 0:
            self.start_level(self.level_number + 1)
        elif self.player.lives <= 0:
            self.start_level(self.level_number)

        self.paddle.update()
        if self.ball.docked and not self.ball.dead:
            self.ball.rect.x = self.paddle.rect.x + self.paddle.rect.width/2 - self.ball.radius
            self.ball.rect.y = self.paddle.rect.y - self.ball.radius * 2
        elif self.player.lives > 0:
            self.ball.update()
        for entity in self.entities:
            if not entity.dead:
                entity.update()

        self.check_collision()
        self.score_label = self.font.render("SCORE: " + str(self.player.score), 1, (255, 255, 255))
        self.lives_label = self.font.render("LIVES: " + str(self.player.lives), 1, (255, 255, 255))
        self.level_label = self.font.render("LEVEL " + str(self.level_number), 1, (255, 255, 255))

    def check_collision(self):
        """
        Called after input handling and movement of the object, to check and solve collisions
        :return:
        """
        # ball vs paddle
        if self.ball.rect.y < self.paddle.rect.y and \
                sprite.collide_rect(self.paddle, self.ball):
            self.ball.vy = -1  # ball.vy

        # ball vs bottom
        if not self.ball.dead and self.ball.rect.y + self.ball.radius * 2 > LEVEL_HEIGHT:
            self.player.lives -= 1
            if self.player.lives < 1:
                self.ball.dead = True
            else:
                self.ball.rect.x = self.paddle.rect.x + self.paddle.rect.width/2 - self.ball.radius
                self.ball.rect.y = self.paddle.rect.y - self.ball.radius * 2
            self.ball.docked = True
            self.paddle.change_size(PADDLE_WIDTHS[PADDLE_DEFAULT_WIDTH_INDEX])
            self.paddle.attachments = []

        # ball vs blocks
        coll_num = [0, 0, 0]
        coll_num_val = (4, 2, 1)
        ball_grid_x = (self.ball.rect.x - PLAYFIELD_PADDING[0] + self.ball.radius) / Block.WIDTH
        ball_grid_y = (self.ball.rect.y - PLAYFIELD_PADDING[1] + self.ball.radius) / Block.HEIGHT
        for y in range(ball_grid_y - 1, ball_grid_y + 2):
            for x in range(ball_grid_x - 1, ball_grid_x + 2):
                if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT:
                    if self.blocks[y][x] is not None and not self.blocks[y][x].dead and \
                            sprite.collide_rect(self.blocks[y][x], self.ball):
                        self.block_destruction(self.blocks[y][x],
                                               self.items[y][x], self.blocks[y][x].on_collide)

                        coll_num[y - ball_grid_y + 1] += coll_num_val[x - ball_grid_x + 1]

        self.ball.on_collide(coll_num)

        # entities
        for entity in self.entities:
            if not entity.dead:
                # paddle vs items
                if isinstance(entity, Item) and sprite.collide_rect(self.paddle, entity):
                    entity.on_collect(self.paddle)
                    entity.dead = True
                    # self.player.lives += 1
                # explosion vs blocks
                elif isinstance(entity, Explosion) and entity.state > 0:
                    entity_block_x = (entity.rect.x - PLAYFIELD_PADDING[0] +
                                      Explosion.WIDTH/2) / Block.WIDTH
                    entity_block_y = (entity.rect.y - PLAYFIELD_PADDING[1] +
                                      Explosion.HEIGHT/2) / Block.HEIGHT
                    for y in xrange(entity_block_y - 1, entity_block_y + 2):
                        for x in xrange(entity_block_x - 1, entity_block_x + 2):
                            if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT:
                                if self.blocks[y][x] is not None and not self.blocks[y][x].dead:
                                    self.block_destruction(self.blocks[y][x], self.items[y][x],
                                                           self.blocks[y][x].kill)
                elif isinstance(entity, Projectile):
                    entity_block_x = (entity.rect.x - PLAYFIELD_PADDING[0] +
                                      entity.rect.width/2) / Block.WIDTH
                    entity_block_y = (entity.rect.y - PLAYFIELD_PADDING[1] +
                                      entity.rect.height/2) / Block.HEIGHT
                    for y in xrange(entity_block_y - 1, entity_block_y + 2):
                        for x in xrange(entity_block_x - 1, entity_block_x + 2):
                            if 0 <= x < BLOCK_NUM_WIDTH and 0 <= y < BLOCK_NUM_HEIGHT:
                                if self.blocks[y][x] is not None and not self.blocks[y][x].dead \
                                        and sprite.collide_rect(self.blocks[y][x], entity):
                                    self.block_destruction(self.blocks[y][x], self.items[y][x],
                                                           self.blocks[y][x].kill)
                                    entity.on_collide()
Exemple #34
0
def load_pygame(filename):
    """
    load a tiled TMX map for use with pygame
    """

    from pygame import Surface
    import pygame, os

    tiledmap = load_tmx(filename)

    # cache will find duplicate tiles to reduce memory usage
    # mostly this is a problem in the blank areas of a tilemap
    cache = {}

    # just a precaution to make sure tileset images are added in the correct order
    for firstgid, t in sorted([(t.firstgid, t) for t in tiledmap.tilesets]):
        path = os.path.join(os.path.dirname(tiledmap.filename), t.source)

        image = pygame.image.load(path)

        w, h = image.get_rect().size

        tile_size = (t.tilewidth, t.tileheight)

        # some tileset images may be slightly larger than the tiles area
        # ie: may include a banner, copyright, etc.  this compensates for that
        for y in range(0, int(h / t.tileheight) * t.tileheight, t.tileheight):
            for x in range(0, int(w / t.tilewidth) * t.tilewidth, t.tilewidth):

                # somewhat handle transparency, though colorkey handling is not tested
                if t.trans is None:
                    tile = Surface(tile_size, pygame.SRCALPHA)
                else:
                    tile = Surface(tile_size)

                # blit the smaller portion onto a new image from the larger one
                tile.blit(image, (0, 0), ((x, y), tile_size))

                # make a unique id for this image, not sure if this is the best way, but it works
                key = pygame.image.tostring(tile, "RGBA")

                # make sure we don't have a duplicate tile
                try:
                    tile = cache[key]
                except KeyError:
                    if t.trans is None:
                        tile = tile.convert_alpha()
                    else:
                        tile = tile.convert()
                        tile.set_colorkey(t.trans)

                    # update the cache
                    cache[key] = tile

                tiledmap.images.append(tile)

    # correctly handle transformed tiles.  currently flipped tiles
    # work by creating a new gid for the flipped tile and changing the gid
    # in the layer to the new gid.
    for layer in tiledmap.tilelayers:
        for x, y, gid, trans in layer.flipped_tiles:
            fx = trans & FLIP_X == FLIP_X
            fy = trans & FLIP_Y == FLIP_Y

            tile = pygame.transform.flip(tiledmap.images[gid], fx, fy)
            tiledmap.images.append(tile)

            # change the original gid in the layer data to the new gid
            layer.data[y][x] = len(tiledmap.images) - 1

        del layer.flipped_tiles
    del cache

    return tiledmap
def simple_alpha_frame(size, color=constants.BRIGHT, alpha=200):
    surface = Surface(size, flags=SRCALPHA)
    color = gac(color, alpha)
    surface.fill(color)
    return surface.convert_alpha()