Exemple #1
0
    def _new_block_from_factory(self, sprite_list, x, y, copy_block=None):
        self.svg = SVG()
        self.svg.set_scale(self.scale)
        self.svg.set_innie([False])
        self.svg.set_outie(False)
        self.svg.set_tab(True)
        self.svg.set_slot(True)

        if copy_block is not None:
            self._left = copy_block._left
            self._top = copy_block._top
            self._right = copy_block._right
            self._bottom = copy_block._bottom
            self.dx = copy_block.dx
            self.ex = copy_block.ex
            self.ey = copy_block.ey
            self.width = copy_block.width
            self.height = copy_block.height
            self.shapes[0] = copy_block.shapes[0]
            if sprite_list is not None:
                self.spr = sprites.Sprite(sprite_list, x, y, self.shapes[0])
                self.spr._margins = copy_block.spr._margins[:]
            if len(copy_block.shapes) > 1:
                self.shapes[1] = copy_block.shapes[1]
            self.docks = copy_block.docks[:]
        else:
            if self.expandable() and self.type == 'block':
                self.svg.set_show(True)

            self._make_block(self.svg)

            if sprite_list is not None:
                self.spr = sprites.Sprite(sprite_list, x, y, self.shapes[0])
                self._set_margins()

        self._set_label_attributes()
        if (self.name == 'number' or self.name == 'string') and \
                len(self.values) > 0:
            for i, v in enumerate(self.values):
                if v is not None:
                    if self.name == 'number':
                        self._set_labels(
                            i,
                            str(v).replace('.', self.block_list.decimal_point))
                    else:
                        self._set_labels(i, str(v))
        elif self.type == 'block' and self.name in CONSTANTS:
            self._set_labels(0, block_names[self.name][0] + ' = ' + \
                                 str(CONSTANTS[self.name]))

        elif self.name in block_names:
            for i, n in enumerate(block_names[self.name]):
                self._set_labels(i, n)

        if copy_block is None and self.spr is not None:
            if self.spr.label_width() > self.spr.label_safe_width():
                self.resize()
    def make_sprites(self):
        sprites = pg.sprite.Group()
        layer = self.tmx_renderer.get_layer('sprites')

        for obj in layer:
            if obj.name == "wanderer":
                sprite = s.Wanderer('player_f', obj.x, obj.y,
                                    obj.properties['direction'])
                sprites.add(sprite)

            if obj.name == 'mover':
                sprite = s.Mover('uncle', obj.x, obj.y)
                sprites.add(sprite)

            if obj.name == 'chicken':
                if self.inventory['chickens']['catch']:
                    if obj.id not in self.inventory['catched_chickens']:
                        sprite = s.Chicken(obj.x, obj.y,
                                           obj.properties['direction'], obj.id)
                        sprites.add(sprite)
                else:
                    sprite = s.Chicken(obj.x, obj.y,
                                       obj.properties['direction'])
                    sprites.add(sprite)

            if obj.name == 'chicken_lost':
                if self.inventory['chickens']['rescue']:
                    if obj.id not in self.inventory['found_items']:
                        sprite = s.Chicken(obj.x, obj.y,
                                           obj.properties['direction'], obj.id,
                                           obj.properties['color'])
                        sprites.add(sprite)

            if obj.name == 'uncle':
                sprite = s.Sprite(obj.name, obj.x, obj.y)
                sprites.add(sprite)

            if 'chicken_rescue' not in self.game_data['active_quests']:
                if obj.name == 'uncle_out':
                    sprite = s.Sprite('uncle', obj.x, obj.y)
                    sprites.add(sprite)
                if obj.name == 'chicken_rgb':
                    sprite = s.Chicken(obj.x, obj.y,
                                       obj.properties['direction'], obj.id,
                                       obj.properties['color'])
                    sprites.add(sprite)
            else:
                if obj.name == 'uncle_in':
                    sprite = s.Sprite('uncle', obj.x, obj.y)
                    sprites.add(sprite)

            if obj.name == 'boat_player':
                sprite = s.Boat(obj.name, obj.x, obj.y, 'right')
                sprites.add(sprite)

        return sprites
Exemple #3
0
	def __init__(self,filename=None):
		self.initialize_metadata()
		self.initialize_waves()
		self.initialize_sfx()
		self.initialize_code()
		self.initialize_gfx()
		if filename:
			self.initialize_waves(True)
			self.initialize_sfx(True)
			with open(filename,"r") as f:
				lines = [l.rstrip() for l in f]
				stage=0
				tag = ""
				for line in lines:
					if not line:
						continue # skip empty lines
					if stage==0:
						if line.startswith("-- "):
							parts=line[3:].split(": ",2)
							self.metadata[parts[0]]=parts[1]
						else:
							stage=1
					if stage==1:
						if not line.startswith("-- <"):
							self.code[0]+="{}\n".format(line)
						else:
							stage=2
					if stage==2:
						match = re.search(r"-- <(.+)>",line)
						if not match:
							raise Exception("Invalid line for stage 2")
						if match.group(1) not in ["TILES","WAVES","SFX","PALETTE"]+["CODE"+str(i) for i in range(8)]:
							raise Exception("Invalid tag!")
						tag = match.group(1)
						if tag.startswith("CODE"):
							self.code[int(tag[-1])]=""
						stage = 3
					elif stage==3:
						if line=="-- </{}>".format(tag):
							stage = 2
						else:
							if tag.startswith("CODE"):
								self.code[int(tag[-1])]+="{}\n".format(line)
								continue
							if tag=="TILES":
								# Sprite class is implemented!
								self.sprites.append(sprites.Sprite(line[3:]))
							elif tag=="PALETTE":
								self.palette = sprites.Palette(line[3:])
							elif tag=="WAVES":
								self.waves.append(line[3:])
							elif tag=="SFX":
								self.sfx.append(line[3:])
Exemple #4
0
 def load_sprites(self, level):
     # load sprites
     self.overlays = pygame.sprite.RenderUpdates()
     # create sprite groups
     block_list = pygame.sprite.Group()
     all_sprites_list = pygame.sprite.Group()
     # get sprites
     for pos, tile in self.level.sprites.items():
         tile = int(tile[0]), int(tile[1])
         thing = sprites.Sprite(pos, tile)
         block_list.add(thing)
         all_sprites_list.add(thing)
     # get player sprite
     tile = [self.level.player['tile'][0], self.level.player['tile'][1]]
     tile = int(tile[0]), int(tile[1])
     pos = (self.level.player['pos'][0], self.level.player['pos'][1])
     pos = int(pos[0]), int(pos[1])
     player = pc.Player(pos, tile)
     all_sprites_list.add(player)
     # return sprite groups and player
     return block_list, all_sprites_list, player
Exemple #5
0
    MAP_CACHE = tileset.TileCache(MAP_TILE_WIDTH, MAP_TILE_HEIGHT)

    # load level
    level = Level()
    level.load_file(arguments['--input'])

    # load sprites
    overlays = pygame.sprite.RenderUpdates()
    things = pygame.sprite.RenderUpdates()

    block_list = pygame.sprite.Group()
    all_sprites_list = pygame.sprite.Group()

    for pos, tile in level.sprites.items():
        tile = int(tile[0]), int(tile[1])
        thing = sprites.Sprite(pos, tile)
        block_list.add(thing)
        all_sprites_list.add(thing)

    # set up player
    tile = [level.player['tile'][0], level.player['tile'][1]]
    tile = int(tile[0]), int(tile[1])
    pos = (level.player['pos'][0], level.player['pos'][1])
    pos = int(pos[0]), int(pos[1])
    player = player.Player(pos, tile)
    all_sprites_list.add(player)

    # set up game clock
    clock = pygame.time.Clock()

    # render level
Exemple #6
0
    def start_element(self, name, attributes):
        if name == 'map':
            self.columns = int(attributes.get('width', None))
            self.lines = int(attributes.get('height', None))
            self.tile_width = int(attributes.get('tilewidth', None))
            self.tile_height = int(attributes.get('tileheight', None))
        elif name == 'image':  # criar um tileset
            # É possível usar mais de um conjunto de peças, mas eles devem ter tamanhos e peças idênticos.
            # chaves de cores transparentes.
            source = attributes.get('source', None)
            transp = attributes.get('trans', None)

            if self.tileset is None:
                self.tileset = Tileset(self.tile_width, self.tile_height)

            self.tileset.add_set(source, ("0x" + str(transp)))
        elif name == 'property':  # armazena propriedades adicionais.
            # adicionar às propriedades do item ou da camada, dependendo da tag pai em que estamos
            if self.in_item:
                self.items[-1].properties[attributes.get(
                    'name', None)] = attributes.get('value', None)
            else:
                self.properties[self.layers][attributes.get(
                    'name', None)] = attributes.get('value', None)
        elif name == 'layer':  # começando a contagem
            self.line = 0
            self.column = 0
            self.layers += 1
            self.properties.append({})
            self.in_item = False
        elif name == 'tile':  # obter informações de cada bloco e colocar no mapa
            # ID do arquivo para fazer referência ao conjunto de blocos
            gid = int(attributes.get('gid', None)) - 1

            if gid < 0:
                gid = 0

            self.cur_row.append(self.tileset.tiles[gid])
            self.column += 1

            if self.column >= self.columns:
                self.line += 1
                self.column = 0
                self.cur_layer.append(self.cur_row)
                self.cur_row = []

            if self.line >= self.lines:
                self.image.append(self.cur_layer)
                self.cur_layer = []
        elif name == 'object':
            # áreas de objetos podem ser pintadas em azulejo ou especificadas manualmente, como no mapa de amostra
            self.in_item = True

            x = int(attributes.get('x', None)) / self.tile_width
            y = int(attributes.get('y', None)) / self.tile_height

            if attributes.get(
                    'type', None
            ) == 'block':  # impede que itens entrem em quadrados contidos
                width = int(attributes.get('width', None)) / self.tile_width
                height = int(attributes.get('height', None)) / self.tile_height

                self.blocking.append(Rect(x, y, width, height))

            if attributes.get('type', None) == 'boulder':  # empurrável
                self.items.append(
                    item.Item(
                        sprites.Sprite('sprites/rock.png', 32, 64,
                                       (0, 198, 198)), Rect(x, y, 1, 1),
                        'boulder'))

            if attributes.get('type', None) == 'girl':
                self.items.append(
                    item.Item(
                        sprites.Sprite('sprites/girl.png', 32, 64,
                                       (0, 198, 198)), Rect(x, y, 1, 1),
                        'person'))

            if attributes.get('type', None) == 'boy':
                self.items.append(
                    item.Item(
                        sprites.Sprite('sprites/boy.png', 32, 64,
                                       (0, 198, 198)), Rect(x, y, 1, 1),
                        'person'))
 def __init__(self, sw, name, x, y, w, h):
     # create sprite from svg file
     self.spr = sprites.Sprite(
         sw.sprites, x, y,
         self.load_image(sw.path, name, w * sw.scale, h * sw.scale))
Exemple #8
0
    def main(self):

        global player

        # Estes assumem valores de 0, -1 ou 1, dependendo se os blocos estão deslizando nesse momento
        # direção. Isso é diferente de se mover, pois leva em consideração a janela que se fecha pelas bordas.
        x_tile_sliding, y_tile_sliding = 0, 0

        # Tudo funciona mesmo com um número par de linhas/colunas visíveis. O jogador simplesmente não está
        # centralizado na superfície da tela.
        mid_x, mid_y = (config.tiles_visible_x -
                        1) / 2, (config.tiles_visible_y - 1) / 2

        # Manuseio especial para objetos ativos no mundo do jogo. Todas as pessoas devem ter uma propriedade de caminho.
        for i in self.tmxhandler.items:
            # Construa o caminho da lista de propriedades analisadas para o mapa
            if i.type == 'person':
                i.path = [int(n) for n in i.properties['path'].split(',')]

        # Estes parâmetros de conjuntos de peças regulares são especificados nos arquivos mundiais XML, mas não há
        # arquivos XML para sprites
        # player para que eles tenham que ser codificados em algum lugar.
        player = item.Item(
            sprites.Sprite('sprites/boy.png', 32, 64, (0, 198, 198)),
            Rect(3, 3, 1, 1), 'player')

        # Adicione o player à lista de itens para que ele colide corretamente e seja pintado como parte do primeiro plano.
        self.tmxhandler.items.append(player)

        # Calcular quais blocos devem ficar visíveis ao redor do player. A visão fixa garante que a câmera não
        # go fora das fronteiras do mundo.
        viewport = Rect(player.position.left - mid_x,
                        player.position.top - mid_y, config.tiles_visible_x,
                        config.tiles_visible_y)
        clamped = viewport.clamp(self.map_edges)

        # A posição do jogador determina quais peças serão sorteadas. Além disso, se o jogador ainda estiver
        # moving, a linha / coluna à direita uma unidade atrás dele também deve ser desenhada.
        for row in range(
                0 - (y_tile_sliding and player.facing[1] == 1),
                config.tiles_visible_y +
            (y_tile_sliding and player.facing[1] == -1)):
            for column in range(
                    0 - (x_tile_sliding and player.facing[0] == 1),
                    config.tiles_visible_x +
                (x_tile_sliding and player.facing[0] == -1)):
                # Blit a área apropriada de uma determinada camada da representação interna do
                # game world no buffer da superfície da tela.
                self.screen.blit(
                    self.tmxhandler.image[layer][row +
                                                 clamped.top][column +
                                                              clamped.left],
                    (column * config.tiles_size +
                     (x_tile_sliding * player.sliding * player.facing[0]),
                     row * config.tiles_size +
                     (y_tile_sliding * player.sliding * player.facing[1]) -
                     16))

        pg.init()

        pg.display.set_caption("Pykemon - Demo")

        # Usamos a biblioteca sax para analisar mapas, caminhos e metadados de blocos dos arquivos XML do mundo do jogo.
        parser = sax.make_parser()
        parser.setContentHandler(self.tmxhandler)

        # moving representa a tecla de direção pressionada agora
        # Se você quiser saber se o jogador está se movendo, player.facing e player.sliding devem ser
        # usado em vez disso, porque a tecla de direção pode ser liberada ou alterada durante o movimento.
        moving = 0, 0
        player.facing = 0, 1

        # Mapas constantes do teclado para vetores de movimento
        moves = {
            K_UP: (0, -1),
            K_DOWN: (0, 1),
            K_LEFT: (-1, 0),
            K_RIGHT: (1, 0)
        }

        # O limitador de quadros está desativado no momento?
        turbo = 0

        # Há um único quadro para ficar parado. Ao deslizar, o item alterna entre a posição imóvel
        # frame e a estrutura de marcha atual (que é alternada a cada passo para que as pernas se alternem)
        animation_cutoffs = (config.tiles_size / 2)

        clock = pg.time.Clock()

        # Estamos gravando atualmente?
        recording = False
        frame = 0
        capture_run = 0

        # Loop principal do jogo
        while True:
            self.screen.fill(255, 0, 255)

            for event in pg.event.get():
                if event.type == QUIT:
                    terminate()

                if event.type == KEYDOWN:
                    if event.key in moves.keys():
                        moving = moves[event.key]

                    if event.key is K_SPACE:  # Segure espaço para desativar o limitador de quadros
                        turbo = True

                    if event.key is K_r:  # Segure r para gravar a saída da tela em muitos PNGs
                        recording = True
                elif event.type == KEYUP:
                    # Não queremos parar se o jogador pressionar e soltar uma tecla de movimento enquanto estiver
                    # movendo em uma direção diferente, para que a direção do movimento seja verificada na tecla
                    # pressionada
                    if event.key in moves.keys() and moves[
                            event.key] == moving:
                        moving = 0, 0

                    if event.key is K_SPACE:  # Restaura o limitador de quadros quando o espaço é liberado
                        turbo = False

                    if event.key is K_r:
                        recording = False
                        capture_run += 1

            # Observe que o movimento do jogador está sendo tratado aqui e não abaixo com o restante dos itens.
            if player.sliding == 0 and moving != (0, 0):
                # Isso retornará falso se o jogador encontrar um obstáculo.
                if player.move(moving):
                    # Mover a janela de visualização com o player
                    viewport.move_ip(moving)
                    # Mova a janela de visualização de volta ao mundo do jogo, se ela acabou de sair.
                    clamped = viewport.clamp(self.map_edges)

                    # Estes cálculos determinam se o jogador deve se mover livremente perto das fronteiras ou deve
                    # ser fixado em o centro de um plano de fundo de rolagem quando distante das bordas. Observe que,
                    # por exemplo, o player pode estar perto do topo do mundo e capaz de se mover livremente na
                    # vertical, mas ainda assim estar fixo no direção horizontal.
                    x_tile_sliding, y_tile_sliding = 0, 0

                    if viewport.left == clamped.left and viewport.move(
                            -1 * moving[0], 0).left == viewport.move(
                                -1 * moving[0], 0).clamp(self.map_edges).left:
                        x_tile_sliding = 1

                    if viewport.top == clamped.top and viewport.move(
                            0, -1 * moving[1]).top == viewport.move(
                                0, -1 * moving[1]).clamp(self.map_edges).top:
                        y_tile_sliding = 1

            # Manipula o movimento de todas as pessoas em todos os quadros, alterando a direção conforme necessário
            # para corresponder ao caminho no arquivo XML.
            for i in self.tmxhandler.items:
                if i.type == 'person':  # Observe que os pedregulhos nunca são chamados para go(), apenas bump_notify()
                    i.go()

            # Primeiro, precisamos escolher todas as camadas não marcadas como oclusivas e desenhá-las em ordem.
            # Isso cria o background em que itens se movem.
            occluding = []

            for layer in range(0, self.tmxhandler.layers):
                if 'occlude' in self.tmxhandler.properties[
                        layer + 1]:  # + 1 porque 0 é o suporte do mapa
                    occluding.append(layer)
                else:
                    self.main(
                    )  # Muitas e muitas variáveis gratuitas passam por aqui

            # Agora, desenhe cada item (incluindo o player), dependendo de estar visível na janela de exibição da
            # câmera.
            for i in self.tmxhandler.items:
                # O deslizamento de um item é definido como tiles_size toda vez que ele se move e diminui em 4 pixels
                # por quadro até it atinge 0 e, nesse ponto, alcançou sua nova posição. Observe que o valor de
                # deslizamento do jogador não é changed até que a camada de oclusão tenha sido desenhada. Isso é
                # necessário porque se a viewport for alterada b Antes de os itens serem desenhados,
                # eles retrocederão 4 pixels no final do movimento deslizante.
                if i is not player and i.sliding > 0:
                    i.sliding -= 4

                # Verifique se o item está visível dentro de três blocos ao redor da janela de visualização e,
                # se estiver, desenhe-o. A visualização deve ser expandida por três peças devido ao pior caso:
                # enquanto um item está deslizando para a direita do jogador, o jogador Move-se para a esquerda. No
                # futuro, posso adicionar uma verificação que permita inflar apenas 2 peças e um inflável direcional
                # dependendo para que lado o jogador está se movendo.
                if clamped.inflate(3, 3).contains(i.position):
                    self.screen.blit(
                        i.sprite.facing[i.facing]
                        [0 if i.sliding < animation_cutoffs else 1 + i.toggle],
                        ((i.position.left - clamped.left) * config.tiles_size -
                         (i.sliding * i.facing[0]),
                         (i.position.top - clamped.top - 1) * config.tiles_size
                         - (i.sliding * i.facing[1]) +
                         (y_tile_sliding * player.sliding * player.facing[1]) -
                         16))

            # Finalmente, desenhe cada camada de oclusão que foi ignorada anteriormente. Essa camada será desenhada
            # em cima dos itens.
            for layer in occluding:
                self.main()

            # E agora que as operações de desenho estão concluídas, atualize o valor deslizante do jogador.
            if player.sliding > 0:
                player.sliding -= 4

            # E agora que as operações de desenho estão concluídas, atualize o valor deslizante do jogador.
            pg.display.update()

            if not turbo:
                clock.tick(30)

            if recording:
                # Exporte a superfície da tela para um arquivo png para fazer vídeos. Isso pode consumir muito espaço
                # em disco se você gravar por mais than alguns segundos. A compactação PNG mata a taxa de quadros,
                # mas os tamanhos dos arquivos são muito mais gerenciáveis.
                pg.image.save(
                    self.screen,
                    'capture/' + 'run' + str(capture_run).zfill(2) + '_f' +
                    str(frame).zfill(5) + '.png')
                frame += 1