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))
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 __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 __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)
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()
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()
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
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 __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)
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))