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()
    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()
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
Esempio n. 8
0
    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()
Esempio n. 9
0
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()
Esempio n. 12
0
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)