Beispiel #1
0
    def __init__(self, game):
        Group.__init__(self)

        self.game = game
        self.need_draw = True

        self.key_test_period = 0.25
        self.__tick = 0

        self.rom_executor = RomExecutor()
        self.game_list = RomDataItemsConstructor(
            game.app.config.get("PATHS", "gamelist"))

        self.sdcard_constructor = DirlistItemConstructor(
            game.app.config.get("PATHS", "sdcard"), Executor())

        self.all_constructors = [
            BaseItemConstructor(),  # for favorites
            self.game_list.getConsole("GEN"),  # for gen
            self.game_list.getConsole("SMS"),  # for sms
            self.game_list.getConsole("NES"),  # for nes
            self.game_list.getConsole("SNES"),  # for snes
            self.sdcard_constructor,
            None
        ]

        self.item_constructor = self.all_constructors[0]

        self.bg = Background(game)

        self.title_text = TextSprite("", game.assets["TITLE_FONT"])
        self.update_title_text(self.game.assets["ICONS"][0]['title'])

        self.title_text.centered = True

        self.platform = MainMenuPlatformList(game)
        self.file_list = FileList(game, self.item_constructor)
        self.file_list.deselect_all()

        self.selector_state = MainStage.SELECTRO_ICONS

        #self.add(*[self.bg, self.title_text, self.platform, self.file_list])

        game.app.input.addEvent(input.Input.EVENT_DOWN, self.nextItem)
        game.app.input.addEvent(input.Input.EVENT_UP, self.lastItem)
        game.app.input.addEvent(input.Input.EVENT_NEXT, self.select)
        game.app.input.addEvent(input.Input.EVENT_BACK, self.selectBack)

        game.app.input.addEvent(input.Input.EVENT_LEFT, self.last10Item_list)
        game.app.input.addEvent(input.Input.EVENT_RIGHT, self.next10Item_list)

        self.parts = [self.title_text, self.platform, self.file_list]
Beispiel #2
0
    def __init__(self, app):

        self.app = app
        self.assets = ASSETS

        self.fps_text = TextSprite("fps:00", None, 14)
        self.count = 0
        self.avg_fps = 0

        self.size = [
            720,  # app.config.getint("DISPLAY", "width"),
            576  # app.config.getint("DISPLAY", "height")
        ]

        flags = 0

        if app.config.getboolean("DISPLAY", "fullscreen"):
            flags = pygame.FULLSCREEN

        _tryogl = app.config.getboolean("DISPLAY", "opengl") and pygame.OPENGL

        near = [0, 0]

        # try get hardware asselerated
        _testFlags = flags | pygame.HWSURFACE | _tryogl | pygame.DOUBLEBUF
        _modes = pygame.display.list_modes(32, _testFlags)

        if (_modes != -1 and len(_modes) == 0):
            _modes = pygame.display.list_modes(32, flags)
            #_testFlags = flags

        if (_modes == -1):
            _modes = [self.size]
            #flags = _testFlags

        _nears = [m for m in _modes[::-1] if m[0] >=
                  self.size[0] and m[1] >= self.size[1]]

        if(len(_nears) > 0):
            near = _nears[0]
        try:
            self.virtual_render = pygame.display.set_mode(near, _testFlags, 32)
            print("[MODE] OPENGL (%s), HW (%s), RES: %s" %
                  (_tryogl and 1, (flags & pygame.HWSURFACE), near))
        except Exception as e:
            print("[MODE] Error: \n %s" % e)
            self.virtual_render = pygame.display.set_mode((0, 0), flags)

        self.renderer = pygame.surface.Surface(self.size)

        print('render info:' + str(pygame.display.Info()))
Beispiel #3
0
    def __init__(self, game, item_contructor):
        pygame.sprite.Group.__init__(self)

        self.need_draw = True

        self.__rect = None
        self.last_rect = []

        self.game = game
        self.__item_constructor = item_contructor
        self.items = []
        self.__selected = 0
        self.__deselected = True

        self.page = -1
        self.counters = False  # show numbers near lines

        self.items_pool = []

        _offset = [250, 110]
        self.text_clip_area = pygame.Rect(_offset[0], _offset[1], 450 - 20,
                                          420 - 20)

        for i in range(10):
            _itm = TextSprite("", game.assets['LIST_FONT'], size=36)

            _itm.pos = [_offset[0], _offset[1] + i * (36 + 4)]
            self.items_pool.append(_itm)

        self.page_counter = TextSprite("", game.assets['LIST_FONT'], size=18)
        self.update_counter(1, 1)

        #self.add(*self.items_pool)
        #self.add(self.page_counter)
        self.selected = 0

        self.deselect_all()
Beispiel #4
0
class MainStage(Group):

    app = None
    SELECTRO_ICONS = "icons"
    SELECTOR_LIST = "list"

    def __init__(self, game):
        Group.__init__(self)

        self.game = game
        self.need_draw = True

        self.key_test_period = 0.25
        self.__tick = 0

        self.rom_executor = RomExecutor()
        self.game_list = RomDataItemsConstructor(
            game.app.config.get("PATHS", "gamelist"))

        self.sdcard_constructor = DirlistItemConstructor(
            game.app.config.get("PATHS", "sdcard"), Executor())

        self.all_constructors = [
            BaseItemConstructor(),  # for favorites
            self.game_list.getConsole("GEN"),  # for gen
            self.game_list.getConsole("SMS"),  # for sms
            self.game_list.getConsole("NES"),  # for nes
            self.game_list.getConsole("SNES"),  # for snes
            self.sdcard_constructor,
            None
        ]

        self.item_constructor = self.all_constructors[0]

        self.bg = Background(game)

        self.title_text = TextSprite("", game.assets["TITLE_FONT"])
        self.update_title_text(self.game.assets["ICONS"][0]['title'])

        self.title_text.centered = True

        self.platform = MainMenuPlatformList(game)
        self.file_list = FileList(game, self.item_constructor)
        self.file_list.deselect_all()

        self.selector_state = MainStage.SELECTRO_ICONS

        #self.add(*[self.bg, self.title_text, self.platform, self.file_list])

        game.app.input.addEvent(input.Input.EVENT_DOWN, self.nextItem)
        game.app.input.addEvent(input.Input.EVENT_UP, self.lastItem)
        game.app.input.addEvent(input.Input.EVENT_NEXT, self.select)
        game.app.input.addEvent(input.Input.EVENT_BACK, self.selectBack)

        game.app.input.addEvent(input.Input.EVENT_LEFT, self.last10Item_list)
        game.app.input.addEvent(input.Input.EVENT_RIGHT, self.next10Item_list)

        self.parts = [self.title_text, self.platform, self.file_list]

    # end of init

    def next10Item_list(self):
        if (self.selector_state != MainStage.SELECTOR_LIST):
            return
        self.file_list.selected = (
            1 + self.file_list.selected //
            self.file_list.ITEMS_PER_PAGE) * self.file_list.ITEMS_PER_PAGE

    def last10Item_list(self):
        if (self.selector_state != MainStage.SELECTOR_LIST):
            return
        self.file_list.selected = (
            -1 + self.file_list.selected //
            self.file_list.ITEMS_PER_PAGE) * self.file_list.ITEMS_PER_PAGE

    def nextItem(self):
        self.lastNextItem(1)

    # end of nextItem

    def lastItem(self):
        self.lastNextItem(-1)

    def lastNextItem(self, dir):
        self.__tick = 0
        if (self.selector_state == MainStage.SELECTRO_ICONS):
            self.platform.selected += dir
            _title = self.game.assets["ICONS"][self.platform.selected]['title']
            self.update_title_text(_title)

            self.item_constructor = self.all_constructors[
                self.platform.selected]
            self.file_list.set_items(
                self.item_constructor,
                not isinstance(self.item_constructor, DirlistItemConstructor))
            self.file_list.deselect_all()
        else:
            self.file_list.selected += dir

    # end of lastNextItem

    def select(self):
        if (self.selector_state == MainStage.SELECTRO_ICONS):
            self.selector_state = MainStage.SELECTOR_LIST
            self.file_list.selected = 0
            return

        if (self.selector_state == MainStage.SELECTOR_LIST):

            if (isinstance(self.item_constructor, DirlistItemConstructor)):
                if self.item_constructor.next(self.file_list.selected):
                    self.file_list.set_items(self.item_constructor)
            else:
                rom = self.item_constructor.all[self.file_list.selected]
                print(self.rom_executor.exec(rom))

    # end of select

    def selectBack(self):

        if (self.selector_state == MainStage.SELECTOR_LIST):
            self.selector_state = MainStage.SELECTRO_ICONS
            self.file_list.deselect_all()

    # end of select

    def update_title_text(self, text):

        self.title_text.set_text(text)
        self.title_text.pos = [
            455 - self.title_text.rect.w / 2, 70 - self.title_text.rect.h / 2
        ]

    # end of update_title_text

    def update(self, dt):

        Group.update(self, dt)
        self.platform.update(dt)

        self.__tick += dt
        if (self.__tick >= self.key_test_period):
            self.__tick = 0
            if (self.game.app.input.keys[input.Input.EVENT_UP]):
                self.lastItem()
            if (self.game.app.input.keys[input.Input.EVENT_DOWN]):
                self.nextItem()

    # end of update

    def draw(self, renderer):
        #Group.draw(self, renderer)

        if (self.need_draw):
            self.bg.draw(renderer)
            self.need_draw = False

        _updated = False

        for p in self.parts:
            if (p.need_draw):

                rs = p.last_rect
                if (not isinstance(rs, list)):
                    rs = [rs]
                for r in rs:
                    renderer.blit(self.bg.image, r, r)

                p.draw(renderer)

                _updated = True

        return _updated
Beispiel #5
0
class Game(object):

    current_stage = None

    def __init__(self, app):

        self.app = app
        self.assets = ASSETS

        self.fps_text = TextSprite("fps:00", None, 14)
        self.count = 0
        self.avg_fps = 0

        self.size = [
            720,  # app.config.getint("DISPLAY", "width"),
            576  # app.config.getint("DISPLAY", "height")
        ]

        flags = 0

        if app.config.getboolean("DISPLAY", "fullscreen"):
            flags = pygame.FULLSCREEN

        _tryogl = app.config.getboolean("DISPLAY", "opengl") and pygame.OPENGL

        near = [0, 0]

        # try get hardware asselerated
        _testFlags = flags | pygame.HWSURFACE | _tryogl | pygame.DOUBLEBUF
        _modes = pygame.display.list_modes(32, _testFlags)

        if (_modes != -1 and len(_modes) == 0):
            _modes = pygame.display.list_modes(32, flags)
            #_testFlags = flags

        if (_modes == -1):
            _modes = [self.size]
            #flags = _testFlags

        _nears = [m for m in _modes[::-1] if m[0] >=
                  self.size[0] and m[1] >= self.size[1]]

        if(len(_nears) > 0):
            near = _nears[0]
        try:
            self.virtual_render = pygame.display.set_mode(near, _testFlags, 32)
            print("[MODE] OPENGL (%s), HW (%s), RES: %s" %
                  (_tryogl and 1, (flags & pygame.HWSURFACE), near))
        except Exception as e:
            print("[MODE] Error: \n %s" % e)
            self.virtual_render = pygame.display.set_mode((0, 0), flags)

        self.renderer = pygame.surface.Surface(self.size)

        print('render info:' + str(pygame.display.Info()))

    # end of init

    ''' 
    Game start method
    '''

    def start(self):
        self.main_stage = MainStage(self)

        self.current_stage = self.main_stage
    # end off start

    '''
    Game update method
    '''

    def update(self, dt):
        if(self.current_stage != None):
            self.current_stage.update(dt)

        if(dt == 0):
            return

        if(self.count < 0.5):
            self.count += dt
            self.avg_fps = 0.5 * (self.avg_fps + 1 / dt)
        else:
            self.fps_text.set_text("avg fps: %d" % self.avg_fps)
            self.count = 0

    # end of update

    ''' 
    Game render method
    '''

    def render(self):

        _flip = False
        if(self.current_stage != None):
            _flip = self.current_stage.draw(self.renderer)

        if(_flip):
            size = [self.virtual_render.get_width(), self.virtual_render.get_height()]
            pygame.transform.scale(self.renderer, size, self.virtual_render)
            pygame.display.flip()
Beispiel #6
0
    def __init__(self, width, height, world):
        # Initialize PyGame
        pygame.init()

        # Initiate the clock
        self.clock = pygame.time.Clock()

        # Set the window Size
        self.screen_width = width
        self.screen_height = height

        # Create the Screen
        self.screen = pygame.display.set_mode(
            (self.screen_width, self.screen_height), pygame.RESIZABLE)

        # tell pygame to keep sending up keystrokes when they are held down
        pygame.key.set_repeat(500, 30)

        # Setup fonts
        self.font = pygame.font.Font(None, 12)

        self.refresh_screen = True

        self.ordered_sprites = pygame.sprite.LayeredUpdates()
        self.ordered_sprites_dict = {}

        # Sprite used to find what the cursor is selecting
        self.mouse_sprite = None
        # Settings for FPS counter
        self.fps_refresh = DisplayMain.FPS_REFRESH
        self.fps_elapsed = 0
        # Associated with user input
        self.last_mouse_position = pygame.mouse.get_pos()

        # Tools have some global settings/properties, like x/ydims (which determine working area)
        # When tool isn't actually being used it's still updated, to provide highlighting info
        # Most basic tool is the "inspection tool", this will highlight whatever it's over including tiles
        # Terrain raise/lower tool, live preview of affected area
        # Terrain leveling tool, click and drag to select area
        self.lmb_tool = tools.Terrain()
        self.rmb_tool = tools.Move()

        # overlay_sprites is for text that overlays the terrain in the background
        self.overlay_sprites = pygame.sprite.LayeredUpdates()

        # Set up instructions font
        instructions_font = pygame.font.SysFont(pygame.font.get_default_font(),
                                                size=20)
        # Make a text sprite to display the instructions
        self.active_tool_sprite = TextSprite((10, 10),
                                             ["Terrain modification"],
                                             instructions_font,
                                             fg=(0, 0, 0),
                                             bg=(255, 255, 255),
                                             bold=False)
        self.overlay_sprites.add(self.active_tool_sprite, layer=100)

        # Clear the stack of dirty tiles
        self.dirty = []

        self.world = world
Beispiel #7
0
class DisplayMain(object):
    """This handles the main initialisation
    and startup for the display"""

    FPS_REFRESH = 500

    def __init__(self, width, height, world):
        # Initialize PyGame
        pygame.init()

        # Initiate the clock
        self.clock = pygame.time.Clock()

        # Set the window Size
        self.screen_width = width
        self.screen_height = height

        # Create the Screen
        self.screen = pygame.display.set_mode(
            (self.screen_width, self.screen_height), pygame.RESIZABLE)

        # tell pygame to keep sending up keystrokes when they are held down
        pygame.key.set_repeat(500, 30)

        # Setup fonts
        self.font = pygame.font.Font(None, 12)

        self.refresh_screen = True

        self.ordered_sprites = pygame.sprite.LayeredUpdates()
        self.ordered_sprites_dict = {}

        # Sprite used to find what the cursor is selecting
        self.mouse_sprite = None
        # Settings for FPS counter
        self.fps_refresh = DisplayMain.FPS_REFRESH
        self.fps_elapsed = 0
        # Associated with user input
        self.last_mouse_position = pygame.mouse.get_pos()

        # Tools have some global settings/properties, like x/ydims (which determine working area)
        # When tool isn't actually being used it's still updated, to provide highlighting info
        # Most basic tool is the "inspection tool", this will highlight whatever it's over including tiles
        # Terrain raise/lower tool, live preview of affected area
        # Terrain leveling tool, click and drag to select area
        self.lmb_tool = tools.Terrain()
        self.rmb_tool = tools.Move()

        # overlay_sprites is for text that overlays the terrain in the background
        self.overlay_sprites = pygame.sprite.LayeredUpdates()

        # Set up instructions font
        instructions_font = pygame.font.SysFont(pygame.font.get_default_font(),
                                                size=20)
        # Make a text sprite to display the instructions
        self.active_tool_sprite = TextSprite((10, 10),
                                             ["Terrain modification"],
                                             instructions_font,
                                             fg=(0, 0, 0),
                                             bg=(255, 255, 255),
                                             bold=False)
        self.overlay_sprites.add(self.active_tool_sprite, layer=100)

        # Clear the stack of dirty tiles
        self.dirty = []

        self.world = world

    def main_loop(self):
        """This is the Main Loop of the Game"""
        while True:
            self.clock.tick(0)
            # If there's a quit event, don't bother parsing the event queue
            if pygame.event.peek(pygame.QUIT):
                pygame.display.quit()
                sys.exit()

            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_F12:
                        pygame.image.save(self.screen, "pytile_sc.png")
                    if not self.lmb_tool.process_key(event.key):
                        # process_key() will always return False if it hasn't processed the key,
                        # so that keys can be used for other things if a tool doesn't want them
                        if event.key == pygame.K_h:
                            # Activate terrain modification mode
                            self.lmb_tool = tools.Terrain()
                            self.active_tool_sprite.text_lines = [
                                "Terrain modification"
                            ]
                            self.dirty.append(self.active_tool_sprite.update())

                        # Some tools may use the escape key
                        if event.key == pygame.K_ESCAPE:
                            pygame.display.quit()
                            sys.exit()

                if event.type == pygame.MOUSEBUTTONDOWN:
                    # LMB
                    if event.button == 1:
                        self.lmb_tool.mouse_down(event.pos,
                                                 self.ordered_sprites)
                    # RMB
                    if event.button == 3:
                        self.rmb_tool.mouse_down(event.pos,
                                                 self.ordered_sprites)
                if event.type == pygame.MOUSEBUTTONUP:
                    # LMB
                    if event.button == 1:
                        self.lmb_tool.mouse_up(event.pos, self.ordered_sprites)
                    # RMB
                    if event.button == 3:
                        self.rmb_tool.mouse_up(event.pos, self.ordered_sprites)
                if event.type == pygame.MOUSEMOTION:
                    # LMB is pressed, update all the time to keep highlight working
                    self.lmb_tool.mouse_move(event.pos, self.ordered_sprites)
                    # RMB is pressed, only update while RMB pressed
                    if event.buttons[2] == 1:
                        self.rmb_tool.mouse_move(event.pos,
                                                 self.ordered_sprites)
                if event.type == pygame.VIDEORESIZE:
                    self.screen_width = event.w
                    self.screen_height = event.h
                    self.screen = pygame.display.set_mode(
                        (self.screen_width, self.screen_height),
                        pygame.RESIZABLE)
                    self.paint_world()
                    self.refresh_screen = True

            if self.lmb_tool.has_aoe_changed():
                # Update the screen to reflect changes made by tools
                aoe = self.lmb_tool.get_last_aoe() + self.lmb_tool.get_aoe()
                self.update_world(aoe, self.lmb_tool.get_highlight())
                self.lmb_tool.set_aoe_changed(False)
                self.lmb_tool.clear_aoe()

            if self.rmb_tool.active():
                # Repaint the entire screen until something better is implemented
                self.paint_world()
                self.refresh_screen = True

            # Write some useful info on the top bar
            self.fps_elapsed += self.clock.get_time()
            if self.fps_elapsed >= self.fps_refresh:
                self.fps_elapsed = 0
                ii = self.lmb_tool.tile
                if ii:
                    layer = self.ordered_sprites.get_layer_of_sprite(ii)
                    pygame.display.set_caption(
                        "FPS: %i | Tile: (%s,%s) of type: %s, layer: %s | dxoff: %s dyoff: %s"
                        % (self.clock.get_fps(), ii.x_world, ii.y_world,
                           ii.type, layer, self.world.dxoff, self.world.dyoff))
                else:
                    pygame.display.set_caption(
                        "FPS: %i | dxoff: %s dyoff: %s" %
                        (self.clock.get_fps(), self.world.dxoff,
                         self.world.dyoff))

            # If land height has been altered, or the screen has been moved
            # we need to refresh the entire screen
            if self.refresh_screen:
                self.screen.fill((0, 0, 0))
                self.ordered_sprites.draw(self.screen)
                self.overlay_sprites.draw(self.screen)
                pygame.display.update()
                self.refresh_screen = False
            else:
                for r in self.dirty:
                    self.screen.fill((0, 0, 0), r)

                self.ordered_sprites.draw(self.screen)
                self.overlay_sprites.draw(self.screen)
                pygame.display.update(self.dirty)

    @staticmethod
    def array_to_string(array):
        """Convert a heightfield array to a string"""
        return "{}{}{}{}".format(*array)

    def update_world(self, tiles, highlight=None):
        """Instead of completely regenerating the entire world, just update certain tiles"""
        # Add all the items in tiles to the checked_nearby hash table
        nearby_tiles = []
        for t in tiles:
            x, y = t
            # Also need to look up tiles at (x-1,y) and (x,y-1) and have them re-evaluate their cliffs too
            # This needs to check that a) that tile hasn't already been re-evaluated and that
            # b) that tile isn't one of the ones which we're checking, i.e. not in tiles
            if (x - 1, y) not in tiles and (x - 1, y) not in nearby_tiles:
                nearby_tiles.append((x - 1, y))

            if (x, y - 1) not in tiles and (x, y - 1) not in nearby_tiles:
                nearby_tiles.append((x, y - 1))

        # This is a direct reference back to the aoe specified in the tool,
        # need to make a copy to use this!
        for t in tiles + nearby_tiles:
            x, y = t
            # If an override is defined in highlight for this tile,
            # update based on that rather than on contents of World
            if highlight and (x, y) in highlight:
                tile = highlight[(x, y)]
            else:
                tile = self.world.array[x][y]
            # Look the tile up in the group using the position, this will give us the tile and all its cliffs
            if (x, y) in self.ordered_sprites_dict:
                tile_set = self.ordered_sprites_dict[(x, y)]
                t = tile_set[0]
                # Add old positions to dirty rect list
                self.dirty.append(t.rect)

                # Calculate layer
                layer = self.get_layer(x, y)

                # Update the tile type
                t.update_type()
                # Update the tile image
                t.update()
                # Update cursor highlight for tile (if it has one)
                if len(tile) >= 4:
                    t.change_highlight(tile[3])
                self.dirty.append(t.update_xyz())

                self.ordered_sprites.remove(tile_set)
                # Recreate the cliffs
                cliffs = self.make_cliffs(x, y)
                cliffs.insert(0, t)

                # Add the regenerated sprites back into the appropriate places
                self.ordered_sprites_dict[(x, y)] = cliffs
                self.ordered_sprites.add(cliffs, layer=layer)

    @staticmethod
    def get_layer(x, y):
        """Return the layer a sprite should be based on some parameters"""
        return (x + y) * 10

    def paint_world(self, highlight=None):
        """Paint the world as a series of sprites
        Includes ground and other objects"""
        # highlight defines tiles which should override the tiles stored in World
        # can be accessed in the same way as World
        self.refresh_screen = True
        self.ordered_sprites.empty(
        )  # This doesn't necessarily delete the sprites though?
        self.ordered_sprites_dict = {}
        # Top-left of view relative to world given by self.dxoff, self.dyoff
        # Find the base-level tile at this position
        top_left_tile_y, top_left_tile_x = self.screen_to_iso(
            self.world.dxoff, self.world.dyoff)
        for x1 in range(int(self.screen_width / p + 1)):
            for y1 in range(int(self.screen_height / p4)):
                x = int(top_left_tile_x - x1 + math.ceil(y1 / 2.0))
                y = int(top_left_tile_y + x1 + math.floor(y1 / 2.0))

                # Tile must be within the bounds of the map
                if (x >= 0 and y >= 0) and (x < self.world.WorldX
                                            and y < self.world.WorldY):
                    # If an override is defined in highlight for this tile,
                    # update based on that rather than on contents of World
                    if highlight and (x, y) in highlight:
                        tile = highlight[(x, y)]
                    else:
                        tile = self.world.array[x][y]
                    layer = self.get_layer(x, y)
                    # Add the main tile
                    tile_type = self.array_to_string(tile[1])
                    t = TileSprite(self.world,
                                   tile_type,
                                   x,
                                   y,
                                   tile[0],
                                   exclude=False)
                    add_to_dict = [t]

                    # Update cursor highlight for tile (if it has one)
                    if len(tile) >= 4:
                        t.change_highlight(tile[3])

                    self.ordered_sprites.add(t, layer=layer)

                    # Add vertical surfaces (cliffs) for this tile (if any)
                    for t in self.make_cliffs(x, y):
                        add_to_dict.append(t)
                        self.ordered_sprites.add(t, layer=layer)
                    self.ordered_sprites_dict[(x, y)] = add_to_dict

    def make_cliffs(self, x, y):
        """Produce a set of cliff sprites to go with a particular tile"""
        result = []
        # a1/a2 are top and right vertices of tile in front/left of the one we're testing
        if x == self.world.WorldX - 1:
            a1 = 0
            a2 = 0
        else:
            a1 = self.world.array[x + 1][y][1][3] + self.world.array[x +
                                                                     1][y][0]
            a2 = self.world.array[x + 1][y][1][2] + self.world.array[x +
                                                                     1][y][0]

        # b1/b2 are left and bottom vertices of tile we're testing
        b1 = self.world.array[x][y][1][0] + self.world.array[x][y][0]
        b2 = self.world.array[x][y][1][1] + self.world.array[x][y][0]

        while b1 > a1 or b2 > a2:
            if b1 > b2:
                b1 -= 1
                tile_type = "CL10"
            elif b1 == b2:
                b1 -= 1
                b2 -= 1
                tile_type = "CL11"
            else:
                b2 -= 1
                tile_type = "CL01"

            result.append(
                TileSprite(self.world, tile_type, x, y, b1, exclude=True))

        # a1/a2 are top and right vertices of tile in front/right of the one we're testing
        if y == self.world.WorldY - 1:
            a1 = 0
            a2 = 0
        else:
            a1 = self.world.array[x][y + 1][1][3] + self.world.array[x][y +
                                                                        1][0]
            a2 = self.world.array[x][y + 1][1][0] + self.world.array[x][y +
                                                                        1][0]

        # b1/b2 are left and bottom vertices of tile we're testing
        b1 = self.world.array[x][y][1][2] + self.world.array[x][y][0]
        b2 = self.world.array[x][y][1][1] + self.world.array[x][y][0]

        while b1 > a1 or b2 > a2:
            if b1 > b2:
                b1 -= 1
                tile_type = "CR10"
            elif b1 == b2:
                b1 -= 1
                b2 -= 1
                tile_type = "CR11"
            else:
                b2 -= 1
                tile_type = "CR01"

            result.append(
                TileSprite(self.world, tile_type, x, y, b1, exclude=True))

        return result

    def screen_to_iso(self, wx, wy):
        """Convert screen coordinates to Iso world coordinates
        returns tuple of iso coords"""
        tile_ratio = 2.0

        # Convert coordinates to be relative to the position of tile (0,0)
        dx = wx - self.world.WorldWidth2
        dy = wy - p2

        # Do some maths
        x = int((dy + (dx / tile_ratio)) / p2)
        y = int((dy - (dx / tile_ratio)) / p2)

        return x, y
Beispiel #8
0
class FileList(pygame.sprite.Group):

    ITEMS_PER_PAGE = 10
    ITEM_SELECTED_COLOR = (171, 249, 59)
    ITEM_DEF_COLOR = None  # (255,255,255)

    def __init__(self, game, item_contructor):
        pygame.sprite.Group.__init__(self)

        self.need_draw = True

        self.__rect = None
        self.last_rect = []

        self.game = game
        self.__item_constructor = item_contructor
        self.items = []
        self.__selected = 0
        self.__deselected = True

        self.page = -1
        self.counters = False  # show numbers near lines

        self.items_pool = []

        _offset = [250, 110]
        self.text_clip_area = pygame.Rect(_offset[0], _offset[1], 450 - 20,
                                          420 - 20)

        for i in range(10):
            _itm = TextSprite("", game.assets['LIST_FONT'], size=36)

            _itm.pos = [_offset[0], _offset[1] + i * (36 + 4)]
            self.items_pool.append(_itm)

        self.page_counter = TextSprite("", game.assets['LIST_FONT'], size=18)
        self.update_counter(1, 1)

        #self.add(*self.items_pool)
        #self.add(self.page_counter)
        self.selected = 0

        self.deselect_all()

    # end of init

    def update_items(self):

        _all = []
        if (self.__item_constructor != None):
            _all = self.__item_constructor.all
            self.items = _all[(self.page - 1) *
                              FileList.ITEMS_PER_PAGE:self.page *
                              FileList.ITEMS_PER_PAGE]
        else:
            self.items = []

        _pages = max(math.ceil(len(_all) / FileList.ITEMS_PER_PAGE), 1)
        self.update_counter(_pages, self.page)

        for idx, itm in enumerate(self.items_pool):

            txt = None
            if (idx < len(self.items)):
                id = idx + (self.page - 1) * FileList.ITEMS_PER_PAGE + 1
                txt = str(self.items[idx])
                if (self.counters):
                    txt = str(id) + ':' + txt

            itm.set_text(txt)
            self.need_draw = self.need_draw or itm.need_draw

        #self.need_draw = True

    # end of update_items

    def set_items(self, new, counters=False):
        self.__item_constructor = new
        self.counters = counters
        self.__deselected = True
        self.update_items()
        self.selected = 0
        #self.need_draw = True

    # end of set_items

    def update_counter(self, all_pages, current_page):

        self.page_counter.set_text('СТРАНИЦА %d ИЗ %d' %
                                   (current_page, all_pages))
        self.page_counter.pos = [
            self.game.size[0] - 40 - self.page_counter.rect.w, 520
        ]

        self.need_draw = self.need_draw or self.page_counter.need_draw

    # end of update_counter

    def deselect_all(self):
        self.items_pool[self.__selected % FileList.ITEMS_PER_PAGE].set_color(
            FileList.ITEM_DEF_COLOR)

        self.__deselected = True
        self.need_draw = True

    @property
    def selected(self):
        return self.__selected

    @selected.setter
    def selected(self, val):

        if (val == self.__selected and not self.__deselected):
            return

        self.__deselected = False

        if (self.__item_constructor != None):
            _all = len(self.__item_constructor.all)
        else:
            _all = 0

        self.items_pool[self.__selected % FileList.ITEMS_PER_PAGE].set_color(
            FileList.ITEM_DEF_COLOR)

        self.__selected = val

        if (self.__selected < 0):
            self.__selected = _all - 1
        elif (self.__selected > _all - 1):
            self.__selected = 0

        _page = self.__selected // FileList.ITEMS_PER_PAGE + 1

        if (_page != self.page):
            self.page = _page
            self.update_items()

        self.items_pool[self.__selected % FileList.ITEMS_PER_PAGE].set_color(
            FileList.ITEM_SELECTED_COLOR)

        self.need_draw = True

    def draw(self, renderer):

        self.need_draw = False

        self.page_counter.draw(renderer)
        self.last_rect = [self.page_counter.last_rect]

        for itm in self.items_pool:
            itm.draw(renderer)
            self.last_rect.append(itm.last_rect)