def __init__(self, start_position, width, height, parent_frame): UIFrame.__init__(self, start_position, width, height, parent_frame) self.buttons_per_page = height / BUTTON_HEIGHT self.current_page = 0 self.start_position = start_position self.back_button = Button(Vector2(0, 0), 50, height, list(globals.forward_button_img_list), self, self.back_pressed) self.forward_button = Button(Vector2(width - 50, 0), 50, height, list(globals.back_button_img_list), self, self.forward_pressed) self.game_button_list = [] #begin polling for rooms self.update_game_list_thread = RepeatTask(5, self.update_game_list) self.update_game_list_thread.start()
def __init__(self, always_visible=False, x_offset=0, y_offset=0, box_width=None, box_height=None, max_chars=65, player_heads_up_display=None, screen=None): self.screen = screen self.always_visible = always_visible self.max_chars = max_chars self.view_offset = 0 # The part of the text log you're viewing. 0 is the most recent on the bottom. # These values move the ChatBox from it's default position at the bottom left hand corner of the screen. self.x_offset = x_offset self.y_offset = y_offset self.hidden = not self.always_visible # while this is true the ChatBox shouldn't be displayed. self.alpha = 255 self.delaying_to_fade = False self.is_fading = False # while this is true, the ChatBox text is fading to transparency. self.fade_delay = 3 # seconds after the ChatBox is deselected until the text starts to fade. self.fade_time = 2 # seconds that it fades for after the fadeDelay self.last_deselect_time = 0 # time that the fade process started. self.last_fade_start_time = 0 self.selected = False self.fade_proportion = 0 # This will hold the proportion to convert the time to terms of opacity (0-255) self.font = pygame.font.SysFont('arial', 12) self.cursor_blink_time = 1.5 # the cursor will change every half of this number self.last_cursor_blink = 0 self.cursor_is_blinking = False self.cursor_surface = self.font.render("|", True, [255, 255, 255]) self.text_content = [] # list of strings. lower index = older self.input = None # a string of input to send to the textBox. self.surface_content = [] # a list of surface slices. lower index = older self.border_offset = 14 # offset text by ten pixels to account for the border of the chatBox self.blit_dict = {} self.alpha_blit_dict = {} temp_sprite_sheet = SpriteSheet("resources/images/Sprite Sheet1.png") self.box_image = temp_sprite_sheet.imageAt(pygame.Rect(5, 15, 370, 135)) # this image is cursed to never change color. self.unfocused_image = temp_sprite_sheet.imageAt(pygame.Rect(6, 158, 368, 130)) if box_width is not None and box_height is not None: self.box_image = pygame.transform.scale(self.box_image, (box_width, box_height)) self.unfocused_image = pygame.transform.scale(self.box_image, (box_width, box_height)) self.image = self.box_image # everything will be blit onto here. self.shift_is_pressed = False if hasattr(globals, 'online_game'): self.last_message_received = 0 self.get_new_messages_thread = RepeatTask(1, self.get_new_messages) self.get_new_messages_thread.start() self.player_heads_up_display = player_heads_up_display self.last_paused = datetime.now()
class PageButton(UIFrame): def __init__(self, start_position, width, height, parent_frame): UIFrame.__init__(self, start_position, width, height, parent_frame) self.buttons_per_page = height / BUTTON_HEIGHT self.current_page = 0 self.start_position = start_position self.back_button = Button(Vector2(0, 0), 50, height, list(globals.forward_button_img_list), self, self.back_pressed) self.forward_button = Button(Vector2(width - 50, 0), 50, height, list(globals.back_button_img_list), self, self.forward_pressed) self.game_button_list = [] #begin polling for rooms self.update_game_list_thread = RepeatTask(5, self.update_game_list) self.update_game_list_thread.start() #NOTE: this class dosn't use self.all_elements #************************************************************************************************* #************************************************************************************************* #returns a list of all the buttons in the frame def get_all_buttons(self): value = list(self.game_button_list) value.append(self.back_button) value.append(self.forward_button) return value #************************************************************************************************* #************************************************************************************************* #returns a list of all the buttons being displayed def get_displayed_objects(self): if len(self.game_button_list) - (self.buttons_per_page * self.current_page) >= self.buttons_per_page: value = self.game_button_list[self.buttons_per_page * self.current_page: self.buttons_per_page * (self.current_page + 1)] else: value = self.game_button_list[self.buttons_per_page * self.current_page: len(self.game_button_list)] value.append(self.back_button) value.append(self.forward_button) return value #************************************************************************************************* #************************************************************************************************* #if forward is pressed def back_pressed(self): if self.current_page != 0 and len(self.game_button_list) != 0: self.current_page -= 1 #************************************************************************************************* #************************************************************************************************* #if back is pressed def forward_pressed(self): if math.ceil(float(len(self.game_button_list)) / float(self.buttons_per_page)) != self.current_page + 1 and\ len(self.game_button_list) != 0: self.current_page += 1 self.back_button.is_pressed = False #************************************************************************************************* #************************************************************************************************* #returns true if the given button is in the game_buttons list def is_game_button(self, button): return button in self.game_button_list #************************************************************************************************* #************************************************************************************************* #blits buttons to the frame def update(self, user_input): self.rect.center = self.get_center_frame_pov() self.image.fill(BLACK) for button in self.get_displayed_objects(): button.update(user_input) self.image.blit(button.image, button.rect) #************************************************************************************************* #************************************************************************************************* #makes the game list def update_game_list(self): temp_game_button_list = self.game_button_list self.game_button_list = [] game_name_list = list_available_games(remote_server_name, remote_server_port) ix = 0 for button in temp_game_button_list: if button.text in game_name_list: if ix == 0 or ix % self.buttons_per_page == 0: button.start_position = Vector2(self.back_button.rect.right, 0) self.game_button_list.append(button) else: button.start_position = Vector2(self.game_button_list[-1].start_position.x, self.game_button_list[-1].start_position.y + self.game_button_list[-1].get_height()) self.game_button_list.append(button) game_name_list.remove(button.text) ix += 1 for new_game_name in game_name_list: if ix == 0 or ix % self.buttons_per_page == 0: self.game_button_list.append(TextButton(Vector2(self.back_button.rect.right, 0), BUTTON_WIDTH, BUTTON_HEIGHT, list(globals.join_game_img_list), new_game_name, self, self.enter_lobby, (40, 22))) else: self.game_button_list.append(TextButton(Vector2(self.game_button_list[-1].start_position.x, self.game_button_list[-1].start_position.y + self.game_button_list[-1].get_height()), BUTTON_WIDTH, BUTTON_HEIGHT, list(globals.join_game_img_list), new_game_name, self, self.enter_lobby, (40, 22))) ix += 1 #************************************************************************************************* #************************************************************************************************* #makes the game list def enter_lobby(self, button): globals.online_game = join_game(button.text, remote_server_name, remote_server_port, user_name) #globals.current_screen = "game lobby" first_parent = self.main_frame_parent() from lobby import GameLobby first_parent.scene = GameLobby(globals.online_game.name)
def start_update_game_data_thread(self): self.update_game_data_thread = RepeatTask(1, self.update_game_data) self.update_game_data_thread.start()
def start_keep_alive_thread(self): self.keep_alive_thread = RepeatTask(3, self.keep_alive) self.keep_alive_thread.start()
class Game: def __init__(self, settings=None): if hasattr(globals, 'online_game') and globals.online_game is not None: globals.online_game.stop_all_threads() self.keep_alive_thread = None self.update_game_data_thread = None if settings: self.server = settings.server self.server_port = settings.server_port self.name = settings.name self.owner = settings.user_name self.map_name = settings.map_name self.status = 'lobby' message = Message(message_type='START_GAME') message.name = self.name message.owner = self.owner message.map_name = self.map_name send_message(message, self.server, self.server_port, wait_for_response=False) self.start_keep_alive_thread() self.start_update_game_data_thread() def get_players(self): """ Returns an array of player names in game. """ message = Message(message_type='LIST_GAME_PLAYERS') message.name = self.name return send_message(message, self.server, self.server_port) def get_new_messages(self, last_message_received): """ Returns all messages for the game since the last poll. """ message = Message(message_type='GET_GAME_MESSAGES') message.name = self.name message.last_received = last_message_received return send_message(message, self.server, self.server_port) def keep_alive(self): """ Sends a keep alive message (AKA ping) to the server to prevent being idle and kicked. """ from networking.configuration import user_name message = Message(message_type='PING') message.user_name = user_name send_message(message, self.server, self.server_port, wait_for_response=False) def set_status(self, new_status): message = Message(message_type='SET_GAME_STATUS') message.game_name = self.name message.new_status = new_status send_message(message, self.server, self.server_port, wait_for_response=False) def start_keep_alive_thread(self): self.keep_alive_thread = RepeatTask(3, self.keep_alive) self.keep_alive_thread.start() def start_update_game_data_thread(self): self.update_game_data_thread = RepeatTask(1, self.update_game_data) self.update_game_data_thread.start() def stop_all_threads(self): """ Use this when leaving a game. """ self.keep_alive_thread.stop() self.update_game_data_thread.stop() def update_game_data(self): """ Updates game data from server. """ message = Message(message_type='UPDATE_GAME_DATA') message.game_name = self.name game_data = send_message(message, self.server, self.server_port, wait_for_response=True) self.owner = game_data.owner self.map_name = game_data.map_name self.status = game_data.status
def __init__(self, always_visible=False, x_offset=0, y_offset=0, box_width=None, box_height=None, max_chars=65, player_heads_up_display=None, screen=None): self.screen = screen self.always_visible = always_visible self.max_chars = max_chars self.view_offset = 0 # The part of the text log you're viewing. 0 is the most recent on the bottom. # These values move the ChatBox from it's default position at the bottom left hand corner of the screen. self.x_offset = x_offset self.y_offset = y_offset self.hidden = not self.always_visible # while this is true the ChatBox shouldn't be displayed. self.alpha = 255 self.delaying_to_fade = False self.is_fading = False # while this is true, the ChatBox text is fading to transparency. self.fade_delay = 3 # seconds after the ChatBox is deselected until the text starts to fade. self.fade_time = 2 # seconds that it fades for after the fadeDelay self.last_deselect_time = 0 # time that the fade process started. self.last_fade_start_time = 0 self.selected = False self.fade_proportion = 0 # This will hold the proportion to convert the time to terms of opacity (0-255) self.font = pygame.font.SysFont('arial', 12) self.cursor_blink_time = 1.5 # the cursor will change every half of this number self.last_cursor_blink = 0 self.cursor_is_blinking = False self.cursor_surface = self.font.render("|", True, [255, 255, 255]) self.text_content = [] # list of strings. lower index = older self.input = None # a string of input to send to the textBox. self.surface_content = [ ] # a list of surface slices. lower index = older self.border_offset = 14 # offset text by ten pixels to account for the border of the chatBox self.blit_dict = {} self.alpha_blit_dict = {} temp_sprite_sheet = SpriteSheet("resources/images/Sprite Sheet1.png") self.box_image = temp_sprite_sheet.imageAt(pygame.Rect( 5, 15, 370, 135)) # this image is cursed to never change color. self.unfocused_image = temp_sprite_sheet.imageAt( pygame.Rect(6, 158, 368, 130)) if box_width is not None and box_height is not None: self.box_image = pygame.transform.scale(self.box_image, (box_width, box_height)) self.unfocused_image = pygame.transform.scale( self.box_image, (box_width, box_height)) self.image = self.box_image # everything will be blit onto here. self.shift_is_pressed = False if hasattr(globals, 'online_game'): self.last_message_received = 0 self.get_new_messages_thread = RepeatTask(1, self.get_new_messages) self.get_new_messages_thread.start() self.player_heads_up_display = player_heads_up_display self.last_paused = datetime.now()
class ChatBox(UIFrame): """ Used for chatting. Handles user input and displays a log of messages. """ LINE_HEIGHT = 18.5 # number of pixels a 12 font arial is in height about. def __init__(self, always_visible=False, x_offset=0, y_offset=0, box_width=None, box_height=None, max_chars=65, player_heads_up_display=None, screen=None): self.screen = screen self.always_visible = always_visible self.max_chars = max_chars self.view_offset = 0 # The part of the text log you're viewing. 0 is the most recent on the bottom. # These values move the ChatBox from it's default position at the bottom left hand corner of the screen. self.x_offset = x_offset self.y_offset = y_offset self.hidden = not self.always_visible # while this is true the ChatBox shouldn't be displayed. self.alpha = 255 self.delaying_to_fade = False self.is_fading = False # while this is true, the ChatBox text is fading to transparency. self.fade_delay = 3 # seconds after the ChatBox is deselected until the text starts to fade. self.fade_time = 2 # seconds that it fades for after the fadeDelay self.last_deselect_time = 0 # time that the fade process started. self.last_fade_start_time = 0 self.selected = False self.fade_proportion = 0 # This will hold the proportion to convert the time to terms of opacity (0-255) self.font = pygame.font.SysFont('arial', 12) self.cursor_blink_time = 1.5 # the cursor will change every half of this number self.last_cursor_blink = 0 self.cursor_is_blinking = False self.cursor_surface = self.font.render("|", True, [255, 255, 255]) self.text_content = [] # list of strings. lower index = older self.input = None # a string of input to send to the textBox. self.surface_content = [ ] # a list of surface slices. lower index = older self.border_offset = 14 # offset text by ten pixels to account for the border of the chatBox self.blit_dict = {} self.alpha_blit_dict = {} temp_sprite_sheet = SpriteSheet("resources/images/Sprite Sheet1.png") self.box_image = temp_sprite_sheet.imageAt(pygame.Rect( 5, 15, 370, 135)) # this image is cursed to never change color. self.unfocused_image = temp_sprite_sheet.imageAt( pygame.Rect(6, 158, 368, 130)) if box_width is not None and box_height is not None: self.box_image = pygame.transform.scale(self.box_image, (box_width, box_height)) self.unfocused_image = pygame.transform.scale( self.box_image, (box_width, box_height)) self.image = self.box_image # everything will be blit onto here. self.shift_is_pressed = False if hasattr(globals, 'online_game'): self.last_message_received = 0 self.get_new_messages_thread = RepeatTask(1, self.get_new_messages) self.get_new_messages_thread.start() self.player_heads_up_display = player_heads_up_display self.last_paused = datetime.now() #************************************************************************************************* #************************************************************************************************* #Updates the TextBox image if it's not hidden. #blits stuff on its own def update(self, userInput): returnString = "" #empty blitting dictionaries self.blit_dict.clear() self.alpha_blit_dict.clear() if (not self.hidden) or self.always_visible: if self.selected: #self.screen.blit(self.box_image, (0, self.screen.get_height() - self.box_image.get_height())) self.blit_dict.update({ self.box_image: (0, self.screen.get_height() - self.box_image.get_height()) }) self.cursorBlink() elif self.delaying_to_fade and not self.always_visible: self.delay() # waiting to fade text elif self.is_fading and not self.always_visible: #changes the self.alpha for the surface slices of text. The method disengage() sets isFading to true # or not and sets lastFadeTime to now() self.fade() if self.always_visible and not self.selected: # display a faded edge around the chatbox #TODO: unfocused_image is broken and cursed. nothing will change it's color. change it's color. ypos = self.screen.get_height( ) - self.unfocused_image.get_height() #self.screen.blit(self.unfocused_image, (0, ypos)) self.blit_dict.update({self.unfocused_image: (0, ypos)}) self.buildChatBoxImage(userInput) # blits stuff # ChatBox handling for user input. Engages and disengages ChatBox. # These controls are disabled if the user is in the pause menu # (and 1 second after pausing due to conflict with Enter button). # if self.player_heads_up_display and self.player_heads_up_display.pause_menu.is_paused: # self.last_paused = datetime.now() # if not self.player_heads_up_display or \ # (not self.player_heads_up_display.pause_menu.is_paused and # (self.last_paused and datetime.now() - self.last_paused > timedelta(seconds=1))): # if not self.player_heads_up_display or \ # (self.last_paused and datetime.now() - self.last_paused > timedelta(seconds=1)): if self.last_paused and datetime.now() - self.last_paused > timedelta( seconds=1): if userInput[RETURN] and self.selected: # if enter is pressed if userInput[INPUT_STRING]: # Take out addText if you want to not artificially increase local user chat update speed. # Other part is in get_new_messages. returnString = userInput[INPUT_STRING] self.addText(user_name + ': ' + userInput[INPUT_STRING]) userInput[INPUT_STRING] = "" self.view_offset = 0 self.disengage() elif userInput[RETURN]: userInput[INPUT_STRING] = "" self.engage() #elif (userInput[MOUSE_SCROLL_UP_PRESSED] and current_time - userInput[MOUSE_SCROLL_UP_UNPRESSED] == 0) or (userInput[ARROW_UP] and current_time - userInput[ARROW_UP_PRESSED] == 0): #scroll up and down elif userInput[MOUSE_SCROLL_UP] and self.view_offset < len( self.surface_content) - math.floor( self.box_image.get_height() / self.LINE_HEIGHT ) + 1 and self.selected: # round down.: self.view_offset += 1 elif userInput[ MOUSE_SCROLL_DOWN] and self.view_offset != 0 and self.selected: self.view_offset -= 1 if returnString: return returnString #************************************************************************************************* #************************************************************************************************* #Builds the image of the chatbox using slices of text. #create the chat from the bottom up. lower index = older. def buildChatBoxImage(self, userInput): i = 0 #chatboxCapacity includes the spot in the bottom for text input. chatBoxCapacity = math.floor(self.box_image.get_height() / self.LINE_HEIGHT) # round down. #calculate x component of position curr_xpos = self.border_offset + self.x_offset #get first part of y component of position ypos_independent_offset = self.screen.get_height( ) - self.box_image.get_height() # independent from i input_ypos_independent_offset = self.screen.get_height( ) - self.box_image.get_height() input_surface_xpos = self.border_offset + 5 + self.x_offset cursor_independent_ypos = self.screen.get_height( ) - self.box_image.get_height() while i < chatBoxCapacity - 1 and i < len(self.surface_content): #find the slice to blit; top to bottom here curr_slice = self.surface_content[len(self.surface_content) - (i + self.view_offset) - 1] #get the ypos components and add them together to get the y component of position slice_height = self.surface_content[len(self.surface_content) - i - 1].get_height() ypos_dependent_offset = (chatBoxCapacity - i - 1) * slice_height # dependant on i curr_ypos = ypos_independent_offset + ypos_dependent_offset #globals.blit_alpha(curr_slice, (curr_xpos, curr_ypos), self.screen, self.alpha, self.box_image.get_rect()) self.alpha_blit_dict.update({curr_slice: (curr_xpos, curr_ypos)}) i += 1 #draw the text that the user is typing in if userInput[INPUT_STRING] is not None and self.selected: #scroll the text left and right if it's too big for the input box if len(userInput[INPUT_STRING]) > self.max_chars: snipIndex = len(userInput[INPUT_STRING]) - self.max_chars else: snipIndex = 0 inputSurface = self.font.render( userInput[INPUT_STRING] [snipIndex:len(userInput[INPUT_STRING])], True, WHITE) #blit input surface input_dependent_ypos = ( chatBoxCapacity) * inputSurface.get_height() input_ypos = input_ypos_independent_offset + input_dependent_ypos #self.screen.blit(inputSurface, (input_surface_xpos, input_ypos)) self.blit_dict.update( {inputSurface: (input_surface_xpos, input_ypos)}) #blit cursor cursor_xpos = self.border_offset + 5 + self.x_offset + inputSurface.get_width( ) cursor_ypos = cursor_independent_ypos + ( chatBoxCapacity) * inputSurface.get_height() #self.screen.blit(self.cursor_surface, (cursor_xpos, cursor_ypos)) self.blit_dict.update( {self.cursor_surface: (cursor_xpos, cursor_ypos)}) #************************************************************************************************* #************************************************************************************************* #Add a new line of text to the chatbox #important: in order to set the alpha of text, you have to first blit it to a surface. if you just blit the text, it won't ever be able to be transparent. def addText(self, text, color=[255, 255, 255]): chatLine = ChatLine( text, self.max_chars ) # returns a list of surfaces if the text needs to be wordwrapped. self.text_content.append( text) # store text into textContent before it's truncated if len(text) > self.max_chars: text = text[ 0:self. max_chars] # substring from 0 to maxChars. The full string is still stored in textContent. for x in chatLine.lines: # rest of chat box self.surface_content.append(self.font.render(x, True, color)) #self.surfaceContent.append(self.font.render(text, True, color)) #************************************************************************************************* #************************************************************************************************* #get ready to accept input def engage(self): self.hidden = False self.alpha = 255 # set each surfacecontent surface's alpha to 250 self.selected = True # when the chatbox is selected it is accepting input from the player. #************************************************************************************************* #************************************************************************************************* #stop accepting input def disengage(self): self.selected = False self.delaying_to_fade = True self.last_deselect_time = now() #************************************************************************************************* #************************************************************************************************* #makes the cursor blink. def cursorBlink(self): if now() - self.last_cursor_blink > self.cursor_blink_time / 2 and now( ) - self.last_cursor_blink < self.cursor_blink_time: self.cursor_surface = self.font.render(" ", True, [255, 255, 255]) self.cursor_is_blinking = True elif now() - self.last_cursor_blink > self.cursor_blink_time: self.cursor_surface = self.font.render("|", True, [255, 255, 255]) self.cursor_is_blinking = False self.last_cursor_blink = now() #************************************************************************************************* #************************************************************************************************* #show text on screen until delay timer expires def delay(self): if now( ) - self.last_deselect_time > self.fade_delay: # now() returns seconds. It's time to fade the text if this is True self.is_fading = True self.fade_proportion = now() / 255 self.last_fade_start_time = now() self.delaying_to_fade = False #************************************************************************************************* #************************************************************************************************* #fade the text to nothing after a delay. assume self.isfading == True and self.lastDeselectTime has been set. def fade(self): for index in range(0, len(self.surface_content)): #self.surfaceContent[index].set_alpha(255 - ((now() - self.lastFadeStartTime) * (255 / self.fadeTime))) self.alpha = 255 - ((now() - self.last_fade_start_time) * (255 / self.fade_time)) #print self.surfaceContent[index].get_alpha() if now() - self.last_fade_start_time > self.fade_time: # done fading self.is_fading = False self.hidden = True def get_new_messages(self): """ Polls the server for new messages on a timer. """ if hasattr(globals, 'online_game') and globals.online_game is not None: response = globals.online_game.get_new_messages( self.last_message_received) if response['last_received'] > self.last_message_received: self.last_message_received = response['last_received'] for new_message in response['messages']: self.engage() self.disengage() if find( new_message, user_name[:len(user_name)] ) == -1: # string.find find the lowest index.-1 no match self.addText(new_message) else: self.get_new_messages_thread.stop() #************************************************************************************************* #************************************************************************************************* #gets blit_dict def get_blit_info(self): return self.blit_dict #************************************************************************************************* #************************************************************************************************* #gets alpha_blit_dict def get_alpha_blit_info(self): return self.alpha_blit_dict #************************************************************************************************* #************************************************************************************************* #gets alpha_blit_dict def get_alpha(self): return self.alpha
class ChatBox(UIFrame): """ Used for chatting. Handles user input and displays a log of messages. """ LINE_HEIGHT = 18.5 # number of pixels a 12 font arial is in height about. def __init__(self, always_visible=False, x_offset=0, y_offset=0, box_width=None, box_height=None, max_chars=65, player_heads_up_display=None, screen=None): self.screen = screen self.always_visible = always_visible self.max_chars = max_chars self.view_offset = 0 # The part of the text log you're viewing. 0 is the most recent on the bottom. # These values move the ChatBox from it's default position at the bottom left hand corner of the screen. self.x_offset = x_offset self.y_offset = y_offset self.hidden = not self.always_visible # while this is true the ChatBox shouldn't be displayed. self.alpha = 255 self.delaying_to_fade = False self.is_fading = False # while this is true, the ChatBox text is fading to transparency. self.fade_delay = 3 # seconds after the ChatBox is deselected until the text starts to fade. self.fade_time = 2 # seconds that it fades for after the fadeDelay self.last_deselect_time = 0 # time that the fade process started. self.last_fade_start_time = 0 self.selected = False self.fade_proportion = 0 # This will hold the proportion to convert the time to terms of opacity (0-255) self.font = pygame.font.SysFont('arial', 12) self.cursor_blink_time = 1.5 # the cursor will change every half of this number self.last_cursor_blink = 0 self.cursor_is_blinking = False self.cursor_surface = self.font.render("|", True, [255, 255, 255]) self.text_content = [] # list of strings. lower index = older self.input = None # a string of input to send to the textBox. self.surface_content = [] # a list of surface slices. lower index = older self.border_offset = 14 # offset text by ten pixels to account for the border of the chatBox self.blit_dict = {} self.alpha_blit_dict = {} temp_sprite_sheet = SpriteSheet("resources/images/Sprite Sheet1.png") self.box_image = temp_sprite_sheet.imageAt(pygame.Rect(5, 15, 370, 135)) # this image is cursed to never change color. self.unfocused_image = temp_sprite_sheet.imageAt(pygame.Rect(6, 158, 368, 130)) if box_width is not None and box_height is not None: self.box_image = pygame.transform.scale(self.box_image, (box_width, box_height)) self.unfocused_image = pygame.transform.scale(self.box_image, (box_width, box_height)) self.image = self.box_image # everything will be blit onto here. self.shift_is_pressed = False if hasattr(globals, 'online_game'): self.last_message_received = 0 self.get_new_messages_thread = RepeatTask(1, self.get_new_messages) self.get_new_messages_thread.start() self.player_heads_up_display = player_heads_up_display self.last_paused = datetime.now() #************************************************************************************************* #************************************************************************************************* #Updates the TextBox image if it's not hidden. #blits stuff on its own def update(self, userInput): returnString = "" #empty blitting dictionaries self.blit_dict.clear() self.alpha_blit_dict.clear() if (not self.hidden) or self.always_visible: if self.selected: #self.screen.blit(self.box_image, (0, self.screen.get_height() - self.box_image.get_height())) self.blit_dict.update({self.box_image: (0, self.screen.get_height() - self.box_image.get_height())}) self.cursorBlink() elif self.delaying_to_fade and not self.always_visible: self.delay() # waiting to fade text elif self.is_fading and not self.always_visible: #changes the self.alpha for the surface slices of text. The method disengage() sets isFading to true # or not and sets lastFadeTime to now() self.fade() if self.always_visible and not self.selected: # display a faded edge around the chatbox #TODO: unfocused_image is broken and cursed. nothing will change it's color. change it's color. ypos = self.screen.get_height() - self.unfocused_image.get_height() #self.screen.blit(self.unfocused_image, (0, ypos)) self.blit_dict.update({self.unfocused_image: (0, ypos)}) self.buildChatBoxImage(userInput) # blits stuff # ChatBox handling for user input. Engages and disengages ChatBox. # These controls are disabled if the user is in the pause menu # (and 1 second after pausing due to conflict with Enter button). # if self.player_heads_up_display and self.player_heads_up_display.pause_menu.is_paused: # self.last_paused = datetime.now() # if not self.player_heads_up_display or \ # (not self.player_heads_up_display.pause_menu.is_paused and # (self.last_paused and datetime.now() - self.last_paused > timedelta(seconds=1))): # if not self.player_heads_up_display or \ # (self.last_paused and datetime.now() - self.last_paused > timedelta(seconds=1)): if self.last_paused and datetime.now() - self.last_paused > timedelta(seconds=1): if userInput[RETURN] and self.selected: # if enter is pressed if userInput[INPUT_STRING]: # Take out addText if you want to not artificially increase local user chat update speed. # Other part is in get_new_messages. returnString = userInput[INPUT_STRING] self.addText(user_name + ': ' + userInput[INPUT_STRING]) userInput[INPUT_STRING] = "" self.view_offset = 0 self.disengage() elif userInput[RETURN]: userInput[INPUT_STRING] = "" self.engage() #elif (userInput[MOUSE_SCROLL_UP_PRESSED] and current_time - userInput[MOUSE_SCROLL_UP_UNPRESSED] == 0) or (userInput[ARROW_UP] and current_time - userInput[ARROW_UP_PRESSED] == 0): #scroll up and down elif userInput[MOUSE_SCROLL_UP] and self.view_offset < len(self.surface_content) - math.floor(self.box_image.get_height() / self.LINE_HEIGHT) + 1 and self.selected: # round down.: self.view_offset += 1 elif userInput[MOUSE_SCROLL_DOWN] and self.view_offset != 0 and self.selected: self.view_offset -= 1 if returnString: return returnString #************************************************************************************************* #************************************************************************************************* #Builds the image of the chatbox using slices of text. #create the chat from the bottom up. lower index = older. def buildChatBoxImage(self, userInput): i = 0 #chatboxCapacity includes the spot in the bottom for text input. chatBoxCapacity = math.floor(self.box_image.get_height() / self.LINE_HEIGHT) # round down. #calculate x component of position curr_xpos = self.border_offset + self.x_offset #get first part of y component of position ypos_independent_offset = self.screen.get_height() - self.box_image.get_height() # independent from i input_ypos_independent_offset = self.screen.get_height() - self.box_image.get_height() input_surface_xpos = self.border_offset + 5 + self.x_offset cursor_independent_ypos = self.screen.get_height() - self.box_image.get_height() while i < chatBoxCapacity - 1 and i < len(self.surface_content): #find the slice to blit; top to bottom here curr_slice = self.surface_content[len(self.surface_content) - (i + self.view_offset) - 1] #get the ypos components and add them together to get the y component of position slice_height = self.surface_content[len(self.surface_content) - i - 1].get_height() ypos_dependent_offset = (chatBoxCapacity - i - 1) * slice_height # dependant on i curr_ypos = ypos_independent_offset + ypos_dependent_offset #globals.blit_alpha(curr_slice, (curr_xpos, curr_ypos), self.screen, self.alpha, self.box_image.get_rect()) self.alpha_blit_dict.update({curr_slice: (curr_xpos, curr_ypos)}) i += 1 #draw the text that the user is typing in if userInput[INPUT_STRING] is not None and self.selected: #scroll the text left and right if it's too big for the input box if len(userInput[INPUT_STRING]) > self.max_chars: snipIndex = len(userInput[INPUT_STRING]) - self.max_chars else: snipIndex = 0 inputSurface = self.font.render(userInput[INPUT_STRING][snipIndex:len(userInput[INPUT_STRING])], True, WHITE) #blit input surface input_dependent_ypos = (chatBoxCapacity) * inputSurface.get_height() input_ypos = input_ypos_independent_offset + input_dependent_ypos #self.screen.blit(inputSurface, (input_surface_xpos, input_ypos)) self.blit_dict.update({inputSurface: (input_surface_xpos, input_ypos)}) #blit cursor cursor_xpos = self.border_offset + 5 + self.x_offset + inputSurface.get_width() cursor_ypos = cursor_independent_ypos + (chatBoxCapacity) * inputSurface.get_height() #self.screen.blit(self.cursor_surface, (cursor_xpos, cursor_ypos)) self.blit_dict.update({self.cursor_surface: (cursor_xpos, cursor_ypos)}) #************************************************************************************************* #************************************************************************************************* #Add a new line of text to the chatbox #important: in order to set the alpha of text, you have to first blit it to a surface. if you just blit the text, it won't ever be able to be transparent. def addText(self, text, color=[255, 255, 255]): chatLine = ChatLine(text, self.max_chars) # returns a list of surfaces if the text needs to be wordwrapped. self.text_content.append(text) # store text into textContent before it's truncated if len(text) > self.max_chars: text = text[0:self.max_chars] # substring from 0 to maxChars. The full string is still stored in textContent. for x in chatLine.lines: # rest of chat box self.surface_content.append(self.font.render(x, True, color)) #self.surfaceContent.append(self.font.render(text, True, color)) #************************************************************************************************* #************************************************************************************************* #get ready to accept input def engage(self): self.hidden = False self.alpha = 255 # set each surfacecontent surface's alpha to 250 self.selected = True # when the chatbox is selected it is accepting input from the player. #************************************************************************************************* #************************************************************************************************* #stop accepting input def disengage(self): self.selected = False self.delaying_to_fade = True self.last_deselect_time = now() #************************************************************************************************* #************************************************************************************************* #makes the cursor blink. def cursorBlink(self): if now() - self.last_cursor_blink > self.cursor_blink_time / 2 and now() - self.last_cursor_blink < self.cursor_blink_time: self.cursor_surface = self.font.render(" ", True, [255, 255, 255]) self.cursor_is_blinking = True elif now() - self.last_cursor_blink > self.cursor_blink_time: self.cursor_surface = self.font.render("|", True, [255, 255, 255]) self.cursor_is_blinking = False self.last_cursor_blink = now() #************************************************************************************************* #************************************************************************************************* #show text on screen until delay timer expires def delay(self): if now() - self.last_deselect_time > self.fade_delay: # now() returns seconds. It's time to fade the text if this is True self.is_fading = True self.fade_proportion = now() / 255 self.last_fade_start_time = now() self.delaying_to_fade = False #************************************************************************************************* #************************************************************************************************* #fade the text to nothing after a delay. assume self.isfading == True and self.lastDeselectTime has been set. def fade(self): for index in range(0, len(self.surface_content)): #self.surfaceContent[index].set_alpha(255 - ((now() - self.lastFadeStartTime) * (255 / self.fadeTime))) self.alpha = 255 - ((now() - self.last_fade_start_time) * (255 / self.fade_time)) #print self.surfaceContent[index].get_alpha() if now() - self.last_fade_start_time > self.fade_time: # done fading self.is_fading = False self.hidden = True def get_new_messages(self): """ Polls the server for new messages on a timer. """ if hasattr(globals, 'online_game') and globals.online_game is not None: response = globals.online_game.get_new_messages(self.last_message_received) if response['last_received'] > self.last_message_received: self.last_message_received = response['last_received'] for new_message in response['messages']: self.engage() self.disengage() if find(new_message, user_name[:len(user_name)]) == -1: # string.find find the lowest index.-1 no match self.addText(new_message) else: self.get_new_messages_thread.stop() #************************************************************************************************* #************************************************************************************************* #gets blit_dict def get_blit_info(self): return self.blit_dict #************************************************************************************************* #************************************************************************************************* #gets alpha_blit_dict def get_alpha_blit_info(self): return self.alpha_blit_dict #************************************************************************************************* #************************************************************************************************* #gets alpha_blit_dict def get_alpha(self): return self.alpha
from networking.configuration import reserved_games from networking.server import HOST, PORT from networking.server.controllers.game import start_game from networking.server.request_handler import UDPHandler from networking.server.scheduled_tasks import debug_task, garbage_collection from utilities.threading_helper import RepeatTask import logging import SocketServer if __name__ == "__main__": # create reserved games for reserved_game in reserved_games: start_game( name=reserved_games[reserved_game], owner='reserved_game', map_name='' ) # kick off scheduled tasks garbage_collection_thread = RepeatTask(20, garbage_collection) garbage_collection_thread.start() debug_thread = RepeatTask(10, debug_task) # debug_thread.start() # start the server server = SocketServer.UDPServer((HOST, PORT), UDPHandler) logging.info('Server listening on {host}:{port}'.format(host=HOST, port=str(PORT))) server.serve_forever()
from networking.configuration import reserved_games from networking.server import HOST, PORT from networking.server.controllers.game import start_game from networking.server.request_handler import UDPHandler from networking.server.scheduled_tasks import debug_task, garbage_collection from utilities.threading_helper import RepeatTask import logging import SocketServer if __name__ == "__main__": # create reserved games for reserved_game in reserved_games: start_game(name=reserved_games[reserved_game], owner='reserved_game', map_name='') # kick off scheduled tasks garbage_collection_thread = RepeatTask(20, garbage_collection) garbage_collection_thread.start() debug_thread = RepeatTask(10, debug_task) # debug_thread.start() # start the server server = SocketServer.UDPServer((HOST, PORT), UDPHandler) logging.info('Server listening on {host}:{port}'.format(host=HOST, port=str(PORT))) server.serve_forever()
def __update_player_list(self): self.update_player_list_thread = RepeatTask(.5, self.update_player_list) self.update_player_list_thread.start()
class PageButton(UIFrame): def __init__(self, start_position, width, height, parent_frame): UIFrame.__init__(self, start_position, width, height, parent_frame) self.buttons_per_page = height / BUTTON_HEIGHT self.current_page = 0 self.start_position = start_position self.back_button = Button(Vector2(0, 0), 50, height, list(globals.forward_button_img_list), self, self.back_pressed) self.forward_button = Button(Vector2(width - 50, 0), 50, height, list(globals.back_button_img_list), self, self.forward_pressed) self.game_button_list = [] #begin polling for rooms self.update_game_list_thread = RepeatTask(5, self.update_game_list) self.update_game_list_thread.start() #NOTE: this class dosn't use self.all_elements #************************************************************************************************* #************************************************************************************************* #returns a list of all the buttons in the frame def get_all_buttons(self): value = list(self.game_button_list) value.append(self.back_button) value.append(self.forward_button) return value #************************************************************************************************* #************************************************************************************************* #returns a list of all the buttons being displayed def get_displayed_objects(self): if len(self.game_button_list) - ( self.buttons_per_page * self.current_page) >= self.buttons_per_page: value = self.game_button_list[self.buttons_per_page * self. current_page:self.buttons_per_page * (self.current_page + 1)] else: value = self.game_button_list[ self.buttons_per_page * self.current_page:len(self.game_button_list)] value.append(self.back_button) value.append(self.forward_button) return value #************************************************************************************************* #************************************************************************************************* #if forward is pressed def back_pressed(self): if self.current_page != 0 and len(self.game_button_list) != 0: self.current_page -= 1 #************************************************************************************************* #************************************************************************************************* #if back is pressed def forward_pressed(self): if math.ceil(float(len(self.game_button_list)) / float(self.buttons_per_page)) != self.current_page + 1 and\ len(self.game_button_list) != 0: self.current_page += 1 self.back_button.is_pressed = False #************************************************************************************************* #************************************************************************************************* #returns true if the given button is in the game_buttons list def is_game_button(self, button): return button in self.game_button_list #************************************************************************************************* #************************************************************************************************* #blits buttons to the frame def update(self, user_input): self.rect.center = self.get_center_frame_pov() self.image.fill(BLACK) for button in self.get_displayed_objects(): button.update(user_input) self.image.blit(button.image, button.rect) #************************************************************************************************* #************************************************************************************************* #makes the game list def update_game_list(self): temp_game_button_list = self.game_button_list self.game_button_list = [] game_name_list = list_available_games(remote_server_name, remote_server_port) ix = 0 for button in temp_game_button_list: if button.text in game_name_list: if ix == 0 or ix % self.buttons_per_page == 0: button.start_position = Vector2( self.back_button.rect.right, 0) self.game_button_list.append(button) else: button.start_position = Vector2( self.game_button_list[-1].start_position.x, self.game_button_list[-1].start_position.y + self.game_button_list[-1].get_height()) self.game_button_list.append(button) game_name_list.remove(button.text) ix += 1 for new_game_name in game_name_list: if ix == 0 or ix % self.buttons_per_page == 0: self.game_button_list.append( TextButton(Vector2(self.back_button.rect.right, 0), BUTTON_WIDTH, BUTTON_HEIGHT, list(globals.join_game_img_list), new_game_name, self, self.enter_lobby, (40, 22))) else: self.game_button_list.append( TextButton( Vector2( self.game_button_list[-1].start_position.x, self.game_button_list[-1].start_position.y + self.game_button_list[-1].get_height()), BUTTON_WIDTH, BUTTON_HEIGHT, list(globals.join_game_img_list), new_game_name, self, self.enter_lobby, (40, 22))) ix += 1 #************************************************************************************************* #************************************************************************************************* #makes the game list def enter_lobby(self, button): globals.online_game = join_game(button.text, remote_server_name, remote_server_port, user_name) #globals.current_screen = "game lobby" first_parent = self.main_frame_parent() from lobby import GameLobby first_parent.scene = GameLobby(globals.online_game.name)