def main(): screen_width = 80 screen_height = 50 tdl.set_font('arial10x10.png', greyscale=True, altLayout=True) root_console = tdl.init(screen_width, screen_height, title='Roguelike Tutorial Revised') while not tdl.event.is_window_closed(): root_console.draw_char(1, 1, '@', bg=None, fg=(255, 255, 255)) tdl.flush() root_console.draw_char(1, 1, ' ', bg=None) for event in tdl.event.get(): if event.type == 'KEYDOWN': user_input = event break else: user_input = None if not user_input: continue if user_input.key == 'ESCAPE': return True
def wait(timeout=None, flush=True): """Wait for an event. @type timeout: int or None @param timeout: The time in seconds that this function will wait before giving up and returning None. With the default value of None, this will block forever. @type flush: boolean @param flush: If True a call to L{tdl.flush} will be made before listening for events. @rtype: L{Event} or None @return: Returns an instance derived from L{Event}, or None if the function has timed out. Anything added via L{push} will also be returned. @since: 1.4.0 """ if timeout is not None: timeout = timeout + _time.clock() # timeout at this time while True: if _eventQueue: return _eventQueue.pop(0) if flush: # a full 'round' of events need to be processed before flushing _tdl.flush() if timeout and _time.clock() >= timeout: return None # return None on timeout _time.sleep(0.001) # sleep 1ms _processEvents()
def target_tile(self, max_range=None): # return the position of a tile left-clicked in player's FOV (optionally in # a range), or (None,None) if right-clicked. while True: tdl.flush() clicked = False for event in tdl.event.get(): if event.type == 'MOUSEMOTION': self.mouse_controller.mouse_coord = event.cell if event.type == 'MOUSEDOWN' and event.button == 'LEFT': clicked = True elif ((event.type == 'MOUSEDOWN' and event.button == 'RIGHT') or (event.type == 'KEYDOWN' and event.key == 'ESCAPE')): return (None, None) self.camera.render_all_objects() coord = Vector2( *self.mouse_controller.mouse_coord) + self.camera.camera_coord if (clicked and self.map.is_visible_tile(coord.X, coord.Y) and (max_range is None or Vector2.distance(coord, self.player.coord) <= max_range)): self.mouse_controller.set_mouse_coord(coord) return self.mouse_controller.mouse_coord
def __show_window(self, header, options, width): header_wrapped = textwrap.wrap(header, width) header_height = len(header_wrapped) height = len(options) + header_height window = tdl.Console(width, height) window.draw_rect(0, 0, width, height, None, fg=(255, 255, 255), bg=None) for i, line in enumerate(header_wrapped): window.draw_str(0, 0 + i, header_wrapped[i]) y = header_height letter_index = ord('a') for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text window.draw_str(0, y, text, bg=None) y += 1 letter_index += 1 x = UISettings.screen_width // 2 - width // 2 y = UISettings.screen_height // 2 - height // 2 self.__root_console.blit(window, x, y, width, height, 0, 0) tdl.flush()
def target_tile(max_range=None): """ return the position of a tile left-clicked in player's FOV (optionally in a range), or (None,None) if right-clicked. """ global mouse_coord while True: tdl.flush() clicked = False for event in tdl.event.get(): if event.type == 'MOUSEMOTION': mouse_coord = event.cell if event.type == 'MOUSEDOWN' and event.button == 'LEFT': clicked = True elif ((event.type == 'MOUSEDOWN' and event.button == 'RIGHT') or (event.type == 'KEYDOWN' and event.key == 'ESCAPE')): return (None, None) render_all() # accept the target if the player clicked in FOV, and in case # a range is specified, if it's in that range x = mouse_coord[0] y = mouse_coord[1] if (clicked and mouse_coord in visible_tiles and (max_range is None or player.distance(x, y) <= max_range)): return mouse_coord
def draw(self): self.console.clear() for row in self.board: for tile in row: tile.draw(self.console) tdl.flush() tdl.set_title("STEP {0}".format(self.step))
def close_door(self, screen, x, y): '''Allow the player to close a door''' neighbours = self.neighbouring_tiles(x, y) doors = [n for n in neighbours if n.name == 'open_door'] if len(doors) == 1: return doors[0] elif len(doors) > 1: screen.add_message(Message('Select a door...', LIGHT1)) screen.panel.render_messages(screen.messages) tdl.flush() tdl.event.key_wait() keypress = tdl.event.key_wait() keys = ['UP', 'DOWN', 'LEFT', 'RIGHT'] keychars = ['h', 'j', 'k', 'l', 'y', 'u', 'b', 'n'] if keypress.key in keys: key = keypress.key elif keypress.keychar in keychars: key = keypress.keychar else: return None x, y = key_to_coords(key, x, y) tile = screen.current_map.lmap[y][x] if tile.name == 'open_door': return tile else: return None else: return None
def item_interaction_menu(item): ''' interaction menu for a single item ''' panel = gv.inv_panel # panel to draw the window over # draw the item's description window + options draw_item_window(item, settings.SIDE_PANEL_X, settings.STAT_PANEL_HEIGHT, panel.width, panel.height) tdl.flush() key = ' ' # begin a loop waiting for a key. the loop will only quit when ESC is pressed or an item is selected while key != 'ESCAPE': print('item loop') user_input = tdl.event.key_wait() key = user_input.key text = user_input.char if key == 'ESCAPE': return None break if text == 'u': print(text) return 'use' elif text == 'd': print(text) return 'drop' elif text == 'e': print(text) return 'equip'
def target_tile(): '''Display a targeting cursor''' Message( 'Select a target by moving your cursor. Enter to confirm the target, press ESC to cancel.' ) if gv.gamestate is not GameStates.CURSOR_ACTIVE: # If the player-state is not yet targeting, enable it and create the cursor gv.gamestate = GameStates.CURSOR_ACTIVE gv.cursor.activate('X', colors.red) while gv.gamestate == GameStates.CURSOR_ACTIVE: # While the player is considered targeting, suspend game-play to control the cursor and get a target # update the screen render_all() tdl.flush() player_action = handle_keys(tdl.event.key_wait()) if player_action is not None: if 'move' in player_action: # if key is a movement key process input as normal (will move the cursor) process_input(player_action) elif 'confirm' in player_action: # if enter was pressed, return the coordinates of the cursor gv.gamestate = GameStates.ENEMY_TURN gv.cursor.deactivate() return ( gv.cursor.x, gv.cursor.y ) #Return the cursor's current coordinates to the calling function elif 'cancel' in player_action: gv.gamestate = GameStates.ENEMY_TURN gv.cursor.deactivate() break
def play_game(): """ Main loop """ global mouse_coord, fov_recompute player_action = None mouse_coord = (0, 0) fov_recompute = True # unexplored areas start black (which is the default background color) con.clear() while not tdl.event.is_window_closed(): # draw all objects in the list render_all() tdl.flush() # erase all objects at their old locations, before they move for obj in objects: obj.clear() # handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break # let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn': for obj in objects: if obj != player: if obj.ai: obj.ai.take_turn()
def play_game(): global key, mouse, object, turnCount player_action = None key = tdl.event.get() while not tdl.event.is_window_closed(): # tdl.sys_check_for_event(tdl.EVENT_KEY_PRESS|tdl.EVENT_MOUSE, key.mouse) tdl.event.get() render_all() tdl.flush() for object in objects: object.clear() turnCount = 0 turnCount += 1 player_action = handle = handle_keys() if player_action == 'exit': save_game() break if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn()
def target_tile(self, max_range=None): #return the position of a tile left-clicked in player's FOV (optionally in #a range), or (None,None) if right-clicked. while True: #render the screen. this erases the inventory and shows the names of #objects under the mouse. tdl.flush() clicked = False for event in tdl.event.get(): if event.type == 'MOUSEMOTION': self.gui.mouse_coord = event.cell if event.type == 'MOUSEDOWN' and event.button == 'LEFT': clicked = True elif ((event.type == 'MOUSEDOWN' and event.button == 'RIGHT') or (event.type == 'KEYDOWN' and event.key == 'ESCAPE')): return (None, None) render_all(self.world) #accept the target if the player clicked in FOV, and in case a range is #specified, if it's in that range x = self.gui.mouse_coord[0] y = self.gui.mouse_coord[1] if (clicked and mouse_coord in visible_tiles and (max_range is None or player.distance(x, y) <= max_range)): return self.gui.mouse_coord
def play_game(self): """ The main game loop """ while True: # Continue in an infinite game loop. self.game_state = 'playing' if self.player.character_state == 'alive' else None self.console_manager.main_console.clear() # Blank the console. self.render_all() self.monsters = [ m for m in (Character.select().join(DungeonLevel).where( (DungeonLevel.level_id == self.dungeon.level.level_id) & (Character.name != 'player'))) ] self.items = [ item for item in (Item.select().join(DungeonLevel).where(( DungeonLevel.level_id == self.dungeon.level.level_id))) ] if self.player.character_state == 'dead': CONSOLES['status'].drawStr(0, 4, 'You have died!') # TODO: Fix win condition # elif player.character_state == 'done': # STATUS.move(0, 4) # STATUS.printStr('CONGRADULATIONS!\n\nYou have found a Cone of Dunshire!') tdl.flush() # Update the window. self.listen_for_events()
def wait(timeout=None, flush=True): """Wait for an event. Args: timeout (Optional[int]): The time in seconds that this function will wait before giving up and returning None. With the default value of None, this will block forever. flush (bool): If True a call to :any:`tdl.flush` will be made before listening for events. Returns: Type[Event]: An event, or None if the function has timed out. Anything added via :any:`push` will also be returned. """ if timeout is not None: timeout = timeout + _time.clock() # timeout at this time while True: if _eventQueue: return _eventQueue.pop(0) if flush: # a full 'round' of events need to be processed before flushing _tdl.flush() if timeout and _time.clock() >= timeout: return None # return None on timeout _time.sleep(0.001) # sleep 1ms _processEvents()
def update(self, game): # NOTE: run everything in 1 update call, hijacking tdl.flush() from the game loop # copy the root content onto board self.window.blit(game.root, 0, 0, game.screen_width, game.screen_height, 0, 0) rndval = 1 running = True i = 0 while running: y = rndval & 0x000FF x = (rndval & 0x1FF00) >> 8 lsb = rndval & 1 rndval >>= 1 if lsb != 0: rndval ^= 0x00012000 if x < game.screen_width and y < game.screen_height: self.window.draw_char(x, y, " ", fg=(205, 38, 38), bg=(205, 38, 38)) i += 1 if i >= 100: i = 0 game.root.blit(self.window, 0, 0, game.screen_width, game.screen_height, 0, 0) tdl.flush() if rndval == 1: running = False
def play_game(): global fov_recompute player_action = None fov_recompute = True con.clear() #unexplored areas start with black while not tdl.event.is_window_closed(): #Draw all objects render_all() tdl.flush() #this presents change to the screen #erase all objects for obj in objects: obj.clear() #handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break if game_state == 'playing' and player_action != 'turn-not-taken': for obj in objects: if obj.ai: obj.ai.take_turn()
def main(): global console tdl.set_font('data/terminal8x8_gs_ro.png') console = tdl.init(WIDTH, HEIGHT) console.draw_str(0, 0, "Hello World") tdl.flush() tdl.event.key_wait()
def update(self): # Clean window self.window.clear() if self.following != None: self.offsetX = int(self.width / 2) - self.following.x self.offsetY = int(self.height / 2) - self.following.y else: self.offsetX = 0 self.offsetY = 0 # Draw all entities for entity in self.entities: # If off-screen, dont draw entity if entity.x + self.offsetX >= self.width or entity.y + self.offsetY >= self.height or entity.x + self.offsetX < 0 or entity.y + self.offsetY < 0: pass else: if self.following == None: self.window.drawChar(entity.x + self.offsetX, entity.y + self.offsetY, entity.char) elif abs(self.following.x - entity.x) <= self.following.sightRange and abs( self.following.y - entity.y) <= self.following.sightRange: self.window.drawChar(entity.x + self.offsetX, entity.y + self.offsetY, entity.char) # Write window to screen tdl.flush()
def gameloop(w): hero = object.GameObject(1, 1, '@', colors.red) npc = object.GameObject(10, 10, 'X', colors.blue) objects = [hero, npc] sta = stage.Stage(w.screen.width, w.screen.height) sta.map[5][5].blocked = True sta.map[15][15].blocked = True while not tdl.event.is_window_closed(): for obj in objects: obj.draw(w.con) for x in range(w.screen.width): for y in range(w.screen.height): wall = sta.map[x][y].blocked if wall: w.con.draw_char(x, y, None, fg=None, bg=colors.grey) else: w.con.draw_char(x, y, None, fg=None, bg=colors.black) w.root.blit(w.con, 0, 0, w.screen.width, w.screen.height, 0, 0) tdl.flush() for obj in objects: obj.clear(w.con) escape_pushed = handle_keys(hero, sta) if escape_pushed: break
def render_main_menu(self): options = ['Play a new game', 'Quit'] main_menu = Menu('Main Menu', options, self.main_console_w, self.main_console_h) x = 20 y = 20 main_menu.print_str('Welcome', x, y) y += 2 main_menu.print_str('Your goal is to find the Cone of Dunshire (!).', x, y) y += 2 main_menu.print_str('Use Caution as there are Trolls (T)and Orcs (o)', x, y) y += 1 main_menu.print_str('lurking in this dungeon!', x, y) y += 2 x += 5 for option_text in options: text = '(' + chr(main_menu.letter_index) + ') ' + option_text main_menu.print_str(text, x, y) y += 2 main_menu.letter_index += 1 self.render_console(main_menu, 0, 0) tdl.flush()
def run(self): timer = 0 last_time = 0 running = True self.start_time = time.time() while running: # Draw the scene self.console.clear() Game.scene_root.draw(self.console) tdl.flush() # Handle input/events for event in list(tdl.event.get()) + self.observer.get_events(): Game.scene_root.handle_events(event) if event.type == 'QUIT': running = False self.observer.stop() # Update scene time_elapsed = time.time() - last_time timer += time_elapsed last_time = time.time() Game.scene_root.update(time_elapsed) # Send out tick event if timer > Game.seconds_per_tick: timer = 0 Game.tick_count += 1 Game.scene_root.tick(Game.tick_count)
def item_selection_menu(): # update the inventory panel's caption and border render_all() #draw_inv_panel(gv.inv_panel,gv.root) tdl.flush() item = None key = ' ' # begin a loop waiting for input. the loop will only quit when ESC is pressed or an item is selected while key != 'ESCAPE': user_input = tdl.event.key_wait() key = user_input.key char = user_input.char if key == 'ESCAPE': break # elif it's an arrow key or pageup/pagedown, scroll the inventory: # # for any other key, check if a corresponding item exists in the player's inventory elif char: index = ord(char) - ord('a') if 0 <= index < len(gv.player.inventory): item = gv.player.inventory[index] break return item
def menu(header, options, width): """ """ if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options.') # calculate total height for the header (after textwrap) and one # line per option header_wrapped = [] for header_line in header.splitlines(): header_wrapped.extend(textwrap.wrap(header_line, width)) header_height = len(header_wrapped) if header == '': header_height = 0 height = len(options) + header_height # create an off-screen console that represents the menu's window window = tdl.Console(width, height) window.draw_rect(0, 0, width, height, None, fg=roguecolors.white, bg=roguecolors.dark_grey) # print the header, with wrapped text for i, line in enumerate(header_wrapped): window.draw_str(0, 0 + i, header_wrapped[i], bg=None) y = header_height # now, print each item, one by line letter_index = ord('a') for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text window.draw_str(0, y, text, bg=None) y += 1 letter_index += 1 # blit the contents of "window" to the root console x = SCREEN_WIDTH // 2 - width // 2 y = SCREEN_HEIGHT // 2 - height // 2 root.blit(window, x, y, width, height, 0, 0) # present the root console to the player and wait for a key-press tdl.flush() key = tdl.event.key_wait() key_char = key.char if key_char == '': key_char = ' ' # placeholder if key.key == 'ENTER' and key.alt: # Alt+Enter: toggle fullscreen tdl.set_fullscreen(not tdl.get_fullscreen()) # convert the ASCII code to an index; if it corresponds to an # option, return it index = ord(key_char) - ord('a') if index >= 0 and index < len(options): return index return None
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 colors = {'dark_wall': (0, 0, 100), 'dark_ground': (50, 50, 150)} player = Entity(int(screen_width / 2), int(screen_height / 2), '@', (255, 255, 255)) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', (255, 255, 0)) entities = [npc, player] tdl.set_font('arial10x10.png', greyscale=True, altLayout=True) root_console = tdl.init(screen_width, screen_height, title='Roguelike Tutorial Revised') con = tdl.Console(screen_width, screen_height) game_map = tdl.map.Map(map_width, map_height) make_map(game_map) while not tdl.event.is_window_closed(): render_all(con, entities, game_map, root_console, screen_width, screen_height, colors) tdl.flush() clear_all(con, entities) for event in tdl.event.get(): if event.type == 'KEYDOWN': user_input = event break else: user_input = None if not user_input: continue action = handle_keys(user_input) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move if game_map.walkable[player.x + dx, player.y + dy]: player.move(dx, dy) if exit: return True if fullscreen: tdl.set_fullscreen(not tdl.get_fullscreen())
def update(self, time_delta): self.console.clear() num_opts = len(self.opts) # _, height = self.console.get_size() height = self.console.height draw_str_centered(self.console, self.header, 3) for i, (option, _) in enumerate(self.opts): self.write_option(i, height // 2 - num_opts + i) tdl.flush()
def render(self, dt): if not self.paused: self.world.render() self.draw_bounds() self.console.blit( self.active_window, x=1, y=1, width=self.width - 2, height=self.height - 2 ) self.draw_ui() tdl.flush()
def update(self, entities): # TODO: instead of this, track old positions and redraw only what changed self._root_console.clear() for e in entities: if e.has(DisplayComponent): dc = e.get(DisplayComponent) self._root_console.draw_char(dc.x, dc.y, dc.character, dc.colour) tdl.flush()
def draw_chunk(self, offset, top, d): for i in range(top[0], top[0] + d[0]): for j in range(top[1], top[1] + d[1]): cell = self.game_map[(i, j)] self.console.draw_char(offset[0] + i, offset[1] + j, cell.draw_char(), cell.draw_color()) cell = self.get_cell_under_cursor() self.console.draw_char(self.cursor[0], self.cursor[1], cell.draw_char(), cell.draw_color(), self.cursor_bg_color) tdl.flush()
def char_finder(): w_display = 16 h_display = 16 w_info = 15 h_info = 16 margin = 1 w = w_display + w_info + margin h = 16 highlight = (0, 0) tdl.set_font("mononoki_16-19.png", columns=16, rows=16, greyscale=True, altLayout=False) tdl.set_fps(30) root = tdl.init(w, h, title="char picker") display = tdl.Console(w_display, h_display) info = tdl.Console(w_info, h_info) display.set_colors(FG, BG) info.set_colors(FG, BG) running = True while running: display.clear() info.clear() c = 0 for y in range(0, 16): for x in range(0, 16): color = FG if highlight == (x, y): color = HIGHLIGHT display.draw_char(x, y, c, fg=color) c += 1 for event in tdl.event.get(): if event.type == "KEYDOWN": running = False break elif event.type == "MOUSEDOWN": print(event.cell) highlight = event.cell info.draw_str(0, 0, "cell: %dx%d" % highlight) info.draw_str(0, 1, "char: %d" % get_char(*highlight)) root.blit(display, 0, 0, 16, 16, 0, 0) root.blit(info, w_display + margin, 0, w_info, h_info, 0, 0) tdl.flush()
def blit(fname): #image open try: img = Image.open(fname) except: input('ERROR: File not found.') return #image resize size = (W, H) = img.size w_blit = W // FONTSIZE h_blit = H // FONTSIZE size_blit = (w_blit, h_blit) img.thumbnail(size_blit, Image.ANTIALIAS) pix = img.load() #tdl renderer start console = tdl.init( w_blit, h_blit, 'ASCII BLITTER Press ANY key to save to file.' ) console.clear() for x in range(w_blit): for y in range(h_blit): m = (pix[x, y][0] + pix[x, y][1] + pix[x, y][2]) // 3 if m < 9: c = '.' elif m < 22: c = ',' elif m < 27: c = '`' elif m < 32: c = '-' elif m < 37: c = '+' elif m < 45: c = '/' elif m < 130: c = chr(random.randint(97, 120)) elif m < 195: c = chr(random.randint(65, 90)) else: c = str(random.randint(0, 9)) console.draw_char( x, y, c, pix[x, y], (pix[x, y][0] // 10, pix[x, y][1] // 10, pix[x, y][2] // 10)) tdl.flush() tdl.event.key_wait() tdl.flush() tdl.screenshot() del console return
def Main(): horzDirection = 1 globalCounter = 0 delay = 20 Score = 0 Hardness = 0 SCREEN_WIDTH = 80 SCREEN_HEIGHT = 50 LIMIT_FPS = 20 tdl.set_font('arial10x10.png', greyscale=True, altLayout=True) console = tdl.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="Space Invaders", fullscreen=False) tdl.setFPS(LIMIT_FPS) while not tdl.event.is_window_closed(): screen.Update() globalCounter+=1 if globalCounter >= delay - Hardness: globalCounter=0 horzDirection *= NeedToChangeDir() for en in enemies: en.TryToMove(Vector(horzDirection, 0)) PrintScreen(console) tdl.flush() print("Score: " + str(Score)) if not screen.Objects.__contains__(player): break for en in enemies: if not screen.Objects.__contains__(en): enemies.remove(en) Score+=100 tmp = Score/1000 if Hardness<19: Hardness = int(tmp) if Hardness>18: Hardness = 18 if len(enemies) == 0: InitEnemies() print("Game Over! Your Score is {0}".format(Score))