def dim_rgb_pct(rgb, pct: float) -> libtcod.Color: """ Dim a colour by a specified amount :param rgb: the RGB colour that you want to dim :param pct: how much do you want to dim it by as a percentage? :return: a libtcod.Color object with the dimmed RGB colour """ r, g, b = rgb r = int(min(max(0, r * pct), 255)) g = int(min(max(0, g * pct), 255)) b = int(min(max(0, b * pct), 255)) return libtcod.Color(r, g, b)
class Constants: window_title = 'Our Glory Shall Not Descend' screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True min_fov_radius = 4 max_monsters_per_room = 3 max_items_per_room = 2 colors = { 'dark_wall': libtcod.Color(1, 1, 111), 'dark_ground': libtcod.Color(49, 51, 152), 'shadowed_wall': libtcod.Color(0, 0, 90), 'shadowed_ground': libtcod.Color(60, 60, 160), 'illuminated_wall': libtcod.Color(130, 110, 50), 'illuminated_ground': libtcod.Color(200, 180, 50) } constants = { 'window_title': window_title, 'screen_width': screen_width, 'screen_height': screen_height, 'bar_width': bar_width, 'panel_height': panel_height, 'panel_y': panel_y, 'message_x': message_x, 'message_width': message_width, 'message_height': message_height, 'map_width': map_width, 'map_height': map_height, 'room_max_size': room_max_size, 'room_min_size': room_min_size, 'max_rooms': max_rooms, 'fov_algorithm': fov_algorithm, 'fov_light_walls': fov_light_walls, 'min_fov_radius': min_fov_radius, 'max_monsters_per_room': max_monsters_per_room, 'max_items_per_room': max_items_per_room, 'colors': colors }
def test_color_math(): color_a = libtcodpy.Color(0, 1, 2) color_b = libtcodpy.Color(0, 10, 20) assert color_a + color_b == libtcodpy.Color(0, 11, 22) assert color_b - color_a == libtcodpy.Color(0, 9, 18) assert libtcodpy.Color(255, 255, 255) * color_a == color_a assert color_a * 100 == libtcodpy.Color(0, 100, 200)
def get_constants(): colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 # Why the constants (except colors) weren't defined inside the dict is # an odd part of the tutorial. Just to allow the copy paste? # A: Because some of them are derived from others constants = { 'window_title': "Roguelike Tutorial Revised", 'screen_width': screen_width, 'screen_height': screen_height, 'bar_width': bar_width, 'panel_height': panel_height, 'panel_y': screen_height - panel_height, 'message_x': bar_width + 2, 'message_width': screen_width - bar_width - 2, 'message_height': panel_height - 1, 'map_width': 80, 'map_height': 43, 'room_max_size': 10, 'room_min_size': 6, 'max_rooms': 30, 'fov_algorithm': 0, # to indicate the default algorithm, 'fov_light_walls': True, # brighten the walls we can see, 'fov_radius': 10, # how far can we see?, 'colors': colors } return constants
def add_item(self, item): results = [] if len(self.items) >= self.capacity: results.append({ 'item_added': None, 'message': Message('You cannot carry any more, your inventory is full', libtcodpy.Color(186, 251, 24)) }) else: results.append({ 'item_added': item, 'message': Message('You pick up the {0}!'.format(item.name), libtcodpy.Color(66, 190, 255)) }) self.items.append(item) return results
def CivGen( Races, Govern ): # -------------------------------------------------------------------- * CIV GEN * ---------------------------------------------------------------------------------- Civs = [] for x in range(CIVILIZED_CIVS): tcod.namegen_parse("./dist/namegen/jice_fantasy.cfg") Name = tcod.namegen_generate("Fantasy male") tcod.namegen_destroy() Name += " Civilization" Race = Races[randint(0, len(Races) - 1)] # Gets stuck here while Race.Form != "civilized": Race = Races[randint(0, len(Races) - 1)] Government = Govern[randint(0, len(Govern) - 1)] Color = Palette[randint(0, len(Palette) - 1)] Flag = FlagGenerator(Color) # Initialize Civ Civs.append(Civ(Race, Name, Government, Color, Flag, 0)) for a in range(TRIBAL_CIVS): tcod.namegen_parse("./dist/namegen/jice_fantasy.cfg") Name = tcod.namegen_generate("Fantasy male") tcod.namegen_destroy() Name += " Tribe" Race = Races[randint(0, len(Races) - 1)] while Race.Form != "tribal": Race = Races[randint(0, len(Races) - 1)] Government = GovernmentType("Tribal", "*PLACE HOLDER*", 2, 50, 0) Color = tcod.Color(randint(0, 255), randint(0, 255), randint(0, 255)) Flag = FlagGenerator(Color) # Initialize Civ Civs.append(Civ(Race, Name, Government, Color, Flag, 0)) print("- Civs Generated -") return Civs
def create_room(self, room): # go through the tiles in the rectangle and make them passable for x in range(room.x1 + 1, room.x2): for y in range(room.y1 + 1, room.y2): self.tiles[x][y].blocked = False self.tiles[x][y].block_sight = False i = randint(0, 50) if i == 1: self.items.insert(0, Entity(x, y, '.', "Stone", tcod.grey)) elif i == 2: self.items.insert(0, Entity(x, y, '"', "Grass", colors.get('grass'))) elif i == 3: self.entities.insert(0, Entity(x, y, 'b', "Bat", tcod.Color(100, 60, 50)))
def average_color(*colors): rs = 0 gs = 0 bs = 0 for color in colors: rs += color.r gs += color.g bs += color.b n = len(colors) return tcod.Color( rs // n, gs // n, bs // n, )
def get_colors(): colors = { 'blink': tcod.Color(255, 71, 243), 'dark_wall': tcod.Color(66, 47, 32), 'dark_ground': tcod.Color(110, 78, 54), 'light_wall': tcod.Color(156, 97, 26), #darker orange 'light_ground': tcod.Color(245, 164, 66), #light orange 'black': tcod.Color(0, 0, 0), #CREAtURES 'player': tcod.Color(28, 43, 140), 'bandit': tcod.Color(66, 139, 255), 'troll': tcod.darker_green, 'fox': tcod.orange, } return colors
def cast_lightning(*args, **kwargs): caster = args[0] entities = kwargs.get('entities') fov_map = kwargs.get('fov_map') damage = kwargs.get('damage') maximum_range = kwargs.get('maximum_range') results = [] target = None closest_distance = maximum_range + 1 for entity in entities: if entity.fighter and entity != caster and libtcodpy.map_is_in_fov( fov_map, entity.x, entity.y): distance = caster.distance_to(entity) if distance < closest_distance: target = entity closest_distance = distance if target: results.append({ 'consumed': True, 'target': target, 'message': Message( 'A lighting bolt strikes the {0} with a loud thunder! The damage is {1}' .format(target.name, damage)) }) results.extend(target.fighter.take_damage(damage)) else: results.append({ 'consumed': False, 'target': None, 'message': Message('No enemy is close enough to strike.', libtcodpy.Color(170, 16, 0)) }) return results
def render_all(map): #go through all tiles, and set their background color for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): c = map[x][y].color if toggleDisplay == True: if c >= 112: c = 255 map[x][y].blocked = False map[x][y].block_sight = False else: c = 0 map[x][y].blocked = True map[x][y].block_sight = True wall = map[x][y].block_sight if wall: libtcod.console_set_char_background(con, x, y, colors.get('dark_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background(con, x, y, colors.get('dark_ground'), libtcod.BKGND_SET) else: libtcod.console_set_char_background(con, x, y, libtcod.Color(c-40, c+20, c-10), libtcod.BKGND_SET) #libtcod.console_set_char_background(con, x, y, libtcod.Color(c, c-20, c+50), libtcod.BKGND_SET) #libtcod.console_set_char_background(con, x, y, libtcod.Color(c-50, c-20, c), libtcod.BKGND_SET) #libtcod.console_set_char_background(con, x, y, libtcod.Color(c, c, c-100), libtcod.BKGND_SET) ## yellow violet #color = libtcod.Color(c,c,c) #map[x][y].block_sight #libtcod.console_set_char_background(con, x, y, color, libtcod.BKGND_SET) #draw all objects in the list for object in objects: object.draw() #blit the contents of "con" to the root console libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0)
def create_entities(default_console, player_coordiantes): # Creating entity list entityList = [] # Object has x-position, y-position, console, representitve character and color. # Player object should always be in the 0th index of the EntityStorage list. player = Entity(player_coordiantes[0], player_coordiantes[1], default_console, '@', libtcod.Color(33, 33, 33), True) npc = Entity(player_coordiantes[0] - 1, player_coordiantes[1] - 1, default_console, '@', libtcod.red) # Appending the player to the entity list. entityList.append(player) entityList.append(npc) # Creating and returning an EntityList object that stores all active entities. return EntityStorage(entityList)
def draw_side(game, console): console.clear() # TODO: fix and use background texture code from stars_etc.py # Draw stars for star in game.stars: x = SCREEN_WIDTH * (0.5 - star.right_ascension / 360.0) % SCREEN_WIDTH y = SCREEN_HEIGHT * (0.5 - star.declination / 180.0) apmag = int(math.floor(1.0 - star.radial * 256)) tcod.console_put_char_ex(console, int(x), int(y), chr(15), tcod.Color(apmag, apmag, apmag), tcod.black) # Draw orbiting bodies earth_xecl, earth_yecl, earth_zecl = game.orbits['Earth'].position(game.time / DAYS_PER_YEAR) earth_xeq = earth_xecl earth_yeq = earth_yecl * math.cos(OBLIQUITY) + earth_zecl * math.sin(OBLIQUITY) earth_zeq = -earth_yecl * math.sin(OBLIQUITY) + earth_zecl * math.cos(OBLIQUITY) for name, body in game.orbits.items(): if name == 'Earth': continue xecl, yecl, zecl = body.position(game.time / DAYS_PER_YEAR) xeq = xecl - earth_xecl yeq = (yecl - earth_yecl) * math.cos(OBLIQUITY) + (zecl - earth_zecl) * math.sin(OBLIQUITY) zeq = -(yecl - earth_yecl) * math.sin(OBLIQUITY) + (zecl - earth_zecl) * math.cos(OBLIQUITY) screen_x = math.floor(SCREEN_WIDTH * (0.5 - orbit.right_ascension(xeq, yeq) / 360.0) % SCREEN_WIDTH) screen_y = math.floor(SCREEN_HEIGHT * (0.5 - orbit.declination(xeq, yeq, zeq) / 180.0)) tcod.console_put_char_ex(console, int(screen_x), int(screen_y), game.planet_symbols[name], game.planet_colors[name], tcod.black) # Draw sun # TODO: refactor this so the sun isn't special xecl, yecl, zecl = 0, 0, 0 xeq = xecl - earth_xecl yeq = (yecl - earth_yecl) * math.cos(OBLIQUITY) + (zecl - earth_zecl) * math.sin(OBLIQUITY) zeq = -(yecl - earth_yecl) * math.sin(OBLIQUITY) + (zecl - earth_zecl) * math.cos(OBLIQUITY) screen_x = math.floor(SCREEN_WIDTH * (0.5 - orbit.right_ascension(xeq, yeq) / 360.0) % SCREEN_WIDTH) screen_y = math.floor(SCREEN_HEIGHT * (0.5 - orbit.declination(xeq, yeq, zeq) / 180.0)) tcod.console_put_char_ex(console, int(screen_x), int(screen_y), chr(42), tcod.yellow, tcod.black) # TODO: Earth's moon # TODO: camera stuff # info = 'Day: {t:.2f} @ {ts:.2f} d/s; Camera: ({x:.3f}, {z:.3f})\n'.format(t = game.time, ts = game.time_scale, x=game.camera_rot_x, z=game.camera_rot_z) info = 'Day: {t:.2f} @ {ts:.2f} d/s)'.format(t = game.time, ts = game.time_scale) console.print(0, SCREEN_HEIGHT-1, info, fg=tcod.constants.white, bg=tcod.constants.black)
def render_tooltip(x, y, text): if len(text) + 2 > 58: print(text) raise Exception( "Tooltip text is too long. Must be 58 characters or less, string was " + (str(len(text))) + " characters.") ttcon = libtcod.console.Console(len(text) + 4, 3) libtcod.console_set_default_background(ttcon, libtcod.Color(102, 102, 102)) libtcod.console_set_default_foreground(ttcon, libtcod.black) libtcod.console_clear(ttcon) libtcod.console_print_ex(ttcon, 0, 0, libtcod.BKGND_NONE, libtcod.LEFT, chr(201)) libtcod.console_print_ex(ttcon, len(text) + 3, 0, libtcod.BKGND_SET, libtcod.LEFT, chr(187)) libtcod.console_print_ex(ttcon, 0, 2, libtcod.BKGND_SET, libtcod.LEFT, chr(200)) libtcod.console_print_ex(ttcon, len(text) + 3, 2, libtcod.BKGND_SET, libtcod.LEFT, chr(188)) libtcod.console_print_ex(ttcon, 0, 1, libtcod.BKGND_SET, libtcod.LEFT, chr(186)) libtcod.console_print_ex(ttcon, len(text) + 3, 1, libtcod.BKGND_SET, libtcod.LEFT, chr(186)) for tx in range(1, len(text) + 3): libtcod.console_print_ex(ttcon, tx, 0, libtcod.BKGND_SET, libtcod.LEFT, chr(205)) libtcod.console_print_ex(ttcon, tx, 2, libtcod.BKGND_SET, libtcod.LEFT, chr(205)) libtcod.console_set_default_foreground(ttcon, libtcod.white) libtcod.console_print_ex(ttcon, 2, 1, libtcod.BKGND_NONE, libtcod.LEFT, str(text).capitalize()) while ((y - 3) < 1): y = +1 while ((x + len(text) + 4) > 59): x -= 1 libtcod.console_blit(ttcon, 0, 0, 0, 0, 0, x, y)
def new_object(what): objects_list={ "Sompi": Object(0, 0, "S", "Sompi", libtcod.light_green,blocks=True, fighter=Fighter(hp=7, hunger=1000, defense=0, power=10, xp=40, death_function=monster_death), ai=NoobMonster()), "Morko": Object(0, 0, "M", "Morko", libtcod.green,blocks=True, fighter=Fighter(hp=12, hunger=1000, defense=0, power=5, xp=80, death_function=monster_death), ai=BasicMonster()), "Kyrssi": Object(0, 0, "K", "Kyrssi", libtcod.green,blocks=True, fighter=Fighter(hp=30, hunger=1000, defense=10, power=10, xp=200, death_function=monster_death), ai=BasicMonster(a)), "Kaareni": Object(0, 0, "C", "Kaareni", libtcod.gray,blocks=True, fighter=Fighter(hp=20, hunger=1000, defense=0, power=20, xp=60, death_function=monster_death), ai=Wandering()), "Tomuttaja": Object(0, 0, "T", "Tomuttaja", libtcod.red,blocks=True, fighter=Fighter(hp=10, hunger=1000, defense=5, power=10, xp=100, death_function=monster_death), ai=AdvancedMonster()), "Taikajuoma": Object(0, 0, "!", "Taikajuoma", libtcod.purple,blocks=False, item = Item(use_function=spell_heal,use_arguments=[10])), "Puukko": Object(0, 0, "/", "Puukko", libtcod.gray, blocks=False, equipment=Equipment("oikea nyrkki", power_bonus=2)), "Miekka": Object(0, 0, "/", "Miekka", libtcod.gray, blocks=False, equipment=Equipment("oikea nyrkki", power_bonus=5)), "Sauva": Object(0, 0, "/", "Sauva", libtcod.white, blocks=False, equipment=Equipment("oikea nyrkki", power_bonus=15)), "Kilpi": Object(0, 0, "[", "Kilpi", libtcod.white, blocks=False, equipment=Equipment("vasen nyrkki", defense_bonus=5)), "Kakku": Object(0, 0, "%", "Kakku", libtcod.white, blocks=False, item=Item(use_function=spell_eat,use_arguments=[20])), "Mokkapala": Object(0, 0, "%", "Mokkapala", libtcod.Color(210,105,30), blocks=False, item = Item(use_function=spell_eat,use_arguments=[15])), "Impostor_kakku": Object(0, 0, "%", "Kakku", libtcod.gray, blocks=False, item=Item(use_function=spell_explode)), "Arkku": Object(0, 0, "=", "Arkku", libtcod.yellow, blocks=False, actions={"interact":arkku_interact}), } return objects_list[what]
def main(): init() playing = True wina = Window(0, 0, 10, screenheight) winb = Window(0, 0, screenwidth, screenheight) winc = Window(screenwidth // 2, screenheight // 2, 10, 10) winb.print_(50, 20, "Hello World!") winb.print_(0, 20, "Here I am!") wina.print_(0, 0, "Yo Yo Yo") winc.print_(10, 10, '@@YO@@') for y in range(winc.height): for x in range(winc.width): tcod.console_set_char_background(winc, x, y, tcod.Color(20, 20, 20), tcod.BKGND_SET) while not tcod.console_is_window_closed() and playing: root.clear() winb.flush() wina.flush() winc.flush() flip() key = tcod.console_wait_for_keypress(True) if key.vk == tcod.KEY_ENTER and key.lalt: # Alt+Enter: toggle fullscreen tcod.console_set_fullscreen(not tcod.console_is_fullscreen()) elif key.vk == tcod.KEY_ESCAPE: playing = False return if tcod.console_is_key_pressed(tcod.KEY_UP): winc.y -= 1 elif tcod.console_is_key_pressed(tcod.KEY_DOWN): winc.y += 1 elif tcod.console_is_key_pressed(tcod.KEY_LEFT): winc.x -= 1 elif tcod.console_is_key_pressed(tcod.KEY_RIGHT): winc.x += 1
def drop_item(self, item): results = [] if self.owner.equipment.main_hand == item or self.owner.equipment.off_hand == item: self.owner.equipment.toggle_equip(item) item.x = self.owner.x item.y = self.owner.y self.remove_item(item) results.append({ 'item_dropped': item, 'message': Message('You dropped the {0}'.format(item.name), libtcodpy.Color(186, 251, 24)) }) return results
def place_entities(self, room, entities, max_monsters, max_items): # Get random number for monsters num_monsters = randint(0, max_monsters) num_items = randint(0, max_items) for i in range(num_monsters): # Pick a random location in the room x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 +1, room.y2 - 1) if not any([entity for entity in entities if entity.x == x and entity.y == y]): if randint(0, 100) < 80: fighter_comp = Fighter(hp=10, defense=0, power=3) ai_comp = BasicMonster() monster = Entity(x, y, 'O', libtcod.desaturated_green, 'Orc', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_comp, ai=ai_comp) else: fighter_comp = Fighter(hp=16, defense=1, power=4) ai_comp = BasicMonster() monster = Entity(x, y, 'T', libtcod.darker_green, 'Troll', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_comp, ai=ai_comp) entities.append(monster) for i in range(num_items): x = randint(room.x1 + 1, room.x2 - 1) y = randint(room.y1 + 1, room.y2 - 1) if not any([entity for entity in entities if entity.x == x and entity.y == y]): item_chance = randint(0, 100) if item_chance < 70: item_comp = Item(use_function=heal, amount=4) item = Entity(x, y, '!', libtcod.violet, 'Healing Potion', render_order=RenderOrder.ITEM, item=item_comp) else: item_comp = Item(use_function=lightning_attack, damage=20, max_range=5) item = Entity(x, y, '#', libtcod.Color(255, 255, 0), 'Lightning Scroll', render_order=RenderOrder.ITEM, item=item_comp) entities.append(item)
def HeightGradMap( World, ): # ------------------------------------------------------------ Print Map (Heightmap Gradient) ------------------------------------------------------------------- for x in range(WORLD_WIDTH): for y in range(WORLD_HEIGHT): hm_v = World[x][y].height HeightColor = tcod.Color(255, 255, 255) tcod.color_set_hsv( HeightColor, 0, 0, hm_v ) # Set lightness to hm_v so higher heightmap value -> "whiter" tcod.console_put_char_ex( 0, x, y + SCREEN_HEIGHT / 2 - WORLD_HEIGHT / 2, "\333", HeightColor, tcod.black, ) tcod.console_flush() return
def draw_map(con, game_map, fov_map, fov_recompute, colors): if fov_recompute: for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight color = libtcod.Color(0, 0, 0) if visible: if wall: color = colors.get('light_wall') else: color = colors.get('light_ground') game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: color = colors.get('dark_wall') else: color = colors.get('dark_ground') draw_tile(con, x, y, color)
def __init__(self, name, number_of_campers=1, parent=None): super().__init__(name, parent=parent) self.number_of_campers = number_of_campers self.campfire_char = { 'char': '#', 'color': tcod.lightest_orange, 'name': 'Campfire at {0}'.format(name.title()), 'render_order': RenderOrder.ITEM } self.tent_char = { 'char': '^', 'color': tcod.Color(40, 28, 11), 'name': 'Tent at {0}'.format(name) } self.bench_char = { 'char': '_', 'color': tcod.dark_grey, 'name': 'Bench at {0}'.format(name) }
def load_and_create_monster(monster_name, x=None, y=None): Minfo = monster_list.get(monster_name) def loadk(key): return Minfo.get(key) # 기본 정보 불러오기 name = loadk('name') char = loadk('char') # 색상: 문자열 또는 리스트 mon_color = loadk('color') if type(mon_color) == str: color = getattr(tcod, mon_color) else: #리스트 형식일때 color = tcod.Color(i for i in mon_color) # 싸움꾼 부품 mon_fighter = loadk("F_comp") attributes = [ 'hp', 'sanity', 'defense', 'power', ] def create_fighter(*args): for i in args: print(i) create_fighter(mon_fighter) #fighter = tuple((key,value) for key,value in mon_fighter) #print(fighter) #fighter = (i for i in mon_fighter) #print(fighter) # 인공지능 부품 ai = loadk('AI_comp') if not ai: ai = BasicAi()
def color_lookup(x): badlands = tcod.Color(204, 159, 81) ice = tcod.Color(176, 223, 215) darkgreen = tcod.Color(68, 158, 53) lightgreen = tcod.Color(131, 212, 82) water = tcod.Color(13, 103, 196) mountain = tcod.Color(185, 192, 162) desert = tcod.Color(255, 218, 90) return { 0: ice, # ice cap 1: ice, # tundra 2: ice, # subarctic 3: badlands, # dry steppe 4: desert, # dry desert 5: mountain, # highland 6: lightgreen, # humid continental 7: lightgreen, # dry summer subtropic 8: lightgreen, # tropical wet & dry 9: desert, # marine west coast 10: lightgreen, # humid subtropical 11: darkgreen, # wet tropics 12: water, # ocean 13: water, # shallow ocean }[x]
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 colors = { "dark_wall": libtcod.Color(0, 0, 100), "dark_ground": libtcod.Color(50, 50, 150), "light_wall": libtcod.Color(130, 110, 50), "light_ground": libtcod.Color(200, 180, 50), } player = Entity(0, 0, "@", libtcod.white, "Player", blocks=True) entities = [player] libtcod.console_set_custom_font( "arial10x10.png", libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD, ) libtcod.console_init_root( screen_width, screen_height, "libtcod tutorial revisited", False ) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map( max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, ) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov( fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm, ) render_all( con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors, ) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get("move") leave = action.get("exit") fullscreen = action.get("fullscreen") 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: print( f"you kick the {target.name} in the shins, much to its annoyance!" ) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if leave: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity != player: print( f"The {entity.name} ponders the meaning of its existence" ) game_state = GameStates.PLAYERS_TURN
def __init__(self): self.blocked = True self.block_sight = True self.color = tcod.Color(0, 0, 100)
def get_constants(): window_title = "Roguelike RPG" screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 max_items_per_room = 2 max_equipment_items_per_room = 2 colors = { 'dark_wall': libtcod.Color(36, 36, 36), 'dark_ground': libtcod.Color(40, 51, 35), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } constants = { 'window_title': window_title, 'screen_width': screen_width, 'screen_height': screen_height, 'bar_width': bar_width, 'panel_height': panel_height, 'panel_y': panel_y, 'message_x': message_x, 'message_width': message_width, 'message_height': message_height, 'map_width': map_width, 'map_height': map_height, 'room_max_size': room_max_size, 'room_min_size': room_min_size, 'max_rooms': max_rooms, 'fov_algorithm': fov_algorithm, 'fov_light_walls': fov_light_walls, 'fov_radius': fov_radius, 'max_monsters_per_room': max_monsters_per_room, 'max_items_per_room': max_items_per_room, 'max_equipment_items_per_room': max_equipment_items_per_room, 'colors': colors } return constants
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 50 fov_algorithm = 5 fov_light_walls = True fov_radius = 10 max_monster_per_room = 3 max_items_per_room = 2 colors = { 'dark_wall': tcod.Color(0, 0, 100), 'dark_ground': tcod.Color(50, 50, 150), 'light_wall': tcod.Color(130, 110, 50), 'light_ground': tcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Entity(0, 0, "@", tcod.black, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component) entities = [player] tcod.console_set_custom_font( "BBT\\fonts\\arial12x12.png", tcod.FONT_TYPE_GRAYSCALE | tcod.FONT_LAYOUT_TCOD) tcod.console_init_root(screen_width, screen_height, 'Battle Theater', False) con = tcod.console_new(screen_width, screen_height) panel = tcod.console_new(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monster_per_room, max_items_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) 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, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, 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_clikc = 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_result.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: 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 targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) 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 targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN 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
#size of the map MAP_WIDTH = 80 MAP_HEIGHT = 45 #parameters for dungeon generator ROOM_MAX_SIZE = 10 ROOM_MIN_SIZE = 6 MAX_ROOMS = 30 FOV_ALGO = 0 #default FOV algorithm FOV_LIGHT_WALLS = True #light walls or not TORCH_RADIUS = 10 LIMIT_FPS = 20 #20 frames-per-second maximum color_dark_wall = tcod.Color(0, 0, 100) color_light_wall = tcod.Color(130, 110, 50) color_dark_ground = tcod.Color(50, 50, 150) color_light_ground = tcod.Color(200, 180, 50) class Tile: #a tile of the map and its properties def __init__(self, blocked, block_sight=None): self.blocked = blocked #all tiles start unexplored self.explored = False #by default, if a tile is blocked, it also blocks sight if block_sight is None: block_sight = blocked
def get_constants(): maptemplate = ( "###########################", "#............#............#", "#.###.######.#.######.###.#", "#o###.###.........###.###o#", "#.###.###.#######.###.###.#", "#............#............#", "#.###.###### # ######.###.#", "#.......# #.......#", "#######.# ###-### #.#######", "#######.# # B # #.#######", "$........ # CPI # ........$", "#######.# # # #.#######", "#######.# ####### #.#######", "#............#............#", "#.###.######.#.######.###.#", "#o..#...#....@....#...#..o#", "###.###.#.#######.#.###.###", "#.......#....#....#.......#", "#.##########.#.##########.#", "#.........................#", "##########################") debugmaptemplate = ("#######", "#o...o#", "#@ #", "# #", "###=###", "# B#", "#######") colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50), 'overlay_bkg': libtcod.black, 'overlay_border': libtcod.red, 'overlay_text': libtcod.white, 'message_damage': libtcod.amber, 'message_nodamage': libtcod.white, 'scared_ghost': libtcod.azure, 'scared_ghost_unseen': libtcod.darker_azure, } # Map generation will crash if these are not provided because it doesn't check to make sure they exist, just calls the dict entry and hopes placeable_names = { '.': 'dot', 'o': 'superdot', 'B': 'Binky', 'P': 'Pinky', 'I': 'Inky', 'C': 'Clyde', '$': 'warp', '%': 'corpse', '=': 'locked door', } placeable_colors = { '.': libtcod.white, 'o': libtcod.lightest_red, 'B': libtcod.red, 'P': libtcod.lighter_fuchsia, 'I': libtcod.cyan, 'C': libtcod.amber, '$': libtcod.red, '%': libtcod.dark_red, '=': colors['light_wall'], } placeable_unseen_colors = { '.': libtcod.dark_grey, 'o': libtcod.desaturated_red, 'B': libtcod.darker_red, 'P': libtcod.darker_fuchsia, 'I': libtcod.darker_cyan, 'C': libtcod.darker_amber, '$': libtcod.dark_red, '%': libtcod.darkest_red, '=': colors['dark_wall'], } placeable_values = { '.': 10, 'o': 50, } pickup_messages = {'o': Message("Power Overwhelming!", libtcod.cyan)} font = 'arial8x8.png' end_superpill_message = Message("Your power fades...", libtcod.darker_cyan) mobs = "BIPC" items = '.o' renderer = libtcod.RENDERER_GLSL # NOT USED. Shoudl be one of RENDERER_GLSL, RENDERER_OPENGL, RENDERER_OPENGL2, RENDERER_SDL,RENDERER_SDL2. I have no idea what the default it but it works best. DEBUG_use_debug_map = True DEBUG_seeall = False map_starts_revealed = True DEBUG_disableAI = False DEBUG_debuginfo = True DEBUG_show_AI_targets = True always_show_items = True always_show_mobs = True mapoffset = (26, 9) screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 fov_algorithm = 0 fov_light_walls = True fov_radius = 12 window_title = '@man 2019' AI_max_steps = 30 AI_allow_diagonal = False ghost_speed_min = 50 ghost_speed_max = 90 blink_duration = 500 #milliseconds overlay_offset = (20, 10) overlay_size = (40, 7) superpill_duration = 15 ghost_spawn_min = 3 ghost_spawn_max = 10 constants = { 'font': font, 'end_superpill_message': end_superpill_message, 'mobs': mobs, 'items': items, 'renderer': renderer, 'DEBUG_use_debug_map': DEBUG_use_debug_map, 'DEBUG_seeall': DEBUG_seeall, 'map_starts_revealed': map_starts_revealed, 'DEBUG_disableAI': DEBUG_disableAI, 'DEBUG_debuginfo': DEBUG_debuginfo, 'DEBUG_show_AI_targets': DEBUG_show_AI_targets, 'always_show_items': always_show_items, 'always_show_mobs': always_show_mobs, 'maptemplate': maptemplate, 'debugmaptemplate': debugmaptemplate, 'mapoffset': mapoffset, 'colors': colors, 'placeable_names': placeable_names, 'placeable_colors': placeable_colors, 'placeable_unseen_colors': placeable_unseen_colors, 'placeable_values': placeable_values, 'pickup_messages': pickup_messages, 'screen_width': screen_width, 'screen_height': screen_height, 'bar_width': bar_width, 'panel_height': panel_height, 'panel_y': panel_y, 'message_x': message_x, 'message_width': message_width, 'message_height': message_height, 'map_width': map_width, 'map_height': map_height, 'fov_algorithm': fov_algorithm, 'fov_light_walls': fov_light_walls, 'fov_radius': fov_radius, 'window_title': window_title, 'AI_max_steps': AI_max_steps, 'AI_allow_diagonal': AI_allow_diagonal, 'ghost_speed_min': ghost_speed_min, 'ghost_speed_max': ghost_speed_max, 'blink_duration': blink_duration, 'overlay_offset': overlay_offset, 'overlay_size': overlay_size, 'superpill_duration': superpill_duration, 'ghost_spawn_min': ghost_spawn_min, 'ghost_spawn_min': ghost_spawn_min, } return constants
SCREEN_WIDTH = 101 SCREEN_HEIGHT = 81 # size of the game_map MAP_WIDTH = 101 MAP_HEIGHT = 81 # number of the room ROOM_MAX_SIZE = 14 ROOM_MIN_SIZE = 6 MAX_ROOMS = 20 TRIED_TIMES = 2000 LIMIT_FPS = 30 # 20 frames-per-second maximum color_dark_ground = tcod.Color(245, 245, 245) color_dark_wall = tcod.Color(128, 128, 128) class Tile: def __init__(self, blocked, block_sight=None): self.blocked = blocked if block_sight is None: block_sight = blocked self.block_sight = block_sight class Rect(): def __init__(self, x, y, w, h): self.x1 = x