示例#1
0
def draw_loop(player, level_map, paper_map, map_console, main_console,
              message_console, status_console, entities, player_state):
    fov = player.fov(level_map, entities)
    re.draw_map(level_map, paper_map, map_console, fov)
    re.draw_all(level_map, map_console, entities, fov)
    re.draw_con(main_console, map_console,
                main_console.width - map_console.width, 0)
    re.draw_con(main_console, status_console, 0, 0)
    re.draw_con(main_console, message_console, status_console.width,
                main_console.height - message_console.height)
    tcod.console_flush()
    re.clear_all(level_map, map_console, entities)
示例#2
0
文件: game.py 项目: TeaTrey/RoguePy
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = tcod.Key()
    mouse = tcod.Mouse()

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None

    while not tcod.console_is_window_closed():
        tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key,
                                 mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], game_state)

        fov_recompute = False

        tcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.', tcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            tcod.console_set_fullscreen(not tcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
示例#3
0
def main():
    # initialise screen dimensions
    screen_width = 80
    screen_height = 50
    # initialise map dimensions
    map_width = 80
    map_height = 45

    # room limits and dimensions
    max_room_size = 10
    min_room_size = 6
    total_room_limit = 30

    colours = {
        'dark_wall': libtcod.Color(60, 49, 32),
        'dark_ground': libtcod.Color(96, 128, 56),
        'npc_colour': libtcod.Color(80, 80, 80)
    }

    # declare player and npcs, put them into a list
    player = Entity(int(screen_width / 2), int(screen_height / 2), '@',
                    libtcod.white)
    npc = Entity(int(screen_width - 10 / 2), int(screen_height / 2), '$',
                 colours.get('npc_colour'))
    entities = [player, npc]

    # initialise the map
    game_map = Map(map_width, map_height)
    game_map.create_map(total_room_limit, min_room_size, max_room_size,
                        map_width, map_height, player)

    # choose font for rendering
    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    # initialise console
    libtcod.console_init_root(screen_width, screen_height, 'Omars Roguelike',
                              False)

    con = libtcod.console_new(screen_width, screen_height)
    # key and mouse presses
    key = libtcod.Key()
    mouse = libtcod.Mouse()

    while not libtcod.console_is_window_closed():
        # checks for mouse or key interrupt
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)
        # renders all entities
        render_all(con, entities, screen_width, screen_height, colours,
                   game_map)
        libtcod.console_flush()

        clear_all(con, entities)
        # checks what action has to be done
        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        if move:
            dx, dy = move
            if not game_map.is_blocked(player.x + dx, player.y + dy) and map_width-1 > player.x + dx > 0 and map_height-1 > \
                    player.y + dy > 0:
                player.move(dx, dy)

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
示例#4
0
    def do_trap(self, map, paper_map, main_console, map_console, fov,
                message_console, messages, entities):
        trap_type = self.traptype
        if trap_type == 0:
            radius = 2
            for z in drawval.CHARS["floor_give"]:
                lc = 0
                for x in range(self.x - radius, self.x + radius + 1):
                    for y in (self.y + lc, self.y - lc):
                        if x > -1 and x < map.width and y > -1 and y < map.height:
                            if map.t_[x][y].type == "floor":
                                map.t_[x][y].char = z
                                map.t_[x][y].fg = drawval.COLORS["floor-bg"]
                                map.t_[x][y].bg = drawval.COLORS["pit-bg"]
                    if x < self.x:
                        lc += 1
                    if x > self.x - 1:
                        lc -= 1

                fov = entities[0].fov(map, entities)
                re.draw_map(map, paper_map, map_console, fov)
                re.draw_all(map, map_console, entities, fov)
                re.draw_con(main_console, map_console,
                            main_console.width - map_console.width, 0)
                re.draw_con(main_console, message_console,
                            main_console.width - map_console.width,
                            main_console.height - message_console.height)
                tcod.console_flush()
                re.clear_all(map, map_console, entities)
                sleep(0.050)

            lc = 0
            for x in range(self.x - radius, self.x + radius + 1):
                for y in (self.y + lc, self.y - lc):
                    if x > -1 and x < map.width and y > -1 and y < map.height:
                        if map.t_[x][y].type == "floor":
                            map.t_[x][y] = mp.newtile(cx.TERRAIN["pit"])
                if x < self.x:
                    lc += 1
                if x > self.x - 1:
                    lc -= 1
            map.walls_and_pits()

        elif trap_type == 1:
            fov = entities[0].fov(map, entities)
            re.draw_map(map, paper_map, map_console, fov)
            re.draw_all(map, map_console, entities, fov)
            re.draw_con(main_console, map_console,
                        main_console.width - map_console.width, 0)
            re.draw_con(main_console, message_console,
                        main_console.width - map_console.width,
                        main_console.height - message_console.height)
            tcod.console_flush()
            re.clear_all(map, map_console, entities)
            sleep(0.080)
            trapeffect_blocked = False
            while trapeffect_blocked == False:
                trapeffect_blocked = entities[0].move(entities[0].lastx,
                                                      entities[0].lasty, map,
                                                      entities, map_console,
                                                      message_console,
                                                      messages, True)
                fov = entities[0].fov(map, entities)
                re.draw_map(map, paper_map, map_console, fov)
                re.draw_all(map, map_console, entities, fov)
                re.draw_con(main_console, map_console,
                            main_console.width - map_console.width, 0)
                re.draw_con(main_console, message_console,
                            main_console.width - map_console.width,
                            main_console.height - message_console.height)
                tcod.console_flush()
                re.clear_all(map, map_console, entities)
                sleep(0.0075)

        elif trap_type == 2:
            fov = entities[0].fov(map, entities)
            re.draw_map(map, paper_map, map_console, fov)
            re.draw_all(map, map_console, entities, fov)
            re.draw_con(main_console, map_console,
                        main_console.width - map_console.width, 0)
            re.draw_con(main_console, message_console,
                        main_console.width - map_console.width,
                        main_console.height - message_console.height)
            tcod.console_flush()
            re.clear_all(map, map_console, entities)
            sleep(0.080)
            entities[0].lastx = entities[0].lastx * -1
            entities[0].lasty = entities[0].lasty * -1
            trapeffect_blocked = False
            while trapeffect_blocked == False:
                trapeffect_blocked = entities[0].move(entities[0].lastx,
                                                      entities[0].lasty, map,
                                                      entities, map_console,
                                                      message_console,
                                                      messages, True)
                fov = entities[0].fov(map, entities)
                re.draw_map(map, paper_map, map_console, fov)
                re.draw_all(map, map_console, entities, fov)
                re.draw_con(main_console, map_console,
                            main_console.width - map_console.width, 0)
                re.draw_con(main_console, message_console,
                            main_console.width - map_console.width,
                            main_console.height - message_console.height)
                tcod.console_flush()
                re.clear_all(map, map_console, entities)
                sleep(0.0075)

        elif trap_type == 3:

            px = self.x * -1
            py = self.y * -1
            while map.t_[self.x + px][self.y + py].type != "floor":
                randz = randint(0, 4)
                if randz == 0:
                    px = 1
                    py = 0
                elif randz == 1:
                    px = -1
                    py = 0
                elif randz == 2:
                    px = 0
                    py = -1
                elif randz == 3:
                    px = 0
                    py = 1

            boulder = Entity(self.x + px,
                             self.y + py,
                             char_input=drawval.CHARS["boulder"],
                             fg="boulder-fg",
                             bg=cx.TERRAIN["floor"]["bg"],
                             hp=100,
                             speed=100,
                             faction=cx.Faction.Enemy,
                             draw_order=cx.DrawOrder.NPC,
                             block_m=True,
                             dispname="Boulder")
            boulder.persistent_x = px * -1
            boulder.persistent_y = py * -1
            entities.append(boulder)
            boulder.block_j = True
            boulder.block_s = True
            boulder.stats.at = 100
            boulder.stats.df = 3
            fov = entities[0].fov(map, entities)
            re.draw_map(map, paper_map, map_console, fov)
            re.draw_all(map, map_console, entities, fov)
            re.draw_con(main_console, map_console,
                        main_console.width - map_console.width, 0)
            re.draw_con(main_console, message_console,
                        main_console.width - map_console.width,
                        main_console.height - message_console.height)
            tcod.console_flush()
            re.clear_all(map, map_console, entities)
            sleep(0.080)

        self.trapstate = -1
        for event in tcod.event.wait(0.5):
            return
示例#5
0
def main():
    tdl.set_font('terminal16x16.png', greyscale=True,
                 altLayout=False)  # Load the font from a png.
    tdl.set_fps(100)

    map_width = 20
    map_height = 20

    room_width = 30
    room_height = 30

    screen_width = room_width + 22
    screen_height = room_height + 22

    root_console = tdl.init(screen_width, screen_height, title='7DRL 2019')
    top_panel_console = tdl.Console(screen_width, 10)
    view_port_console = tdl.Console(room_width, room_height)
    bottom_panel_console = tdl.Console(screen_width, 10)
    message_log = MessageLog(0, 0, screen_width, 9)

    entities = []

    game_map = GameMap(map_width, map_height)

    sword_stats = Weapon(2, 10)
    player_weapon = Item(game_map,
                         "0x0",
                         0,
                         0,
                         "Sword",
                         "|", (255, 255, 255),
                         weapon=sword_stats)
    player_stats = Fighter(hits=10, left_hand=player_weapon)
    player = Actor(game_map,
                   "2x2",
                   15,
                   10,
                   "Player",
                   "@", (255, 255, 255),
                   fighter=player_stats)
    entities.append(player)

    generate_map(game_map, entities, player)

    all_consoles = [
        root_console, view_port_console, bottom_panel_console,
        top_panel_console
    ]

    fov_algorithm = "BASIC"
    fov_light_walls = True
    fov_radius = 50
    fov_recompute = True

    game_state = GameStates.PLAYER_TURN

    while not tdl.event.is_window_closed():
        if fov_recompute:  # Compute the field of view to show changes.
            game_map.rooms[player.map_x][player.map_y]\
                .compute_fov(player.room_x, player.room_y,
                             fov=fov_algorithm, radius=fov_radius, light_walls=fov_light_walls, sphere=True)

            render_all(all_consoles, game_map, entities, player, fov_recompute,
                       message_log)
            tdl.flush()
            clear_all(view_port_console, entities)
            fov_recompute = False

        for event in tdl.event.get():
            if event.type == 'KEYUP':
                user_input = event
                break

        else:
            user_input = None

        if not user_input:
            continue

        action = handle_keys(user_input)

        move = action.get('move')
        exit_game = action.get('exit_game')
        select_hand = action.get('select_hand')
        drop_item = action.get('drop_item')
        pickup_item = action.get('pickup_item')
        shuffle_rooms = action.get('shuffle_rooms')

        player_turn_results = []

        if shuffle_rooms:
            message = game_map.shuffle_rooms(player, entities)
            message_log.add_message(message)
            fov_recompute = True

        # TODO at the moment these functions are doing all the leg work and player_turn_results isn't used. Rectify.

        if select_hand and game_state == GameStates.PLAYER_TURN:
            player.fighter.selected_hand = select_hand
            fov_recompute = True

        if drop_item and game_state == GameStates.PLAYER_TURN:
            message = player.fighter.drop_item(game_map, entities)
            message_log.add_message(message)
            game_state = GameStates.ENEMY_TURN
            fov_recompute = True

        if pickup_item and game_state == GameStates.PLAYER_TURN:
            message = player.fighter.pickup_item(entities)
            message_log.add_message(message)
            game_state = GameStates.ENEMY_TURN
            fov_recompute = True

        if move and game_state == GameStates.PLAYER_TURN:
            dx, dy = move
            destination_room_x = player.room_x + dx
            destination_room_y = player.room_y + dy

            if destination_room_x < 0:
                dx = 0

                if player.map_x - 1 < 0:
                    player.map_x = map_width - 1
                else:
                    player.map_x -= 1

                player.room_x = room_width - 1

            if destination_room_x == room_width:
                destination_room_x -= 1
                dx = 0

                if player.map_x + 1 > map_width - 1:
                    player.map_x = 0
                else:
                    player.map_x += 1

                player.room_x = 0

            if destination_room_y < 0:
                dy = 0

                if player.map_y - 1 < 0:
                    player.map_y = map_height - 1
                else:
                    player.map_y -= 1

                player.room_y = room_height - 1

            if destination_room_y == room_height:
                destination_room_y -= 1
                dy = 0

                if player.map_y + 1 > map_height - 1:
                    player.map_y = 0
                else:
                    player.map_y += 1

                player.room_y = 0

            if game_map.rooms[player.map_x][player.map_y].walkable[
                    destination_room_x, destination_room_y]:
                target = get_blocking_entities_at_location(
                    entities, player.map_x, player.map_y, destination_room_x,
                    destination_room_y)

                if target:  # Combat here
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(
                        attack_results
                    )  # Add the result of the last turn to the list
                    fov_recompute = True

                else:
                    player.move(dx, dy)  # Or just move
                    player.set_current_room(game_map)

                    # TODO: Bug with the new room layouts - some cause change of room to break.
                    print("MapPos: ",
                          player.map_x,
                          ",",
                          player.map_y,
                          end=" / ")
                    print("RoomPos: ", player.room_x, ",", player.room_y)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN  # Switch over the enemy's turn.

        if exit_game:
            return True

        for player_turn_result in player_turn_results:
            message = player_turn_result.get("message")  # Pull any messages
            dead_entity = player_turn_result.get(
                "dead")  # Or anything that died

            if message:
                message_log.add_message(
                    message
                )  # Add the message (if any) to the message log to print on screen.

            if dead_entity:  # If anything died...
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)  # Game over
                else:
                    message = kill_monster(
                        dead_entity
                    )  # Print a death message for monster, add exp

                message_log.add_message(message)  # Print messages to screen.

        player_turn_results.clear()  # Clear ready for next turn.

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.map_x == player.map_x and entity.map_y == player.map_y:
                    if entity.ai:  # If the entity has some intelligence (monsters, npc)
                        enemy_turn_results = entity.ai.take_turn(
                            player, game_map, entities)

                        for enemy_turn_result in enemy_turn_results:  # Same deal as the player turns
                            message = enemy_turn_result.get("message")
                            dead_entity = enemy_turn_result.get("dead")

                            if message:
                                message_log.add_message(message)

                            if dead_entity:
                                if dead_entity == player:
                                    message, game_state = kill_player(
                                        dead_entity)
                                else:
                                    message = kill_monster(dead_entity)

                                message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                        enemy_turn_results.clear()

                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYER_TURN