class Friends: state = NORMAL decal_y = 0 fr_demands = [] invs = [] def __init__(self, dim, pos, client): self.dim = dim self.pos = (pos[0], pos[1] + DIM_TY ) # update pos to don't care about 'add friend' button self.client = client self.usernames = [] self.obj_friends = [] self.DIM_FR = (dim[0], DIM_TY) self.cadre = Cadre((dim[0], dim[1] - DIM_TY), C.WHITE, (pos[0], pos[1] + DIM_TY)) # state normal self.button_add = Button(DIM_BADD, C.LIGHT_BLUE, (pos[0] + dim[0] - MARGE, pos[1]), 'Add friend', font=Font.f30) # state add fr POS_TEXT = (self.pos[0] + E(20), self.pos[1] + 2 * E(20)) self.text_add = TextBox(DIM_LTB, C.WHITE, POS_TEXT, 'Send demand to someone', font=Font.f30) self.textin_add = TextBox(DIM_STB, C.WHITE, (POS_TEXT[0], POS_TEXT[1] + E(100)), 'Enter username:'******'Done', font=Font.f30) self.button_cancel = Button( DIM_B, C.LIGHT_BLUE, (self.pos[0] + E(20), self.pos[1] + self.dim[1] - E(140)), 'Cancel', font=Font.f30) # state fail self.text_fail = TextBox(DIM_LTB, C.WHITE, POS_TEXT, 'Invalid username', font=Font.f50, TEXT_COLOR=C.RED) def add_friend(self, username, state): i = len(self.obj_friends) new_friend = Friend(self.DIM_FR, (self.pos[0], self.pos[1] + i * E(60)), username, state) self.obj_friends.append(new_friend) def check_connected(self): # check for connected/disconnected friends for username, state in self.client.friends.items(): if username in self.usernames: index = self.usernames.index(username) self.obj_friends[index].state = state else: self.usernames.append(username) self.add_friend(username, state) # get potential new friends demands new_friend_demands = self.client.get_demand_fr() for fr_d in new_friend_demands: current_fr_d = FriendDemand(self.dim[0], (self.pos[0], self.decal_y * E(60) + self.pos[1] + self.dim[1] - E(60)), fr_d) self.decal_y += 1 self.fr_demands.append(current_fr_d) # if a friend deleted you, reset friend if self.client.get_del_friend(): self.obj_friends = [] self.usernames = [] # get potential invitation from friends for username in self.client.get_invs(): new_inv = Invitation(self.dim[0], (self.pos[0], self.decal_y * E(60) + self.pos[1] + self.dim[1] - E(60)), username) self.decal_y += 1 self.invs.append(new_inv) def react_events(self, events, pressed): self.check_connected() if self.state == NORMAL: self.react_events_normal(events, pressed) elif self.state == ADD_FR: self.react_events_addfr(events, pressed) elif self.state == FAIL: self.react_events_fail(events, pressed) def react_events_normal(self, events, pressed): self.react_events_frd(events, pressed) self.react_events_invs(events, pressed) if self.button_add.pushed(events): self.state = ADD_FR for friend in self.obj_friends: if friend.button_delete.pushed(events): self.del_friend(friend) if friend.button_invite.pushed(events): if friend.state == 'conn': self.client.invite_friend(friend.username) def react_events_addfr(self, events, pressed): self.input_add.run(events, pressed) if self.button_cancel.pushed(events): self.state = NORMAL self.input_add.text = '' if self.button_done.pushed(events): username = self.input_add.text self.client.demand_friend(username) if self.client.is_dfr_valid != None: # receive a response if self.client.is_dfr_valid: self.state = NORMAL else: self.state = FAIL self.client.is_dfr_valid = None def react_events_frd(self, events, pressed): for frd in self.fr_demands: if frd.button_yes.pushed(events): self.client.return_friend_demand(frd.username, True) self.fr_demands.remove(frd) self.decal_y -= 1 if frd.button_no.pushed(events): self.client.return_friend_demand(frd.username, False) self.fr_demands.remove(frd) self.decal_y -= 1 def react_events_invs(self, events, pressed): for inv in self.invs: if inv.button_yes.pushed(events): self.client.return_inv_fr(inv.username) self.invs.remove(inv) self.decal_y -= 1 if inv.button_no.pushed(events): self.invs.remove(inv) self.decal_y -= 1 def react_events_fail(self, events, pressed): if self.button_done.pushed(events): self.state = NORMAL self.input_add.text = '' def del_friend(self, friend): self.obj_friends = [] self.usernames = [] self.client.del_friend(friend.username) def reset(self): self.usernames = [] self.obj_friends = [] self.fr_demands = [] def display(self): self.cadre.display() if self.state == NORMAL: self.display_normal() elif self.state == ADD_FR: self.display_addfr() elif self.state == FAIL: self.display_fail() def display_normal(self): self.button_add.display() for friend in self.obj_friends: friend.display() for frd in self.fr_demands: frd.display() for inv in self.invs: inv.display() def display_addfr(self): self.text_add.display() self.textin_add.display() self.input_add.display() self.button_done.display() self.button_cancel.display() def display_fail(self): self.button_done.display() self.text_fail.display() def get_obj_friend(self, username): for obj in self.obj_friends: if obj.username == username: return obj
class Chat: msgs = [] MAX_MSG = 8 def __init__(self, dim, pos, client): self.pos = pos self.text_box = TextBox((dim[0], dim[1] - E(80)), C.WHITE, pos, marge=True, centered=False, font=Font.f30) self.input_text = InputText((dim[0] - E(120), E(80)), (pos[0], pos[1] + dim[1] - E(80)), C.WHITE, font=Font.f30) self.button_send = Button( DIM_B, C.LIGHT_BLUE, (pos[0] + dim[0] - E(120), pos[1] + dim[1] - E(80)), 'Send', font=Font.f30) self.client = client def activate(self): self.client_thread = Thread(target=self.client.loop_msg) self.client_thread.start() def reset(self): self.msgs = [] def display(self): self.text_box.display() self.input_text.display() self.button_send.display() def add_msg(self, username, msg): if len(self.msgs) == self.MAX_MSG: self.msgs.pop(0) new_msg = f'{username}: {msg}' self.msgs.append(new_msg) text = ['\n' for i in range(self.MAX_MSG - 1)] text.insert(0, self.msgs[0]) for i in range(len(self.msgs) - 1): text[i + 1] += self.msgs[i + 1] new_text = cumsum(text, '') self.text_box.set_text(new_text) def react_events(self, events, pressed): self.input_text.run(events, pressed) if self.button_send.pushed(events): msg = self.input_text.text self.input_text.text = '' self.client.send_chat_msg(msg) self.add_msg(self.client.username, msg) for content in self.client.chat_msgs: self.add_msg(content[0], content[1]) self.client.chat_msgs = []
class Menu: play_pushed = False def __init__(self, client): self.client = client self.state = 'main' # state main self.title_main = TextBox(DIM_TITLE, C.WHITE, POS_TITLE,'Title', font=Font.f100) self.button_login = Button(DIM_MAIN_B, C.LIGHT_BLUE, POS_BLOG,'Log in') self.button_signup = Button(DIM_MAIN_B, C.LIGHT_BLUE, POS_BSIGN,'Sign up') # state login self.title_login = TextBox(DIM_TITLE, C.WHITE, POS_TITLE,'Log in', font=Font.f100) self.text_logusername = TextBox(DIM_TEXTBL,C.WHITE, (X_POS_TEXTBL, Y_POS_TEXTBL), 'Username:'******'Password:'******'Done', font=Font.f30) self.button_back = Button(DIM_NB, C.LIGHT_BLUE, POS_BBACK,'Back', font=Font.f30) # state signup self.title_signup = TextBox(DIM_TITLE, C.WHITE, POS_TITLE,'Sign up', font=Font.f100) # state fail log self.text_faillog = TextBox(DIM_FAILT, C.WHITE, (X_POS_TEXTBL2, Y_POS_FAILT), 'Invalid username or password', font=Font.f25, TEXT_COLOR=C.RED) # state fail sign self.text_failsign = TextBox(DIM_FAILT, C.WHITE, (X_POS_TEXTBL2, Y_POS_FAILT), 'Username already taken', font=Font.f25, TEXT_COLOR=C.RED) # state logged self.title_logged = TextBox(DIM_TITLE, C.WHITE, POS_TITLE,'Welcome', font=Font.f100) self.text_username = TextBox(DIM_LOGINP, C.WHITE, (LMARGE, LMARGE),'',marge=True) self.button_play = Button(DIM_MAIN_B, C.LIGHT_BLUE, POS_BPLAY, 'Play') self.chat_logged = Chat(DIM_CHAT, (MARGE,dim.y-DIM_CHAT[1]-MARGE), self.client) self.friends = Friends(DIM_FR, (dim.x-DIM_FR[0]-MARGE, E(250)), self.client) self.button_disconn = Button(DIM_LI_MAIN_B, C.LIGHT_BLUE, (LMARGE, MARGE+DIM_LOGINP[1]) ,'Disconnect',font=Font.f30) # state env self.title_env = TextBox(DIM_TITLE, C.WHITE, POS_TITLE,'Env', font=Font.f100) self.text_wating = TextBox(DIM_TWAIT,C.WHITE, POS_TWAIT, 'Waiting for the other players...', font=Font.f30) self.button_exit = Button(DIM_BEXIT, C.LIGHT_BLUE, POS_BEXIT, 'Exit', font=Font.f30) self.teams = Teams self.teams.init(POS_TEAMS,DIM_TEAMS, client) def display_main(self): self.title_main.display() self.button_login.display() self.button_signup.display() def display_login(self): self.title_login.display() self.text_logusername.display() self.text_password.display() self.input_username.display() self.input_password.display() self.button_back.display() self.button_done.display() def display_signup(self): self.title_signup.display() self.text_logusername.display() self.text_password.display() self.input_username.display() self.input_password.display() self.button_back.display() self.button_done.display() def display_logged(self): self.title_logged.display() self.text_username.display() self.button_disconn.display() self.button_play.display() self.chat_logged.display() self.friends.display() def display_env(self): self.title_env.display() self.text_username.display() if not self.play_pushed: self.button_play.display() else: self.text_wating.display() self.button_disconn.display() self.button_exit.display() self.chat_logged.display() self.friends.display() self.teams.display() def display_faillog(self): self.display_login() self.text_faillog.display() def display_failsign(self): self.display_signup() self.text_failsign.display() def react_events_main(self, events, pressed): if self.button_login.pushed(events): self.state = 'login' elif self.button_signup.pushed(events): self.state = 'signup' def react_events_login(self, events, pressed): self.input_username.run(events, pressed) self.input_password.run(events, pressed) if self.button_back.pushed(events): self.state = 'main' if self.button_done.pushed(events): username = self.input_username.text password = self.input_password.text if self.client.log(username, password): self.state = 'logged' self.text_username.set_text(username) self.teams.set_username(username) self.chat_logged.activate() else: self.state = 'fail log' def react_events_signup(self, events, pressed): self.input_username.run(events, pressed) self.input_password.run(events, pressed) if self.button_back.pushed(events): self.state = 'main' if self.button_done.pushed(events): username = self.input_username.text password = self.input_password.text if self.client == 1: self.state = 'logged' else: if self.client.sign_up(username, password): self.state = 'logged' self.text_username.set_text(username) self.teams.set_username(username) self.chat_logged.activate() else: self.state = 'fail sign' def react_events_logged(self, events, pressed): self.chat_logged.react_events(events, pressed) if self.button_play.pushed(events): print('play') if self.button_disconn.pushed(events): self.disconn() self.friends.react_events(events, pressed) # check for env if self.client.in_env: self.teams.set_players() # must have receive players connected from server (env) self.state = 'env' def react_events_env(self, events, pressed): self.chat_logged.react_events(events, pressed) self.teams.react_events(events, pressed) if self.button_disconn.pushed(events): self.disconn() self.friends.react_events(events, pressed) if not self.play_pushed: if self.button_play.pushed(events): self.client.env_play() self.play_pushed = True if self.button_exit.pushed(events): self.client.quit_game_or_env() if self.client.in_game_session: start_game(self.client) self.state = 'in game' def disconn(self): self.client.disconn() self.state = 'main' self.input_password.text = '' self.input_username.text = '' self.chat_logged.reset() self.friends.reset() def run(self, events, pressed): if self.state == 'in game': if not self.client.in_game_session: if self.client.in_env: self.state = 'env' else: self.state = 'logged' run_game(pressed, events) elif self.state == 'main': self.display_main() self.react_events_main(events, pressed) elif self.state == 'login': self.display_login() self.react_events_login(events, pressed) elif self.state == 'signup': self.react_events_signup(events, pressed) self.display_signup() elif self.state == 'logged': self.display_logged() self.react_events_logged(events, pressed) elif self.state == 'env': self.display_env() self.react_events_env(events, pressed) if not self.client.in_env: self.state = 'logged' elif self.state == 'fail log': self.display_faillog() self.react_events_login(events, pressed) elif self.state == 'fail sign': self.display_failsign() self.react_events_signup(events, pressed)