def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.NO_BORDER):
        wx.Panel.__init__(self, parent, id=id, pos=pos, size=size, style=style)

        self.Viewport = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER)
        self.Scrollbar = wx.ScrollBar(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.SB_VERTICAL)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.Viewport, 1, wx.EXPAND, 0)
        sizer.Add(self.Scrollbar, 0, wx.EXPAND, 0)

        self.SetSizer(sizer)
        self.Layout()
        sizer.Fit(self)

        self.Scrollbar.SetScrollbar(0, 0, 0, 0)

        self._presenter = Presenter.from_window(self.Viewport.GetHandle(), config.SCALE)
        self._camera = Camera(0, 0, 0, 0)

        self._tilemap = None
        self._tileset = None
        self._select_start = None
        self._select_end = None

        self._show_collision = False

        self.Viewport.Bind(wx.EVT_PAINT, self.paint)
        self.Viewport.Bind(wx.EVT_SIZE, self.resize)
        self.Viewport.Bind(wx.EVT_MOUSEWHEEL, self.mouse_wheel)
        self.Viewport.Bind(wx.EVT_LEFT_DOWN, self.mouse_left_down)
        self.Viewport.Bind(wx.EVT_LEFT_UP, self.mouse_left_up)
        self.Viewport.Bind(wx.EVT_MOTION, self.mouse_move)
        self.Scrollbar.Bind(wx.EVT_SCROLL, self.scroll)
Exemple #2
0
SCREEN_HEIGHT = 720

HALF_SCREEN_WIDTH = SCREEN_WIDTH // 2
HALF_SCREEN_HEIGHT = SCREEN_HEIGHT // 2


if __name__ == "__main__":
    logging.basicConfig(format="[%(levelname)s @ %(name)s.%(funcName)s:%(lineno)s] %(message)s")
    window = pyglet.window.Window(SCREEN_WIDTH, SCREEN_HEIGHT)

    # create thread pool to allow async pathfinding
    pool = ThreadPoolExecutor(max_workers=2)
    generator = WorldGenerator(15, Vector2(100, 100), Vector2(300, 300), 50)
    # generate default world and dummy enemy
    world = generator.generate()
    camera = Camera(SCREEN_WIDTH, SCREEN_HEIGHT, 2)
    world.entities.append(EnemyEntity(world, Vector2(25, 25)))
    # enable player and give it the default Arrow Attack
    player = Player(world)
    player.skill = BowAttack()
    # add player, initialize labels
    world.entities.append(player)
    fps_display = FPSDisplay(window)
    fps_display.label.x += 200
    support_display = Label("No Active Supports", font_size=12,
                            x=window.width//2, y=12, anchor_x="center", anchor_y="center")
    score_display = Label("Score: ", font_size=12, x=window.width//2, y=24, anchor_x="center", anchor_y="center")

    @window.event
    def on_draw():
        window.clear()
class TileSelector(wx.Panel):

    SelectEvent, EVT_SELECT_EVENT = wx.lib.newevent.NewEvent()

    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.NO_BORDER):
        wx.Panel.__init__(self, parent, id=id, pos=pos, size=size, style=style)

        self.Viewport = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER)
        self.Scrollbar = wx.ScrollBar(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.SB_VERTICAL)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.Viewport, 1, wx.EXPAND, 0)
        sizer.Add(self.Scrollbar, 0, wx.EXPAND, 0)

        self.SetSizer(sizer)
        self.Layout()
        sizer.Fit(self)

        self.Scrollbar.SetScrollbar(0, 0, 0, 0)

        self._presenter = Presenter.from_window(self.Viewport.GetHandle(), config.SCALE)
        self._camera = Camera(0, 0, 0, 0)

        self._tilemap = None
        self._tileset = None
        self._select_start = None
        self._select_end = None

        self._show_collision = False

        self.Viewport.Bind(wx.EVT_PAINT, self.paint)
        self.Viewport.Bind(wx.EVT_SIZE, self.resize)
        self.Viewport.Bind(wx.EVT_MOUSEWHEEL, self.mouse_wheel)
        self.Viewport.Bind(wx.EVT_LEFT_DOWN, self.mouse_left_down)
        self.Viewport.Bind(wx.EVT_LEFT_UP, self.mouse_left_up)
        self.Viewport.Bind(wx.EVT_MOTION, self.mouse_move)
        self.Scrollbar.Bind(wx.EVT_SCROLL, self.scroll)

    def set_tileset(self, tileset):
        self._tileset = tileset
        self.populate_tiles()

        self.Viewport.Refresh(False)

    def populate_tiles(self):
        if not self._tileset:
            self._tilemap.clear()

        surface = self._presenter.surface

        tiles_width = int(math.floor(surface.width / float(Tilemap.TILE_SIZE)))
        tiles_height = int(math.ceil(len(self._tileset.tiles) / float(tiles_width)))

        tiles = range(0, len(self._tileset.tiles))
        self._tilemap = Tilemap(tiles, tiles_width, tiles_height)

        self._camera.set_max(tiles_width * Tilemap.TILE_SIZE, tiles_height * Tilemap.TILE_SIZE)
        self.Scrollbar.SetScrollbar(wx.VERTICAL, 0, surface.height, tiles_height, True)

        self.Scrollbar.SetThumbPosition(0)

    def resize(self, event):
        self._presenter.resize()
        surface = self._presenter.surface

        self._camera.set_size(surface.width, surface.height)

        if self._tileset:
            tiles_width = int(math.floor(surface.width / float(Tilemap.TILE_SIZE)))
            tiles_height = int(math.ceil((len(self._tileset.tiles) / tiles_width) * Tilemap.TILE_SIZE))

            diff = int(tiles_height - surface.height)
            if diff:
                position = self.Scrollbar.GetThumbPosition()
                self.Scrollbar.SetScrollbar(position, surface.height, tiles_height, Tilemap.TILE_SIZE)
            else:
                self.Scrollbar.SetScrollbar(0, 0, 0, 0)

    def paint(self, event):
        if not self._tileset:
            return

        surface = self._presenter.surface
        surface.clear()

        self._camera.move_absolute(0, self.Scrollbar.GetThumbPosition())
        self._tilemap.render(surface, self._camera, self._tileset, self._show_collision)

        if self._select_start:
            x1 = self._select_start[0] * Tilemap.TILE_SIZE
            y1 = self._select_start[1] * Tilemap.TILE_SIZE

            x2 = self._select_end[0] * Tilemap.TILE_SIZE
            y2 = self._select_end[1] * Tilemap.TILE_SIZE

            x1, y1 = self._camera.world_to_camera(x1, y1)
            x2, y2 = self._camera.world_to_camera(x2, y2)

            if x2 < x1:
                x2, x1 = x1, x2
            if y2 < y1:
                y2, y1 = y1, y2

            width = x2 - x1 + Tilemap.TILE_SIZE
            height = y2 - y1 + Tilemap.TILE_SIZE

            surface.box_fill(x1, y1, width, height, 0xFFFFFFFF, BlendOp.ALPHA50)

        self._presenter.present()

    def mouse_wheel(self, event):
        if not self._tileset:
            return

        position = self.Scrollbar.GetThumbPosition()
        position -= (event.GetWheelRotation() / 20) * Tilemap.TILE_SIZE
        self.Scrollbar.SetThumbPosition(position)

        self.Viewport.Refresh(False)

    def mouse_left_down(self, event):
        if not self._tileset:
            return

        if self._select_start:
            return

        pos = event.GetPosition()
        x, y = self.get_tile_position(pos)

        self._select_start = (x, y)
        self._select_end = self._select_start

        self.Viewport.Refresh(False)

    def mouse_left_up(self, event):
        if not self._tilemap:
            return

        if not self._select_end:
            return

        x1, y1 = self._select_start
        x2, y2 = self._select_end

        if x2 < x1:
            x2, x1 = x1, x2
        if y2 < y1:
            y2, y1 = y1, y2

        width = x2 - x1 + 1
        height = y2 - y1 + 1

        self._select_start = None
        self._select_end = None

        self.Viewport.Refresh(False)

        if width and height:
            selection = Tilemap.from_tilemap(self._tilemap, x1, y1, x2 + 1, y2 + 1)
        else:
            selection = None

        event = TileSelector.SelectEvent(selection=selection)
        wx.PostEvent(self.GetEventHandler(), event)

    def mouse_move(self, event):
        if not self._select_start:
            return

        pos = event.GetPosition()
        x, y = self.get_tile_position(pos)

        self._select_end = (x, y)
        self.Viewport.Refresh(False)

    def scroll(self, event):
        self.Viewport.Refresh(False)

    def get_tile_position(self, pos):
        x = pos[0] / self._presenter.scale
        y = pos[1] / self._presenter.scale
        x, y = self._camera.camera_to_world(x, y)
        x /= Tilemap.TILE_SIZE
        y /= Tilemap.TILE_SIZE

        return x, y

    def show_collision(self, show):
        self._show_collision = show
        self.Viewport.Refresh(False)
Exemple #4
0
def start_game(config):
    # Loads game data, setups first map of the game then runs the main game loop.

    # Load all game data.
    tiles_data, generation_data, actor_data, item_data, animation_data = load_data(
    )

    # Initialize map then generate a new map.
    current_map = Map(100, 100)
    start_x, start_y = generate_cave_map(current_map, generation_data,
                                         tiles_data, actor_data, item_data)

    # Initialize camera.
    camera = Camera(0, 0, config['camera_width'], config['camera_height'], 0,
                    0)

    # Spawn player.
    player_stats = {
        "hp": 100,
        "mp": 100,
        "starting_ap": 2,
        "max_ap": 10,
        "ap_recovery": 2,
        "base_damage": "1d4",
        "ac": 10,
        "hit": 4
    }
    player = Actor(start_x, start_y, 'Player', '@', [255, 255, 255, 255])
    player_inventory = Inventory(player)
    player.alive = Alive(player, player_stats, inventory=player_inventory)

    # Initialize FOV.
    fov = FOV(player, 5, current_map)

    under_mouse = None
    debug = False
    game_state = GameState.players_turn
    previous_state = None

    # Setup presets/containers for the game loop.
    actor_queue = PriorityQueue()
    actor_turns_left = False
    animations = []
    no_block_animations = []
    widgets = []
    targeting_action = None

    terminal.refresh()

    while True:
        terminal.clear()
        if not debug:
            if current_map.tiles[player.x][player.y].is_stairs:
                player.x, player.y = generate_cave_map(current_map,
                                                       generation_data,
                                                       tiles_data, actor_data,
                                                       item_data)
                current_map.depth += 1

            render_all(player, current_map, fov, camera, under_mouse,
                       animations, no_block_animations, widgets,
                       targeting_action, game_state, config, animation_data)

            # Parse player input.
            action = handle_input(player, current_map, camera, fov,
                                  under_mouse, widgets, targeting_action,
                                  animations, no_block_animations,
                                  animation_data, game_state)
            under_mouse = get_under_mouse(player, current_map.tiles,
                                          current_map.actors,
                                          current_map.items, widgets, camera,
                                          game_state)

            # If an action was returned, complete that action.
            if isinstance(action, str):
                if action == 'restart':
                    start_game(config)
                elif action == 'end-turn':
                    if player.alive.check_in_combat(current_map.actors, fov):
                        game_state = GameState.actors_turn
                elif action == 'toggle-inventory':
                    if game_state == GameState.show_inventory:
                        game_state = previous_state
                        widgets = []
                    else:
                        previous_state = game_state
                        game_state = GameState.show_inventory
                        fill_widgets(player, widgets, config, game_state)
                elif action == 'toggle-targeting':
                    game_state = previous_state
                    targeting_action = None
                elif action == 'toggle-map':
                    if game_state == GameState.show_full_map:
                        game_state = previous_state
                    else:
                        previous_state = game_state
                        game_state = GameState.show_full_map

            elif action:
                if len(animations) == 0:
                    if game_state == GameState.show_inventory:
                        game_state = previous_state
                        widgets = []
                        if action.item.targeting:
                            previous_state = game_state
                            game_state = GameState.targeting
                            targeting_action = action
                    elif game_state == GameState.targeting:
                        game_state = previous_state
                        targeting_action = None

                    if game_state == GameState.players_turn:
                        action.perform(animations, no_block_animations,
                                       animation_data)

            # Check if camera was moved, if it was, recalculate FOV.
            camera_moved = camera.move_camera(player.x, player.y, current_map)
            if camera_moved:
                fov.fov_recompute()

            # If player is in combat and out of ap, end the players turn.
            if player.alive.check_in_combat(current_map.actors, fov):
                if player.alive.get_ap(False) <= 0:
                    game_state = GameState.actors_turn

            # Only continue if all animations have finished.
            if len(animations) == 0:
                # Go through all actors and let them take turns until
                # they are out of ap or decide not to take any actions.
                if game_state == GameState.actors_turn:

                    # Fill the queue with actors that still need to take turns.
                    if actor_queue.empty():
                        for actor in current_map.actors:
                            if actor.alive and not actor.alive.turn_over and fov.in_fov(
                                    actor):
                                actor_queue.put(actor,
                                                actor.alive.get_ap(False))
                    else:
                        actor = actor_queue.get()
                        if actor.alive:
                            action = actor.alive.get_action(
                                player, current_map, fov)
                            if action:
                                action.perform(animations, no_block_animations,
                                               animation_data)
                                actor_turns_left = True
                            else:
                                actor.alive.turn_over = True

                    # Player recovers ap at the end of the actors turn.
                    if actor_queue.empty():
                        if not actor_turns_left:
                            player.alive.recover_ap()
                            game_state = GameState.players_turn
                            for actor in current_map.actors:
                                if actor.alive:
                                    actor.alive.turn_over = False
                        actor_turns_left = False
        else:
            debug_render(player, current_map)

            # Parse player input.
            action = handle_input(player, current_map, camera)
            if action == 'restart':
                start_game(config)
            if action == 'debug':
                debug = not debug
                terminal.set("window: size='40x20', cellsize='24x24'")

        terminal.refresh()