Example #1
0
class CreditsScreen(Screen):
    """ Main menu screen """
    def __init__(self, main):
        Screen.__init__(self, main)
        self.waves = Waves()
        self.smallerfont = pygame.font.Font(None, 50)  # font for menu items

        def go_back(mpos):
            self.main.change_screen("main")
        self.clickbox.append((30, 650, 102, 50), go_back)

    def display(self, screen):
        Screen.display(self, screen)  # calls super
        self.waves.display(screen)

        textbox = pygame.Surface((1220, 430), pygame.SRCALPHA)
        textbox.fill((0, 0, 0, 128))
        for i, x in enumerate(CREDITS_TEXT):
            text = self.smallerfont.render(x, True, COLORS["white"])
            textbox.blit(text, (10, 10+i*50))

        screen.blit(textbox, (30, 200))

        text = self.smallerfont.render("Back", True, COLORS["white"])
        backbox = pygame.Surface((text.get_width()+20, 50), pygame.SRCALPHA)
        backbox.fill((0, 0, 0, 128))
        backbox.blit(text, (10, 10))
        screen.blit(backbox, (30, 650))
Example #2
0
    def __init__(self, main):
        Screen.__init__(self, main)
        self.waves = Waves()
        self.inputblock = pygame.Surface((JOIN_BOX_W, JOIN_BOX_H), pygame.SRCALPHA)
        self.inputblock.fill((0, 0, 0, 128))
        self.textbox = pygame.Surface((JOIN_TEXT_W, JOIN_TEXT_H), pygame.SRCALPHA)
        self.textbox.fill((0, 0, 0, 64))
        self.font = pygame.font.Font(None, 40)
        okbutton = pygame.Surface((JOIN_BUTT_W, JOIN_BUTT_H), pygame.SRCALPHA)
        okbutton.fill((0, 0, 0, 64))
        oktxt = self.font.render("Join", True, COLORS["white"])
        okbutton.blit(oktxt, (10, 8))
        backbutton = pygame.Surface((JOIN_BUTT_W, JOIN_BUTT_H), pygame.SRCALPHA)
        backbutton.fill((0, 0, 0, 64))
        backtxt = self.font.render("Back", True, COLORS["white"])
        backbutton.blit(backtxt, (5, 8))
        self.inputblock.blit(backbutton, (JOIN_BUTT_BUF_X, JOIN_BUTT_BUF_Y))
        self.inputblock.blit(okbutton, (self.inputblock.get_width()-JOIN_BUTT_BUF_X-okbutton.get_width(), JOIN_BUTT_BUF_Y))
        instruction = self.font.render("Server Address", True, COLORS["white"])
        self.inputblock.blit(instruction, (int(((self.inputblock.get_width()-instruction.get_width())/2.0)), 10))
        self.ip = ""
        self.countdown = 0

        def go_back(mpos):
            self.main.change_screen("main")
        self.clickbox.append((JOIN_BACK_X, JOIN_BUTT_Y, JOIN_BUTT_W, JOIN_BUTT_H), go_back)
        self.clickbox.append((JOIN_OK_X, JOIN_BUTT_Y, JOIN_BUTT_W, JOIN_BUTT_H), self.connect_ip)
Example #3
0
    def __init__(self, main):
        Screen.__init__(self, main)
        self.waves = Waves()
        self.smallerfont = pygame.font.Font(None, 50)  # font for menu items

        def go_back(mpos):
            self.main.change_screen("main")
        self.clickbox.append((30, 650, 102, 50), go_back)
Example #4
0
    def __init__(self, main):
        Screen.__init__(self, main)
        self.waves = Waves()
        self.files = None
        self.font = pygame.font.Font(None, LINE_HEIGHT)
        self.disp_area = pygame.Surface((600, 520), pygame.SRCALPHA)
        self.text_area = pygame.Surface((500, LINE_HEIGHT), pygame.SRCALPHA)
        self.save_load_button = pygame.Surface((90, LINE_HEIGHT), pygame.SRCALPHA)
        self.highlight_over_box = pygame.Surface((600, LINE_HEIGHT), pygame.SRCALPHA)
        self.highlight_over_box.fill((0, 0, 0, 64))
        self.highlight_over_loc = None
        self.highlight_click_box = pygame.Surface((600, LINE_HEIGHT), pygame.SRCALPHA)
        self.highlight_click_box.fill((0, 0, 0, 64))
        self.highlight_click_loc = None
        self.redraw_save_load()
        self.return_to = None
        self.text_area.fill((0, 0, 0, 64))
        self.text_input = ""
        self.back_button = pygame.Surface((110, 50), pygame.SRCALPHA)
        self.back_button.fill((0, 0, 0, 128))
        txt = pygame.font.Font(None, 60).render("Back", True, COLORS["white"])
        self.back_button.blit(txt, (5, 5))
        def go_back(mpos):
            if self.return_to is not None:
                self.main.change_screen(self.return_to)
            else:
                print "I got nowhere to go to."
        self.clickbox.append((40, 740, 110, 50), go_back)
        self.redraw_files()

        def m_click(mpos):
            index = mpos[1]//LINE_HEIGHT
            if index < len(self.files):
                self.highlight_click_loc = (40, index*LINE_HEIGHT + 160)
                self.text_input = self.files[index]
                self.redraw_text()
        def m_over(mpos):
            index = mpos[1]//LINE_HEIGHT
            if index < len(self.files):
                self.highlight_over_loc = (40, index*LINE_HEIGHT + 160)
            else:
                self.highlight_over_loc = None
        def m_out():
            self.highlight_over_loc = None
        self.overbox.append((40, 160, 600, 520), m_over, off=m_out)
        self.clickbox.append((40, 160, 600, 520), m_click)
        self.clickbox.append((550, 690, 90, LINE_HEIGHT), self.save_load)
Example #5
0
class JoinScreen(Screen):
    def __init__(self, main):
        Screen.__init__(self, main)
        self.waves = Waves()
        self.inputblock = pygame.Surface((JOIN_BOX_W, JOIN_BOX_H), pygame.SRCALPHA)
        self.inputblock.fill((0, 0, 0, 128))
        self.textbox = pygame.Surface((JOIN_TEXT_W, JOIN_TEXT_H), pygame.SRCALPHA)
        self.textbox.fill((0, 0, 0, 64))
        self.font = pygame.font.Font(None, 40)
        okbutton = pygame.Surface((JOIN_BUTT_W, JOIN_BUTT_H), pygame.SRCALPHA)
        okbutton.fill((0, 0, 0, 64))
        oktxt = self.font.render("Join", True, COLORS["white"])
        okbutton.blit(oktxt, (10, 8))
        backbutton = pygame.Surface((JOIN_BUTT_W, JOIN_BUTT_H), pygame.SRCALPHA)
        backbutton.fill((0, 0, 0, 64))
        backtxt = self.font.render("Back", True, COLORS["white"])
        backbutton.blit(backtxt, (5, 8))
        self.inputblock.blit(backbutton, (JOIN_BUTT_BUF_X, JOIN_BUTT_BUF_Y))
        self.inputblock.blit(okbutton, (self.inputblock.get_width()-JOIN_BUTT_BUF_X-okbutton.get_width(), JOIN_BUTT_BUF_Y))
        instruction = self.font.render("Server Address", True, COLORS["white"])
        self.inputblock.blit(instruction, (int(((self.inputblock.get_width()-instruction.get_width())/2.0)), 10))
        self.ip = ""
        self.countdown = 0

        def go_back(mpos):
            self.main.change_screen("main")
        self.clickbox.append((JOIN_BACK_X, JOIN_BUTT_Y, JOIN_BUTT_W, JOIN_BUTT_H), go_back)
        self.clickbox.append((JOIN_OK_X, JOIN_BUTT_Y, JOIN_BUTT_W, JOIN_BUTT_H), self.connect_ip)

    def display(self, screen):
        Screen.display(self, screen)
        self.waves.display(screen)
        screen.blit(self.inputblock, (JOIN_BOX_X, JOIN_BOX_Y))
        screen.blit(self.textbox, (JOIN_TEXT_X, JOIN_TEXT_Y))
        if self.countdown > 0:
            self.countdown -= 1
            if not self.countdown:
                self.redraw_textbox(False)

    def connect_ip(self, mpos=None):
        try:
            if count(self.ip, ".") == 3:
                int(self.ip[-1:])   # what we're "try"ing
                if self.main.join_server(self.ip):
                    self.main.change_screen("lobby")  # TODO: yeah connecting things
                return
        except ValueError:
            pass
        self.redraw_textbox(True)

    def redraw_textbox(self, bad_input=False):
        if bad_input:
            self.countdown = 3
            self.textbox.fill((0xFF, 0, 0, 128))
        else:
            self.textbox.fill((0, 0, 0, 64))
        txt = self.font.render(self.ip, True, COLORS["white"])
        self.textbox.blit(txt, (2, 2))

    def notify_key(self, inkey):
        if inkey.key == pygame.K_BACKSPACE:
            self.ip = self.ip[:-1]
        elif inkey.key == pygame.K_RETURN or inkey.key == pygame.K_KP_ENTER:
            self.connect_ip(self)
            return
        elif pygame.key.get_mods() & pygame.KMOD_CTRL:
            if inkey.key == pygame.K_v:
                try:
                    pygame.scrap.init()
                    word = str(pygame.scrap.get(pygame.SCRAP_TEXT)).rstrip(u"\x00")
                    try:
                        test = map(int, word.split("."))
                        if len(test) != 4 or any(x for x in test if not (0 <= x < 256)):
                            self.redraw_textbox(True)
                            return
                    except ValueError:
                        self.redraw_textbox(True)
                        return
                    self.ip = word
                except:
                    pass  # ghetto fix!
            else:
                return
        elif inkey.unicode:
            try:
                if inkey.unicode != ".":
                    int(inkey.unicode)
            except ValueError:
                self.redraw_textbox(True)
                return
            if inkey.unicode != "." and len(self.ip) >= 3 and "." not in self.ip[-3:]:  # needs a . seperator
                if count(self.ip, ".") >= 3:
                    return
                self.ip += "."
            if inkey.unicode == "." and (self.ip[-1:] in (".", "") or count(self.ip, ".") >= 3):
                return
            self.ip += inkey.unicode
        else:
            return  # if none of these things happened, no need to redraw
        self.redraw_textbox()
Example #6
0
class SaveLoadScreen(Screen):
    def __init__(self, main):
        Screen.__init__(self, main)
        self.waves = Waves()
        self.files = None
        self.font = pygame.font.Font(None, LINE_HEIGHT)
        self.disp_area = pygame.Surface((600, 520), pygame.SRCALPHA)
        self.text_area = pygame.Surface((500, LINE_HEIGHT), pygame.SRCALPHA)
        self.save_load_button = pygame.Surface((90, LINE_HEIGHT), pygame.SRCALPHA)
        self.highlight_over_box = pygame.Surface((600, LINE_HEIGHT), pygame.SRCALPHA)
        self.highlight_over_box.fill((0, 0, 0, 64))
        self.highlight_over_loc = None
        self.highlight_click_box = pygame.Surface((600, LINE_HEIGHT), pygame.SRCALPHA)
        self.highlight_click_box.fill((0, 0, 0, 64))
        self.highlight_click_loc = None
        self.redraw_save_load()
        self.return_to = None
        self.text_area.fill((0, 0, 0, 64))
        self.text_input = ""
        self.back_button = pygame.Surface((110, 50), pygame.SRCALPHA)
        self.back_button.fill((0, 0, 0, 128))
        txt = pygame.font.Font(None, 60).render("Back", True, COLORS["white"])
        self.back_button.blit(txt, (5, 5))
        def go_back(mpos):
            if self.return_to is not None:
                self.main.change_screen(self.return_to)
            else:
                print "I got nowhere to go to."
        self.clickbox.append((40, 740, 110, 50), go_back)
        self.redraw_files()

        def m_click(mpos):
            index = mpos[1]//LINE_HEIGHT
            if index < len(self.files):
                self.highlight_click_loc = (40, index*LINE_HEIGHT + 160)
                self.text_input = self.files[index]
                self.redraw_text()
        def m_over(mpos):
            index = mpos[1]//LINE_HEIGHT
            if index < len(self.files):
                self.highlight_over_loc = (40, index*LINE_HEIGHT + 160)
            else:
                self.highlight_over_loc = None
        def m_out():
            self.highlight_over_loc = None
        self.overbox.append((40, 160, 600, 520), m_over, off=m_out)
        self.clickbox.append((40, 160, 600, 520), m_click)
        self.clickbox.append((550, 690, 90, LINE_HEIGHT), self.save_load)

    def redraw_save_load(self, save=True):
        self.save_notload = save
        self.save_load_button.fill((0, 0, 0, 64))
        txt = self.font.render("Save" if save else "Load", True, COLORS["white"])
        self.save_load_button.blit(txt, (12, 8))

    def redraw_files(self):
        d = os.path.dirname("../saves/")
        if not os.path.exists(d):
            os.makedirs(d)
        self.files = ['.'.join(f.split(".")[:-1]) for f in os.listdir("../saves/") if "sav"==f.split(".")[-1]]
        self.disp_area.fill((0, 0, 0, 64))
        for i, f in enumerate(self.files):
            txt = self.font.render(f, True, COLORS["white"])
            self.disp_area.blit(txt, (10, i*LINE_HEIGHT+10))

    def redraw_text(self):
        self.text_area.fill((0, 0, 0, 64))
        txt = self.font.render(self.text_input, True, COLORS["white"])
        self.text_area.blit(txt, (5, 5))

    def on_switch_in(self):
        self.main.reset_screen("saveload")

    def display(self, screen):
        Screen.display(self, screen)
        self.waves.display(screen)
        if self.highlight_over_loc is not None:
            screen.blit(self.highlight_over_box, self.highlight_over_loc)
        if self.highlight_click_loc is not None:
            screen.blit(self.highlight_click_box, self.highlight_click_loc)
        screen.blit(self.disp_area, (40, 160))
        screen.blit(self.text_area, (40, 690))
        screen.blit(self.save_load_button, (550, 690))
        screen.blit(self.back_button, (40, 740))

    def save_load(self, mpos=None):
        if not self.text_input:
            #print "Invalid filename"
            return False
        f = self.text_input+".sav"
        if self.save_notload:
            if self.text_input in self.files:
                #print "Hot damn are you sure you want to overwrite that file?"
                return False
            if self.return_to is not None:
                self.main.change_screen(self.return_to)
            self.main.save("../saves/"+f)
            self.main.change_screen("saveload")
        else:   # load
            if self.text_input not in self.files:
                #print "File does not exist"
                return False
            self.main.load("../saves/"+f)

    def notify_key(self, inkey):
        if inkey.key == pygame.K_BACKSPACE:
            self.text_input = self.text_input[:-1]
        elif inkey.key == pygame.K_TAB:
            try:    # tab complete
                mname = self.text_input.lower()
                if mname == "":  # don't tab complete on nothing
                    return
                matches = []    # files whose names we've matched
                for i, name in enumerate(self.files):
                    if mname == name[:len(mname)].lower():  # if the first part of their name is what you've typed
                        matches += [name]       # they're a match
                if len(matches) == 1:
                    self.text_input = matches[0]
                elif len(matches) > 1:
                    def get_most_letters():
                        text = ""
                        for x in xrange(len(mname), MAX_FILE_NAME):
                            letter = None
                            for i in matches:
                                if letter is None:
                                    letter = i[x:x+1]
                                    if letter == "":
                                        return text
                                elif i[x:x+1] != letter:
                                    return text
                            text += letter
                    self.text_input += get_most_letters()
            except IndexError:
                pass
        elif inkey.key == pygame.K_RETURN or inkey.key == pygame.K_KP_ENTER:
            self.save_load()
        elif inkey.unicode and len(self.text_input) < MAX_FILE_NAME and inkey.unicode not in "\\/:*?\"<>|":
            self.text_input += inkey.unicode    # send the unicode character you pressed
        else:
            return  # if none of these things happened, no need to redraw
        self.redraw_text()
Example #7
0
class MainScreen(Screen):
    """Main menu screen."""
    def __init__(self, main):
        Screen.__init__(self, main)
        self.selectbox = [None, 15, 205, 50, True]  # coords of the box (x, y, width, height) which highlights selected item
        self.gotobox = [12.5, 15, 205, 50]  # coords of the desitination of the selectbox
        self.sel_accel = 3  # acceleration to new pos
        self.sel_speed = 0  # current speed
        self.smallerfont = pygame.font.Font(None, 50)  # font for menu items

        self.options = ["New Game", "Load Game", "Tutorial", "Options", "Credits", "Exit"]  # menu options
        self.submenuoptions = None
        self.submenu = 0    # submenu = 1 means one submenu is open
        self.maxwid = max([self.smallerfont.size(x)[0] for x in self.options])  # width of hitbox (highlighted area)

        self.textbox = None
        self.text_input = ""
        self.entering_name = False

        self.waves = Waves()

        def over(setbit):
            def anon(mpos):  # picks new location for gotobox
                self.selectbox[4] = setbit
                self.selectbox[2] = (self.maxwid if setbit else self.submaxwid)+25
                wait = (mpos[1] - 13)//50
                if 0 <= wait < len(self.options):
                    self.gotobox = [12.5, (wait * 50) + 15]
                    if self.selectbox[0] is None:
                        self.selectbox[0:2] = self.gotobox[:]
            return anon

        def out():  # removes box since we have left menu
            self.selectbox[0] = None

        self.overbox.append((30, 200, self.maxwid+50, 330), over(True), out)    # makes entire menu mouse-over-able

        def click_newgame(mpos):
            self.entering_name = False
            if self.submenu == 1:   # you've already clicked new game
                return
            self.clickbox.clear(2)
            #if self.submenu != 0:   # you've clicked on options (or load)
            #    self.overbox.remove((90+self.maxwid, 200))  # remove that submenu's overbox
            #    self.clickbox.remove((90+self.maxwid, 250))
            self.submenu = 1
            self.submenuoptions = ["Quick Play", "Join Multiplayer", "Host Multiplayer"]
            self.submaxwid = self.maxwidth(self.submenuoptions)
            self.overbox.append((90+self.maxwid, 200, self.submaxwid+50, 150), over(False), out)

            def click_singleplayer(mpos):
                self.main.reset_screen("game", 2, True)
                self.main.reset_screen("shop")
                self.main.change_screen("game")

            def click_joingame(mpos):
                self.main.change_screen("join")

            def click_hostgame(mpos):
                self.main.server = networking.Server()
                self.main.server.start()
                self.main.join_server()
                if self.main.player_name is None:
                    self.main.player_name = 'Host'
                self.main.change_screen("lobby")

            self.clickbox.append((90+self.maxwid, 215, self.submaxwid+50, 50), click_singleplayer, z=2)
            self.clickbox.append((90+self.maxwid, 265, self.submaxwid+50, 50), click_joingame, z=2)
            self.clickbox.append((90+self.maxwid, 315, self.submaxwid+50, 50), click_hostgame, z=2)

        def click_loadgame(mpos):
            self.entering_name = False
            self.main.change_screen("saveload")
            self.main.screens["saveload"].redraw_save_load(False)
            self.main.screens["saveload"].return_to = "main"

        def click_options(mpos):
            self.entering_name = False

            if self.submenu == 2:
                return
            if self.submenu == 1:   # new game submenu is open
                self.overbox.remove((90+self.maxwid, 200))
                #self.clickbox.remove((90+self.maxwid, 200))
                self.clickbox.remove((90+self.maxwid, 215))
                self.clickbox.remove((90+self.maxwid, 265))
                self.clickbox.remove((90+self.maxwid, 315))
            self.submenu = 2
            self.submenuoptions = ["Multiplayer name:", "________________"]
            self.submaxwid = self.maxwidth(self.submenuoptions)
            #self.overbox.append((90+self.maxwid, 200, self.submaxwid+50, 280), over(False), out)
            self.textbox = pygame.Surface((750, 40), pygame.SRCALPHA)
            if self.main.player_name is not None:
                self.textbox.blit(self.smallerfont.render(self.main.player_name.strip(), True, COLORS["white"]), (5, 5))

            def click_changename(mpos):
                self.entering_name = True
                if self.main.player_name is not None:
                    self.text_input = self.main.player_name
                #if self.main.valid_nick(self.text_input):
                #    self.main.player_name = self.text_input
                #else:
                #    self.main.player_name = None

            self.clickbox.append((90+self.maxwid, 250, self.submaxwid+50, 50), click_changename, z=2)

        def click_credits(mpos):
            self.entering_name = False
            if self.main.valid_nick(self.text_input.strip()):
                self.main.player_name = self.text_input.strip()
            else:
                self.main.player_name = None
            self.main.change_screen("credits")

        def click_exit(mpos):  # ideally this will close the game
            self.main.exit()

        def click_tutorial(mpos):
            self.main.change_screen("tutorial")

        for i, x in enumerate([click_newgame, click_loadgame, click_tutorial, click_options, click_credits, click_exit]):
            self.clickbox.append((30, 215+50*i, 205, 45), x)

    def display(self, screen):
        """ main screen turn on """
        Screen.display(self, screen)  # calls super

        self.waves.display(screen)
        ####################################

        textbox = pygame.Surface((self.maxwid + 50, len(self.options)*50+30), pygame.SRCALPHA)
        textbox.fill((0, 0, 0, 128))

        if self.submenuoptions is not None:
            subtextbox = pygame.Surface((self.submaxwid + 50, len(self.submenuoptions)*50+30), pygame.SRCALPHA)
            subtextbox.fill((0, 0, 0, 128))

        #decide whether or not to move selectbox then do so
        if self.selectbox[0] is not None:
            direction = math.copysign(1, self.gotobox[1] - self.selectbox[1])
            if self.selectbox[1] == self.gotobox[1]:
                self.sel_speed = 0
            else:
                self.sel_speed += direction * self.sel_accel
                self.selectbox[1] += self.sel_speed
                if direction < 0:
                    self.selectbox[1] = max(self.selectbox[1], self.gotobox[1])
                else:
                    self.selectbox[1] = min(self.selectbox[1], self.gotobox[1])
            if not (12.5 <= self.selectbox[1] <= (len(self.options) - 1) * 50 + 12.5):
                self.selectbox[1] = max(min((len(self.options) - 1) * 50 + 12.5, self.selectbox[1]), 12.5)
                self.sel_speed = 0
            pygame.draw.rect((textbox if self.selectbox[4] else subtextbox), (0, 0, 0, 192), self.selectbox[:4])

        #draw all the menu items
        for i, x in enumerate(self.options):
            text = self.smallerfont.render(x, True, COLORS["white"])
            textbox.blit(text, (25, i * 50 + 25))

        if self.submenuoptions is not None:
            for i, x in enumerate(self.submenuoptions):
                text = self.smallerfont.render(x, True, COLORS["white"])
                subtextbox.blit(text, (25, i * 50 + 25))
            screen.blit(subtextbox, (90 + self.maxwid, 200))

        if self.submenu == 2:
            #screen.blit(self.textbox, (300, 270))
            screen.blit(self.textbox, (300, 270), (min(self.textbox.get_width()-self.submaxwid, max(0, (self.smallerfont.size(self.text_input)[0])-self.submaxwid+10)), 0, self.submaxwid, 40))

        screen.blit(textbox, (30, 200))

    def maxwidth(self, optionlist):
        return max([self.smallerfont.size(x)[0] for x in optionlist])

    def notify_key(self, inkey):
        if self.entering_name:
            if inkey.key == pygame.K_BACKSPACE:
                self.text_input = self.text_input[:-1]
            elif inkey.key == pygame.K_RETURN or inkey.key == pygame.K_KP_ENTER:
                return
            elif inkey.unicode:
                if len(self.text_input) < 2 or self.main.valid_nick((self.text_input+inkey.unicode).strip()):
                    self.text_input += inkey.unicode
            else:
                return  # if none of these things happened, no need to redraw
            self.textbox.fill((0, 0, 0, 0))
            txt = self.smallerfont.render(self.text_input, True, COLORS["white"])
            self.textbox.blit(txt, (5, 5))
            if self.main.valid_nick(self.text_input.strip()):
                self.main.player_name = self.text_input.strip()
            else:
                self.main.player_name = None

    def on_switch_in(self):
        self.main.reset_screen("game")
        self.main.reset_screen("shop")
        self.main.reset_screen("upgrade")
        if self.main.server is not None:
            self.main.server.stop()
            self.main.server = None
        if self.main.client is not None:
            self.main.client.stop()
            self.main.client = None
Example #8
0
    def __init__(self, main):
        Screen.__init__(self, main)
        self.selectbox = [None, 15, 205, 50, True]  # coords of the box (x, y, width, height) which highlights selected item
        self.gotobox = [12.5, 15, 205, 50]  # coords of the desitination of the selectbox
        self.sel_accel = 3  # acceleration to new pos
        self.sel_speed = 0  # current speed
        self.smallerfont = pygame.font.Font(None, 50)  # font for menu items

        self.options = ["New Game", "Load Game", "Tutorial", "Options", "Credits", "Exit"]  # menu options
        self.submenuoptions = None
        self.submenu = 0    # submenu = 1 means one submenu is open
        self.maxwid = max([self.smallerfont.size(x)[0] for x in self.options])  # width of hitbox (highlighted area)

        self.textbox = None
        self.text_input = ""
        self.entering_name = False

        self.waves = Waves()

        def over(setbit):
            def anon(mpos):  # picks new location for gotobox
                self.selectbox[4] = setbit
                self.selectbox[2] = (self.maxwid if setbit else self.submaxwid)+25
                wait = (mpos[1] - 13)//50
                if 0 <= wait < len(self.options):
                    self.gotobox = [12.5, (wait * 50) + 15]
                    if self.selectbox[0] is None:
                        self.selectbox[0:2] = self.gotobox[:]
            return anon

        def out():  # removes box since we have left menu
            self.selectbox[0] = None

        self.overbox.append((30, 200, self.maxwid+50, 330), over(True), out)    # makes entire menu mouse-over-able

        def click_newgame(mpos):
            self.entering_name = False
            if self.submenu == 1:   # you've already clicked new game
                return
            self.clickbox.clear(2)
            #if self.submenu != 0:   # you've clicked on options (or load)
            #    self.overbox.remove((90+self.maxwid, 200))  # remove that submenu's overbox
            #    self.clickbox.remove((90+self.maxwid, 250))
            self.submenu = 1
            self.submenuoptions = ["Quick Play", "Join Multiplayer", "Host Multiplayer"]
            self.submaxwid = self.maxwidth(self.submenuoptions)
            self.overbox.append((90+self.maxwid, 200, self.submaxwid+50, 150), over(False), out)

            def click_singleplayer(mpos):
                self.main.reset_screen("game", 2, True)
                self.main.reset_screen("shop")
                self.main.change_screen("game")

            def click_joingame(mpos):
                self.main.change_screen("join")

            def click_hostgame(mpos):
                self.main.server = networking.Server()
                self.main.server.start()
                self.main.join_server()
                if self.main.player_name is None:
                    self.main.player_name = 'Host'
                self.main.change_screen("lobby")

            self.clickbox.append((90+self.maxwid, 215, self.submaxwid+50, 50), click_singleplayer, z=2)
            self.clickbox.append((90+self.maxwid, 265, self.submaxwid+50, 50), click_joingame, z=2)
            self.clickbox.append((90+self.maxwid, 315, self.submaxwid+50, 50), click_hostgame, z=2)

        def click_loadgame(mpos):
            self.entering_name = False
            self.main.change_screen("saveload")
            self.main.screens["saveload"].redraw_save_load(False)
            self.main.screens["saveload"].return_to = "main"

        def click_options(mpos):
            self.entering_name = False

            if self.submenu == 2:
                return
            if self.submenu == 1:   # new game submenu is open
                self.overbox.remove((90+self.maxwid, 200))
                #self.clickbox.remove((90+self.maxwid, 200))
                self.clickbox.remove((90+self.maxwid, 215))
                self.clickbox.remove((90+self.maxwid, 265))
                self.clickbox.remove((90+self.maxwid, 315))
            self.submenu = 2
            self.submenuoptions = ["Multiplayer name:", "________________"]
            self.submaxwid = self.maxwidth(self.submenuoptions)
            #self.overbox.append((90+self.maxwid, 200, self.submaxwid+50, 280), over(False), out)
            self.textbox = pygame.Surface((750, 40), pygame.SRCALPHA)
            if self.main.player_name is not None:
                self.textbox.blit(self.smallerfont.render(self.main.player_name.strip(), True, COLORS["white"]), (5, 5))

            def click_changename(mpos):
                self.entering_name = True
                if self.main.player_name is not None:
                    self.text_input = self.main.player_name
                #if self.main.valid_nick(self.text_input):
                #    self.main.player_name = self.text_input
                #else:
                #    self.main.player_name = None

            self.clickbox.append((90+self.maxwid, 250, self.submaxwid+50, 50), click_changename, z=2)

        def click_credits(mpos):
            self.entering_name = False
            if self.main.valid_nick(self.text_input.strip()):
                self.main.player_name = self.text_input.strip()
            else:
                self.main.player_name = None
            self.main.change_screen("credits")

        def click_exit(mpos):  # ideally this will close the game
            self.main.exit()

        def click_tutorial(mpos):
            self.main.change_screen("tutorial")

        for i, x in enumerate([click_newgame, click_loadgame, click_tutorial, click_options, click_credits, click_exit]):
            self.clickbox.append((30, 215+50*i, 205, 45), x)
Example #9
0
    def __init__(self, main, host=True):
        Screen.__init__(self, main)

        self.my_index = 0

        self.player_colors = [(0xFF, 0, 0), (0, 0xFF, 0), (0xFF, 0, 0xFF), (0xFF, 0xFF, 0),
                              (0, 0xFF, 0xFF), (0xFF, 180, 0), (180, 0, 0xFF),
                              (0, 0xFF, 100), (0xFF, 0xCC, 0xCC), (0xCC, 0xCC, 0xFF)]
        self.color_pick = 0
        self.largefont = pygame.font.Font(None, 70)
        self.font = pygame.font.Font(None, 30)

        self.waves = Waves()

        self.player_menu = pygame.Surface((415, 120), pygame.SRCALPHA)
        self.player_menu_pos = (0, 0)

        self.players_panel = pygame.Surface((496, 578), pygame.SRCALPHA)
        self.players_panel.fill((0, 0, 0, 128))
        self.players = []

        self.start_timeout = time.time()

        self.players.append(["Host", pygame.Surface((474, 48), pygame.SRCALPHA), False])
        for _ in xrange(1, 10):
            self.players.append([CLOSED, pygame.Surface((474, 48), pygame.SRCALPHA), False])
        self.redraw_players()
        self.chat_panel = pygame.Surface((696, 578), pygame.SRCALPHA)
        self.chat_panel.fill((0, 0, 0, 128))
        send_button = pygame.Surface((67, 30), pygame.SRCALPHA)
        send_button.fill((0, 0, 0, 64))
        txt = self.font.render("Send", True, (0xCC, )*3)    # TODO: nope
        send_button.blit(txt, (10, 7))
        self.chat_panel.blit(send_button, (20+582+5, 577-38))
        self.textbox = pygame.Surface((1820, 30), pygame.SRCALPHA)
        self.textbox.fill((0, 0, 0, 64))
        self.base_panel = pygame.Surface((1215, 96), pygame.SRCALPHA)
        self.base_panel.fill((0, 0, 0, 128))
        txt_leave_lobby = self.largefont.render("Leave Lobby", True, COLORS["white"])
        self.button_leave_lobby = pygame.Surface((331, 76), pygame.SRCALPHA)
        self.button_leave_lobby.fill((0, 0, 0, 64))
        self.button_leave_lobby.blit(txt_leave_lobby, (15, 15))
        self.base_panel.blit(self.button_leave_lobby, (10, 10))

        if host:
            def get_ip():
                try:
                    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    s.connect(('google.com', 80))
                    ip = s.getsockname()[0]
                    s.close()

                    txt_ip = self.largefont.render(ip, True, COLORS["white"])
                    self.base_panel.blit(txt_ip, (450, 25))

                    def copy_ip(mpos):
                        try:
                            pygame.scrap.init()
                            pygame.scrap.put(pygame.SCRAP_TEXT, ip)
                        except:
                            pass  # fixes!

                    self.clickbox.append((476, 706, txt_ip.get_width(), txt_ip.get_height()), copy_ip)
                except (urllib2.URLError, urllib2.HTTPError, IOError):
                    print "Error fetching IP"
            threading.Thread(target=get_ip).start()

        self.button_start = pygame.Surface((331, 76), pygame.SRCALPHA)
        self.button_start.fill((0, 0, 0, 64))
        txt_start_game = self.largefont.render("Start Game", True, COLORS["white"])
        self.button_start.blit(txt_start_game, (30, 15))
        self.base_panel.blit(self.button_start, (870, 10))

        def start_game(mpos):
            if time.time() - self.start_timeout > 3:
                self.main.client.start_game()
                self.start_timeout = time.time()
        self.clickbox.append((900, 690, 331, 76), start_game)

        self.text_input = ""
        self.msgpanel = MessagePanel((652, 509), 23, self.font)
        self.startable = False

        def to_main(mpos):
            self.main.change_screen("main")
        self.clickbox.append((37, 692, 329, 74), to_main)

        def ready_button_click(i):
            def anon(mpos):
                if i == self.my_index:
                    self.main.client.set_ready(int(not self.players[i][2]))
                else:
                    print "ready button clicked!!"
            return anon
        for x in xrange(10):
            self.clickbox.append((37, 75+54*x, 48, 48), ready_button_click(x))

        def player_panel_click(i):
            def anon(mpos):
                if self.my_index == 0:      # only the host can kick
                    if i == self.my_index:
                        pass
                    elif isinstance(self.players[i][0], int):
                        self.player_menu_pos = (95, 75+54*i+48)
                        options = ["Closed", "Open", "AI"]
                        self.player_menu.fill((0, 0, 0, 128))

                        def clearworking(mpos):
                            self.player_menu_pos = (0, 0)
                            for k in xrange(3):
                                self.clickbox.remove((95, 75+54*i+48+k*40+5))
                            self.clickbox.remove((0, 0))
                        self.clickbox.append((0, 0, 1280, 800), clearworking, z=2)
                        for j, option in enumerate(options):
                            def wrapper(toWhat):
                                def changeto(mpos):
                                    self.main.client.set_slot(i, toWhat+1)
                                    self.player_menu_pos = (0, 0)
                                    for k in xrange(3):
                                        self.clickbox.remove((95, 75+54*i+48+k*40+5))
                                    self.clickbox.remove((0, 0))
                                return changeto
                            self.clickbox.append((95, 75+54*i+48+j*40+5, 415, 40), wrapper(j), z=3)
                            text = self.font.render(option, True, COLORS["white"])
                            self.player_menu.blit(text, (5, 5+j*40))
                    else:   # it's a person
                        self.player_menu_pos = (95, 75+54*i+48)
                        self.player_menu.fill((0, 0, 0, 0))
                        pygame.draw.rect(self.player_menu, (0, 0, 0, 128), (0, 0, 415, 30))

                        def clearworking(mpos):
                            self.player_menu_pos = (0, 0)
                            self.clickbox.remove((95, 75+54*i+48+5))
                            self.clickbox.remove((0, 0))
                        self.clickbox.append((0, 0, 1280, 800), clearworking, z=2)

                        def kickhim(mpos):
                            self.main.client.kick_player(str(i))
                            self.player_menu_pos = (0, 0)
                            self.clickbox.remove((95, 75+54*i+48+5))
                            self.clickbox.remove((0, 0))
                        self.clickbox.append((95, 75+54*i+48, 415, 40), kickhim, z=3)
                        text = self.font.render("Kick", True, COLORS["white"])
                        self.player_menu.blit(text, (5, 5))
            return anon
        for x in xrange(10):
            self.clickbox.append((95, 75+54*x, 415, 48), player_panel_click(x))

        def wrapper(mpos):
            self.message()
            self.textbox.fill((0, 0, 0, 64))
            txt = self.font.render(self.text_input, True, COLORS["white"])
            self.textbox.blit(txt, (5, 5))
        self.clickbox.append((1154, 580, 64, 25), wrapper)
Example #10
0
class LobbyScreen(Screen):
    def __init__(self, main, host=True):
        Screen.__init__(self, main)

        self.my_index = 0

        self.player_colors = [(0xFF, 0, 0), (0, 0xFF, 0), (0xFF, 0, 0xFF), (0xFF, 0xFF, 0),
                              (0, 0xFF, 0xFF), (0xFF, 180, 0), (180, 0, 0xFF),
                              (0, 0xFF, 100), (0xFF, 0xCC, 0xCC), (0xCC, 0xCC, 0xFF)]
        self.color_pick = 0
        self.largefont = pygame.font.Font(None, 70)
        self.font = pygame.font.Font(None, 30)

        self.waves = Waves()

        self.player_menu = pygame.Surface((415, 120), pygame.SRCALPHA)
        self.player_menu_pos = (0, 0)

        self.players_panel = pygame.Surface((496, 578), pygame.SRCALPHA)
        self.players_panel.fill((0, 0, 0, 128))
        self.players = []

        self.start_timeout = time.time()

        self.players.append(["Host", pygame.Surface((474, 48), pygame.SRCALPHA), False])
        for _ in xrange(1, 10):
            self.players.append([CLOSED, pygame.Surface((474, 48), pygame.SRCALPHA), False])
        self.redraw_players()
        self.chat_panel = pygame.Surface((696, 578), pygame.SRCALPHA)
        self.chat_panel.fill((0, 0, 0, 128))
        send_button = pygame.Surface((67, 30), pygame.SRCALPHA)
        send_button.fill((0, 0, 0, 64))
        txt = self.font.render("Send", True, (0xCC, )*3)    # TODO: nope
        send_button.blit(txt, (10, 7))
        self.chat_panel.blit(send_button, (20+582+5, 577-38))
        self.textbox = pygame.Surface((1820, 30), pygame.SRCALPHA)
        self.textbox.fill((0, 0, 0, 64))
        self.base_panel = pygame.Surface((1215, 96), pygame.SRCALPHA)
        self.base_panel.fill((0, 0, 0, 128))
        txt_leave_lobby = self.largefont.render("Leave Lobby", True, COLORS["white"])
        self.button_leave_lobby = pygame.Surface((331, 76), pygame.SRCALPHA)
        self.button_leave_lobby.fill((0, 0, 0, 64))
        self.button_leave_lobby.blit(txt_leave_lobby, (15, 15))
        self.base_panel.blit(self.button_leave_lobby, (10, 10))

        if host:
            def get_ip():
                try:
                    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    s.connect(('google.com', 80))
                    ip = s.getsockname()[0]
                    s.close()

                    txt_ip = self.largefont.render(ip, True, COLORS["white"])
                    self.base_panel.blit(txt_ip, (450, 25))

                    def copy_ip(mpos):
                        try:
                            pygame.scrap.init()
                            pygame.scrap.put(pygame.SCRAP_TEXT, ip)
                        except:
                            pass  # fixes!

                    self.clickbox.append((476, 706, txt_ip.get_width(), txt_ip.get_height()), copy_ip)
                except (urllib2.URLError, urllib2.HTTPError, IOError):
                    print "Error fetching IP"
            threading.Thread(target=get_ip).start()

        self.button_start = pygame.Surface((331, 76), pygame.SRCALPHA)
        self.button_start.fill((0, 0, 0, 64))
        txt_start_game = self.largefont.render("Start Game", True, COLORS["white"])
        self.button_start.blit(txt_start_game, (30, 15))
        self.base_panel.blit(self.button_start, (870, 10))

        def start_game(mpos):
            if time.time() - self.start_timeout > 3:
                self.main.client.start_game()
                self.start_timeout = time.time()
        self.clickbox.append((900, 690, 331, 76), start_game)

        self.text_input = ""
        self.msgpanel = MessagePanel((652, 509), 23, self.font)
        self.startable = False

        def to_main(mpos):
            self.main.change_screen("main")
        self.clickbox.append((37, 692, 329, 74), to_main)

        def ready_button_click(i):
            def anon(mpos):
                if i == self.my_index:
                    self.main.client.set_ready(int(not self.players[i][2]))
                else:
                    print "ready button clicked!!"
            return anon
        for x in xrange(10):
            self.clickbox.append((37, 75+54*x, 48, 48), ready_button_click(x))

        def player_panel_click(i):
            def anon(mpos):
                if self.my_index == 0:      # only the host can kick
                    if i == self.my_index:
                        pass
                    elif isinstance(self.players[i][0], int):
                        self.player_menu_pos = (95, 75+54*i+48)
                        options = ["Closed", "Open", "AI"]
                        self.player_menu.fill((0, 0, 0, 128))

                        def clearworking(mpos):
                            self.player_menu_pos = (0, 0)
                            for k in xrange(3):
                                self.clickbox.remove((95, 75+54*i+48+k*40+5))
                            self.clickbox.remove((0, 0))
                        self.clickbox.append((0, 0, 1280, 800), clearworking, z=2)
                        for j, option in enumerate(options):
                            def wrapper(toWhat):
                                def changeto(mpos):
                                    self.main.client.set_slot(i, toWhat+1)
                                    self.player_menu_pos = (0, 0)
                                    for k in xrange(3):
                                        self.clickbox.remove((95, 75+54*i+48+k*40+5))
                                    self.clickbox.remove((0, 0))
                                return changeto
                            self.clickbox.append((95, 75+54*i+48+j*40+5, 415, 40), wrapper(j), z=3)
                            text = self.font.render(option, True, COLORS["white"])
                            self.player_menu.blit(text, (5, 5+j*40))
                    else:   # it's a person
                        self.player_menu_pos = (95, 75+54*i+48)
                        self.player_menu.fill((0, 0, 0, 0))
                        pygame.draw.rect(self.player_menu, (0, 0, 0, 128), (0, 0, 415, 30))

                        def clearworking(mpos):
                            self.player_menu_pos = (0, 0)
                            self.clickbox.remove((95, 75+54*i+48+5))
                            self.clickbox.remove((0, 0))
                        self.clickbox.append((0, 0, 1280, 800), clearworking, z=2)

                        def kickhim(mpos):
                            self.main.client.kick_player(str(i))
                            self.player_menu_pos = (0, 0)
                            self.clickbox.remove((95, 75+54*i+48+5))
                            self.clickbox.remove((0, 0))
                        self.clickbox.append((95, 75+54*i+48, 415, 40), kickhim, z=3)
                        text = self.font.render("Kick", True, COLORS["white"])
                        self.player_menu.blit(text, (5, 5))
            return anon
        for x in xrange(10):
            self.clickbox.append((95, 75+54*x, 415, 48), player_panel_click(x))

        def wrapper(mpos):
            self.message()
            self.textbox.fill((0, 0, 0, 64))
            txt = self.font.render(self.text_input, True, COLORS["white"])
            self.textbox.blit(txt, (5, 5))
        self.clickbox.append((1154, 580, 64, 25), wrapper)

    def redraw_players(self):
        self.players_panel.fill((0, 0, 0, 128))
        for i, (name, surf, ready) in enumerate(self.players):
            surf.fill((0, 0, 0, 64))
            if ready:
                pygame.draw.rect(surf, (135, 221, 68, 128), (0, 0, 48, 48))
            pygame.draw.rect(surf, (0, 0, 0, 0), (48, 0, 12, 48))  # clear
            color = self.player_colors[i]
            if isinstance(name, int):
                color = (0x80, 0x80, 0x80)
                if name == CLOSED:
                    name = "Closed"
                elif name == OPEN:
                    name = "Open"
                elif name == AI:
                    name = "AI Player"
            surf.blit(self.font.render(name, True, color), (65, 15))
            self.players_panel.blit(surf, (10, 37+i*54))

    def display(self, screen):
        Screen.display(self, screen)
        # I feel like the following code is flipping me off...
        self.waves.display(screen, False)
        screen.blit(self.players_panel, (26, 38))
        screen.blit(self.chat_panel, (545, 38))
        screen.blit(self.textbox, (565, 577), (min(self.textbox.get_width()-582, max(0, (self.font.size(self.text_input)[0])-582+10)), 0, 582, 30))
        screen.blit(self.base_panel, (26, 681))
        screen.blit(self.msgpanel.view, (566, 63))

        if self.player_menu_pos != (0, 0):
            screen.blit(self.player_menu, (self.player_menu_pos[0], self.player_menu_pos[1]))

    def message(self, data=None):
        index = self.my_index
        msg = self.text_input
        if not (data is None):  # gotta parse the data
            data = data.split(" ")
            index, msg = int(data[0]), ' '.join(data[1:])
        if msg:  # needs to like... say something.
            if isinstance(self.players[index][0], int):
                #print "Why is", self.players[index][0], "trying to talk?"
                return
            if index == self.my_index:
                self.text_input = ""
                if msg[:6] == "/nick ":
                    newnick = msg[6:]
                    if self.main.valid_nick(newnick):
                        self.send_nick_change(newnick)
                    return
                if msg[:6] == "/kick ":
                    newkick = msg[6:].lower()
                    for i, (name, _, _) in enumerate(self.players):
                        if not isinstance(name, int):
                            if name.lower() == newkick:
                                self.main.client.kick_player(str(i))
                                self.recv_kick_player(str(i))
                    return
                self.main.client.send_message(msg)
            self.msgpanel.message(self.players[index][0], msg, self.player_colors[index])

    def reload_server_data(self, data):
        """ loading player data after joining a lobby """
        self.main.race_cond = True
        self.my_index = int(data[0])    # what slot should you get
        data = data.split("\n")[1:]     # split on newlines (ignore the first slot)
        #print data
        for i, d in enumerate(data):     #
            num = int(d[0])             # are you a player or a certain value
            if num:                     # if not a human
                self.players[i][0] = num    # make my "name" that value
                self.players[i][2] = False  # also i'm 'unready'
            else:                           # 0 c Name (c is 0 if unready, 1 if ready)
                self.players[i][0] = d[4:]  # the rest of the string after the first two characters and spaces is the name
                self.players[i][2] = bool(int(d[2]))    # char space _char_ is readiness
        if self.main.player_name is None:
            self.main.player_name = self.players[self.my_index][0]
        self.redraw_players()           # redraw that board

    def ready_up(self, data):
        #print data
        index, ready = int(data[0]), bool(int(data[2]))
        self.players[index][2] = ready
        self.redraw_players()

    def send_nick_change(self, nick):
        self.main.player_name = nick
        self.main.client.change_name(nick)

    def recv_nick_change(self, data=None):
        data = data.split(" ")
        i, name = int(data[0]), ' '.join(data[1:])
        if i == self.my_index:
            self.main.player_name = name
        try:
            name = int(name)
        except ValueError:
            pass
        if not (isinstance(self.players[i][0], int) is isinstance(name, int) is False):
            self.ready_up(str(i)+" 0")
        self.players[i][0] = name
        self.redraw_players()

    def recv_kick_player(self, data=None):
        kickme = int(data[0])
        if kickme == self.my_index:  # D:
            self.main.client = None
            self.main.change_screen("main")
            return
        self.players[kickme][0] = OPEN
        self.players[kickme][2] = False
        self.redraw_players()

    def recv_start_game(self, players):
        #print "game starting!!"
        seed, _, players = players.partition(" ")
        self.main.rand.seed(int(seed))
        players = players.split("\t")
        self.main.reset_screen("game", players, False)
        self.main.reset_screen("shop")
        self.main.change_screen("game")

    def notify_key(self, inkey):
        if inkey.key == pygame.K_BACKSPACE:
            self.text_input = self.text_input[:-1]
        elif inkey.key == pygame.K_TAB:
            try:    # tab complete
                mname = self.text_input.split(' ')[-1].lower()
                if mname == "":  # don't tab complete on nothing
                    return
                matches = []    # people whose names we've matched
                for i, (name, _, _) in enumerate(self.players):
                    if not isinstance(name, int):   # don't check slots that aren't players
                        if mname == name[:len(mname)].lower():  # if the first part of their name is what you've typed
                            matches += [name]       # they're a match
                if len(matches) == 1:
                    self.text_input = self.text_input[:-len(mname)]+matches[0]
                elif len(matches) > 1:
                    def get_most_letters():
                        text = ""
                        for x in xrange(len(mname), 22):
                            letter = None
                            for i in matches:
                                if letter is None:
                                    letter = i[x:x+1]
                                    if letter == "":
                                        return text
                                    continue
                                if i[x:x+1] != letter:
                                    return text
                            text += letter
                    self.text_input += get_most_letters()
            except IndexError:
                pass
        elif inkey.key == pygame.K_RETURN or inkey.key == pygame.K_KP_ENTER:
            self.message()  # send my current message
        elif inkey.unicode and self.font.size(self.text_input+inkey.unicode)[0] <= self.textbox.get_width()-10 and len(self.text_input) < 250:
            self.text_input += inkey.unicode    # send the unicode character you pressed
        else:
            return  # if none of these things happened, no need to redraw
        self.textbox.fill((0, 0, 0, 64))
        txt = self.font.render(self.text_input, True, COLORS["white"])
        self.textbox.blit(txt, (5, 5))