class Menu: """Is the deafult layout to be used for menus. Includes a back button and background image.""" def __init__(self, width, height, screen): """Makes display window for menus""" self._screen = screen # if user clicks back, will be true self._showPreviousScreen = False # make background color self._bgColor = (0, 0, 0) # Create back button self._backButton = Button( (width * 0.45, height * 0.4), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self._backButton.add_image("images\\back_button.png") def run_menu(self): """Runs menu screen""" while self._showPreviousScreen == False: # will be true when user clicks back # Draws background self._draw_background() # Draw buttons self._draw_buttons() # Make the most recently drawn __screen visible. pygame.display.flip() # Watch for keyboard and mouse events. self._check_for_events() def _draw_buttons(self): """Draws buttons for menu screen""" self._backButton.draw(self._screen) def _draw_background(self): """Draws menu screen background""" self._screen.fill(self._bgColor) def _check_for_events(self): """Checks for events from user""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # if back button is pressed if self._backButton.isButton_pressed_event_handler(event) == True: self._showPreviousScreen = True # will exit the while loop and return back to Main Menu.
def __init__(self, width, height, screen, settings): """Extends menu.py __init__""" # initiates super __init__ super().__init__(width, height, screen) # uses settings object created in alien_invasion.py self.__settings = settings # Create change screen resolution button self.__changeResButton = Button((width * 0.45, height * 0.6), (width / 9.6, height / 14.4)) self.__changeResButton.add_image("images\change_resolution_button.png")
def __init__(self, width, height, screen, menuManager): """Initializes main menu __screen elements""" pygame.init() # initialize objects self.__screen = screen self.__menuManag = menuManager # when user clicks a button, turns to True to switch to play screen self.__toPlayScreen = False # load the background image self.__bg = pygame.image.load("images\main_menu_background.png") # create main menu buttons # play button self.__playButton = Button( (width * 0.45, height * 0.4), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__playButton.add_image("images\play_button.png") # instructions button self.__instructionsButton = Button( (width * 0.45, height * 0.5), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__instructionsButton.add_image("images\instructions_button.png") # scoreboard button self.__scoreboardButton = Button( (width * 0.45, height * 0.6), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__scoreboardButton.add_image("images\scoreboard_button.png") # settings button self.__settingsButton = Button( (width * 0.45, height * 0.7), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__settingsButton.add_image("images\settings_button.png") # exit game button self.__exitGameButton = Button( (width * 0.45, height * 0.8), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__exitGameButton.add_image("images\exit_game_button.png")
def __init__(self): pygame.init() self.screen = pygame.display.set_mode((400, 440)) self.game = Game(0, 40, 400, 400) player_options = [ ('Human', 0), ('Minimax', 1), ('Learning', 2), ('Random', 3), ] self.player1_picker = Picker(5, 5, 150, 30, player_options, 1) self.player2_picker = Picker(160, 5, 150, 30, player_options) self.go_button = Button(320, 5, 50, 30, 'GO', self.on_go) self.clock = pygame.time.Clock()
def __init__(self, width, height, screen): """Draws the pause menu and displays it on game play screen, which is passed in from alien_invasion.py""" self.__screen = screen # will be true when pause menu is active. self.__pauseMenuActive = False # will be used to see if user clicked 'Main Menu' button. self.__toMainMenu = False size = (width * 0.18, height * 0.42 ) # will be same postition no matter screen resolution. position = ( width * 0.41, height * 0.30 ) # will allow menu to be centered, no matter the resolution. # create image self._image = pygame.Surface(size) # fill image with color - white self._image.fill((255, 255, 255)) # get image size and position self._rect = pygame.Rect(position, size) # draws rectangle with to main menu button and other buttons # creates Pause title on menu. self.__pausedTitle = Button( (width * 0.45, height * 0.32), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__pausedTitle.add_image("images\paused.png") # creates resume button self.__resumeButton = Button( (width * 0.45, height * 0.4), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__resumeButton.add_image("images\\resume_button.png") # creates main menu button self.__mainMenuButton = Button( (width * 0.45, height * 0.5), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__mainMenuButton.add_image("images\main_menu_button.png") # creates exit game button self.__exitGameButton = Button( (width * 0.45, height * 0.6), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__exitGameButton.add_image( "images\exit_game_button_pause_menu.png")
def __init__(self, width, height, screen): """Makes display window for menus""" self._screen = screen # if user clicks back, will be true self._showPreviousScreen = False # make background color self._bgColor = (0, 0, 0) # Create back button self._backButton = Button( (width * 0.45, height * 0.4), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self._backButton.add_image("images\\back_button.png")
def create_screen_attributes(self): """initializes all elements for this screen""" self.background = pygame.transform.scale( pygame.image.load('data/backgrounds/frontPage.jpg').convert(), self.size) self.button_widht = int(self.width / 4) self.button_height = int(self.width / 14) self.start_button = Button( self, pygame.Rect(self.width - self.button_widht * 5 / 2, self.height - self.button_height * 7 / 2, self.button_widht, self.button_height), "Start", 35, self.start) self.start_button.user_data = "start" self.buttons.append(self.start_button) self.info_button = Button( self, pygame.Rect(self.width - self.button_widht * 5 / 2, self.height - self.button_height * 2, self.button_widht, self.button_height), "Information", 35, self.info) self.info_button.user_data = "Info" self.buttons.append(self.info_button)
def create_screen_attributes(self): """creates all elements to display""" self.screennumber = 0 self.background = pygame.transform.scale( pygame.image.load( 'data/backgrounds/setup_background.png').convert(), self.size) self.draw_text() self.button_widht = int(self.width / 10) self.button_height = int(self.height / 14) self.Back_button = Button( self, pygame.Rect((self.width - self.button_widht) / 2, self.height - self.button_height * 3 / 2, self.button_widht, self.button_height), "Back", 35, self.back) self.Back_button.user_data = "Back" self.buttons.append(self.Back_button) self.Next_button = Button( self, pygame.Rect((self.width - self.button_widht) / 2 + self.button_widht * 3 / 2, self.height - self.button_height * 3 / 2, self.button_widht, self.button_height), "Next", 35, self.next) self.Next_button.user_data = "Next" self.Next_button.enabled = True self.buttons.append(self.Next_button) self.Previous_button = Button( self, pygame.Rect((self.width - self.button_widht) / 2 - self.button_widht * 3 / 2, self.height - self.button_height * 3 / 2, self.button_widht, self.button_height), "Previous", 23, self.previous) self.Previous_button.user_data = "Previous" self.Previous_button.enabled = False self.buttons.append(self.Previous_button)
def create_screen_attributes(self): """creates all elements to display""" self.background = pygame.transform.scale( pygame.image.load( 'data/backgrounds/setup_background.png').convert(), self.size) width = 20 height = 20 x_position = self.screen.get_rect().centerx - width // 2 y_position = 10 img = pygame.image.load('data/buttons/plus_button.png') img_h = pygame.image.load('data/buttons/plus_button_h.png') img_d = pygame.image.load('data/buttons/plus_button_d.png') self.add_button = Button(self, pygame.Rect(x_position, y_position, width, height), action=self.add_text_field, images=(img, img_h, img_d, img_d)) img = pygame.image.load('data/buttons/min_button.png') img_h = pygame.image.load('data/buttons/min_button_h.png') img_d = pygame.image.load('data/buttons/min_button_d.png') self.remove_button = Button(self, pygame.Rect(x_position, y_position + height, width, height), action=self.remove_text_field, images=(img, img_h, img_d, img_d)) width = 300 height = 100 x_position = self.screen.get_rect().right - (width + 50) y_position = self.screen.get_rect().bottom - (height + 50) continue_button = Button( self, pygame.Rect(x_position, y_position, width, height), "continue >", 30, self.next_screen) self.buttons.append(self.add_button) self.buttons.append(self.remove_button) self.buttons.append(continue_button) self.add_text_field()
class Screen: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((400, 440)) self.game = Game(0, 40, 400, 400) player_options = [ ('Human', 0), ('Minimax', 1), ('Learning', 2), ('Random', 3), ] self.player1_picker = Picker(5, 5, 150, 30, player_options, 1) self.player2_picker = Picker(160, 5, 150, 30, player_options) self.go_button = Button(320, 5, 50, 30, 'GO', self.on_go) self.clock = pygame.time.Clock() def start(self): self.running = True self.run() def stop(self): self.running = False def run(self): while self.running: self.clock.tick(30) events = pygame.event.get() for event in events: if event.type == pygame.QUIT: self.stop() self.player1_picker.update(events) self.player2_picker.update(events) self.go_button.update(events) self.game.update(events) self.player1_picker.render() self.player2_picker.render() self.go_button.render() self.game.render() self.screen.blit(self.game, (self.game.x, self.game.y)) self.screen.blit(self.player1_picker, (self.player1_picker.x, self.player1_picker.y)) self.screen.blit(self.player2_picker, (self.player2_picker.x, self.player2_picker.y)) self.screen.blit(self.go_button, (self.go_button.x, self.go_button.y)) pygame.display.flip() def on_go(self): player1 = self.get_player(self.player1_picker.get_value()) player2 = self.get_player(self.player2_picker.get_value()) self.game.start_new_game(player1, player2) def get_player(self, picker_value): if picker_value == 0: return 'human' if picker_value == 1: return MinimaxPlayer() if picker_value == 2: return LearningPlayer() if picker_value == 3: return RandomPlayer()
class GameOverMenu: def __init__(self, width, height, screen): """Draws the game over menu and displays it on game play screen, which is passed in from alien_invasion.py""" self.__screen = screen # will be true when game over menu is active. self.__gameOverMenuActive = False # will be used to see if user clicked 'Main Menu' button. self.__toMainMenu = False # will be used ot see if user clicked 'Play Again' button. self.__play_again = False size = (width*0.18, height*0.42) # will be same postition no matter screen resolution. position = (width*0.41, height*0.30) # will allow menu to be centered, no matter the resolution. # create image self._image = pygame.Surface(size) # fill image with color - white self._image.fill((255,255,255)) # get image size and position self._rect = pygame.Rect(position, size) # draws rectangle with to main menu button and other buttons # creates game over title self.__gameOverTitle = Button((width*0.45, height*0.32), (width/9.6, height/14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__gameOverTitle.add_image("images\game_over.png") # creates playAgain button self.__playAgainButton = Button((width*0.45, height*0.4), (width/9.6, height/14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__playAgainButton.add_image("images\play_again_button.png") # creates main menu button self.__mainMenuButton = Button((width*0.45, height*0.5), (width/9.6, height/14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__mainMenuButton.add_image("images\main_menu_button.png") # creates exit game button self.__exitGameButton = Button((width*0.45, height*0.6), (width/9.6, height/14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__exitGameButton.add_image("images\exit_game_button_pause_menu.png") def run_game_over_menu(self): """Runs the game over menu, till user wants to exit it or the game.""" self.__gameOverMenuActive = True while self.__gameOverMenuActive == True: # draw game over menu self.drawGameOverMenu() # Make the most recently drawn screen visible. pygame.display.flip() # watch for paused menu event self._check_for_events() def drawGameOverMenu(self): """Draws the game over menu and puts it on the game play screen and returns it.""" # draws game over menu self.__screen.blit(self._image, self._rect) # draws buttons self.drawButtons() def drawButtons(self): """Draws button for game over menu.""" self.__gameOverTitle.draw(self.__screen) self.__exitGameButton.draw(self.__screen) self.__playAgainButton.draw(self.__screen) self.__mainMenuButton.draw(self.__screen) def _check_for_events(self): """Checks for events in game over menu.""" for event in pygame.event.get(): # if user exits out of window during game over menu if event.type == pygame.QUIT: sys.exit() # if user presses escape to unpause if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.__gameOverMenuActive = False # if exit game button is pressed if self.__exitGameButton.isButton_pressed_event_handler(event) == True: sys.exit() # if playAgain button is pressed if self.__playAgainButton.isButton_pressed_event_handler(event) == True: self.__gameOverMenuActive = False self.__play_again = True # if main menu button is pressed if self.__mainMenuButton.isButton_pressed_event_handler(event) == True: self.__gameOverMenuActive = False self.__toMainMenu = True def get_to_main_menu(self): """Returns value of toMainMenu.""" return self.__toMainMenu def play_again(self): """Returns boolean value of play again.""" return self.__play_again
class Gameboard: """A visual interface for the player to interact with, should do everything the algorithm does for the bot player""" def __init__(self, screen): pygame.mixer.music.load('data/music/roman_backgroundmusic.ogg' ) #pygame mixer can only play .ogg files pygame.mixer.music.play(-1) pygame.mixer.music.set_volume(0.6) self.muted = False self.screen = screen self.size = self.width, self.height = screen.get_size() self.update_rects = [] self.buttons = [] self.countries = [] self.EDETING = False self.showing = False self.create_screen_attributes() self.victorySound = pygame.mixer.Sound('data/music/victory.ogg') def create_screen_attributes(self): """creates all elements to display""" self.define_screen_attribute_sizes(self.width, self.height) self.worldmap_surface = self.create_worldmap() self.action_panel_surace = self.create_action_panel() self.infoBar = InfoBar(self, self.info_bar_area) self.statusBar = StatusBar(self, self.status_bar_area) self.country_info = None def show(self): """lets this screen know it's currently showing. needs to be called when loading the screen""" self.showing = True self.update_screen() pygame.display.update() def hide(self): """lets this screen know it's no longer showing.""" self.showing = False def define_screen_attribute_sizes(self, screenwidth, screenheight): """defines the sizes of the different attributes on screen""" # wouter: define the area of the action panel width = screenwidth height = screenheight // 6 xPos = 0 yPos = screenheight - height self.action_panel_area = pygame.Rect(xPos, yPos, width, height) # wouter: define the area of the infoBar width = screenwidth // 2 height = 60 xPos = screenwidth // 2 - width // 2 yPos = -height self.info_bar_area = pygame.Rect(xPos, yPos, width, height) self.status_bar_area = pygame.Rect(screenwidth - 300, -440, 300, 500) # wouter: define the area of the worldmap width = screenwidth height = screenheight - self.action_panel_area.height xPos = 0 yPos = 0 self.worldmap_area = pygame.Rect(xPos, yPos, width, height) def update_screen(self, fetch_latest_data=False): """update_screen(self, fetch_latest_data=False). Updates all elements on the screen, this includes the buttons and countries, if True is given as an argument, the drawable counties will be updated to the latest status of the actual countries""" if self.showing: self.screen.blit(self.worldmap_surface, self.worldmap_area) self.screen.blit(self.action_panel_surace, self.action_panel_area) self.update_buttons() self.update_countries(fetch_latest_data) self.statusBar.update() if self.country_info is not None: self.country_info.update() self.infoBar.update() pygame.display.update(self.update_rects) if len(self.update_rects) > 16: print("WARNING: updating a lot of areas on the screen!") print("amount of update rects:", len(self.update_rects)) self.update_rects.clear() def create_worldmap(self): """returns a surface containing the worldmap and all it's countries with the size of worldmap_area""" background = pygame.image.load("data/maps/roman_map.png").convert() normal_width = 1920 normal_height = 720 background = pygame.transform.scale(background, self.worldmap_area.size) background_width = background.get_width() background_heigth = background.get_height() for i, continent in enumerate(worldstats.instance.continents): for j, country in enumerate(continent.countries): x_position = (self.worldmap_area.left + int( country.x)) * background_width // normal_width y_position = (self.worldmap_area.top + int( country.y)) * background_heigth // normal_height country_width = 50 countrie_height = 50 rect = pygame.Rect(x_position, y_position, country_width, countrie_height) drawable_country = DrawableCountry(self, rect, country, Color(0)) country.drawable = drawable_country self.countries.append(drawable_country) return background def create_action_panel(self): """returns a surface containing the action panel and creates the buttons in the action_panel""" action_panel = pygame.Surface(self.action_panel_area.size) background = pygame.transform.scale( pygame.image.load( 'data/backgrounds/roman_action_panel_background.png'), self.action_panel_area.size).convert() action_panel.blit(background, (0, 0)) # create buttons: self.mute_button = Button( self, pygame.Rect(self.width - 125, self.action_panel_area.top + 30, 100, 50), "Mute", 20, self.button_click_mute) decrease_button = Button( self, pygame.Rect(self.width - 125, self.action_panel_area.top + 80, 50, 25), "-", 20, self.decrease_volume) increase_button = Button( self, pygame.Rect(self.width - 75, self.action_panel_area.top + 80, 50, 25), "+", 20, self.increase_volume) button_width = self.width * 5 // 26 button_height = button_width // 150 * 60 self.finish_add_troops_button = Button( self, pygame.Rect(self.action_panel_area.left + 50, self.action_panel_area.top + 30, button_width, button_height), "finish adding troops", 18) self.finish_add_troops_button.user_data = "finish_add_troops" self.finish_add_troops_button.enabled = False self.finish_attack_button = Button( self, pygame.Rect(self.action_panel_area.left + 100 + button_width, self.action_panel_area.top + 30, button_width, button_height), "finish attack", 25) self.finish_attack_button.user_data = "finish_attack" self.finish_attack_button.enabled = False self.skip_move_button = Button( self, pygame.Rect(self.action_panel_area.left + 150 + 2 * button_width, self.action_panel_area.top + 30, button_width, button_height), "skip move", 25) self.skip_move_button.user_data = "skip_move" self.info_button = Button( self, pygame.Rect(self.action_panel_area.left + 200 + 3 * button_width, self.action_panel_area.top + 30, button_width, button_height), "Info", 25, self.info) self.info_button.user_data = "Info" img = pygame.image.load('data/buttons/bonus_info.png') img_hover = pygame.image.load('data/buttons/bonus_info_h.png') self.BonusInfo_button = Button(self, pygame.Rect(self.width - 260, self.height - 350, 200, 50), "", images=(img, img_hover, img_hover, img), action=self.bonusInfo) # add buttons to button-list: self.buttons.append(self.BonusInfo_button) self.buttons.append(decrease_button) self.buttons.append(increase_button) self.buttons.append(self.mute_button) self.buttons.append(self.skip_move_button) self.buttons.append(self.finish_add_troops_button) self.buttons.append(self.finish_attack_button) self.buttons.append(self.info_button) return action_panel def info(self): """switches the diplaying screen to INFOSCREEN""" GUI.screenManager.instance.setScreen( GUI.screenManager.instance.INFOSCREEN) while not self.showing: GUI.screenManager.instance.update_screen() def bonusInfo(self): """displays a popup with information about the continental bonus""" pos = (350, 350) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 popup_rect = pygame.Rect((left, top), pos) popup = Popup(self, popup_rect, Popup.CONINENT_BONUS_INFO, (0, 0)) popup.show() def update_buttons(self): """updates and draws all buttons, needs to be called in game loop""" for btn in self.buttons: btn.update() def update_countries(self, fetch_latest_data=False): """updates and draws all countries, needs to be called in game loop""" for country in self.countries: if fetch_latest_data: country.fetch_latest_data() country.update() def write_county_pos_to_file(self): """for repositioning the countries if needed""" with open('data/output_countries.csv', 'w') as csvfile: writer = csv.writer(csvfile, delimiter=';', quotechar='|', quoting=csv.QUOTE_MINIMAL) for d_country in self.countries: normal_width = 1920 normal_height = 720 x_position = (self.worldmap_area.left + int(d_country.rect.left) ) * normal_width // self.worldmap_area.width y_position = (self.worldmap_area.top + int(d_country.rect.top) ) * normal_height // self.worldmap_area.height writer.writerow([d_country, x_position, y_position]) def button_click_fullscreen(self): """toggles fullscreen mode""" if self.fullscreen is False: self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) self.fullscreen = True else: self.screen = pygame.display.set_mode(self.size) self.fullscreen = False self.update_screen(True) def button_click_mute(self): """play or mute the background music""" if self.muted is False: pygame.mixer.music.pause() self.muted = True self.statusBarChangeText("Music muted") self.mute_button.set_text("Music") else: pygame.mixer.music.unpause() self.muted = False self.statusBarChangeText("Music playing") self.mute_button.set_text("Mute") def decrease_volume(self): """decreases background music""" pygame.mixer.music.set_volume(pygame.mixer.music.get_volume() - 0.1) def increase_volume(self): """increases background music""" pygame.mixer.music.set_volume(pygame.mixer.music.get_volume() + 0.1) def addTroopsInput(self, player): """asks the given player to add troops. The amount of available troops should be set beforehand in Player. returns a dict with countries as keys and troops to add as values.""" self.skip_move_button.enabled = False self.finish_attack_button.enabled = False self.finish_add_troops_button.enabled = False finished = False countries = dict() troops_to_place = player.troopsToPlace self.infoBar.set_text(player.name + " | troops to place: " + str(troops_to_place)) self.infoBar.show() self.set_selectable(player, 0, highlight=True) while not finished: self.update_screen() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == Events.COUNTRY_CLICK and event.country.selectable is True: pos = (400, 200) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 popup_rect = pygame.Rect((left, top), pos) if not self.EDETING: popup = Popup( self, popup_rect, Popup.AMOUNT_INPUT, (event.country.amount_of_troops, event.country.country.amountOfTroops, troops_to_place + event.country.amount_of_troops)) popup.title_text = "adding troops" input = popup.show() else: input = None if input is not None: troops_to_place += (event.country.amount_of_troops - input) countries[ event.country. country] = input - event.country.country.amountOfTroops event.country.amount_of_troops = input self.infoBar.set_text(player.name + " | troops to place: " + str(troops_to_place)) if event.type == Events.BUTTON_CLICK and event.user_data == "finish_add_troops": finished = True if troops_to_place == 0: self.finish_add_troops_button.enabled = True self.infoBar.set_text(player.name + " | placed all troops") else: self.infoBar.set_text(player.name + " | troops to place: " + str(troops_to_place)) self.finish_add_troops_button.enabled = False for drawableCountry in self.countries: drawableCountry.selectable = False drawableCountry.highlighted = False self.infoBar.hide() #for printing on statusbar for country in countries.keys(): countryName = country.getName() troops = countries.get(country) playerName = player.getName() self.statusBarChangeText(playerName + " placed " + str(troops) + " troops on " + countryName) return countries def attackInput(self, player): """asks the given player for an attack, returns a TroopDisplacement with the amount of troops to attack with, the country to attack from and the county being attacked. Returns None if the Player does not wish to attack.""" self.infoBar.set_text(player.name + " | attacking") self.infoBar.show() self.skip_move_button.enabled = False self.finish_attack_button.enabled = True self.finish_add_troops_button.enabled = False attacker = None defender = None finished = False self.set_selectable(player, highlight=True) while not finished: self.update_screen(True) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == Events.COUNTRY_CLICK and event.country.selectable is True: if event.country.country.player is player: self.set_selectable(player, highlight=False) attacker = event.country attackable = worldstats.instance.getAttackableCountries( attacker.country) for country in attackable: country.drawable.selectable = True country.drawable.highlighted = True else: defender = event.country pos = (400, 200) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 popup_rect = pygame.Rect((left, top), pos) popup = Popup(self, popup_rect, Popup.AMOUNT_INPUT, (1, 1, attacker.amount_of_troops - 1)) popup.title_text = "attacking" input = popup.show() if input is not None: self.finish_attack_button.enabled = False tdp = TroopDisplacement(attacker.country, defender.country, input) print(tdp) return tdp if event.type == Events.BUTTON_CLICK and event.user_data == "finish_attack": self.infoBar.hide() self.finish_attack_button.enabled = False return None def moveInput(self, player): """asks the given player to move troops. Returns a TroopDisplacement with the amount of troops, the county from witch to move and county to witch to move to. Returns None if the player does not want to move troops.""" self.infoBar.set_text(player.name + " | moving troops") self.infoBar.show() self.skip_move_button.enabled = True self.finish_attack_button.enabled = False self.finish_add_troops_button.enabled = False from_country = None to_country = None finished = False self.set_selectable(player, must_have_group=True, highlight=True) while not finished: self.update_screen() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == Events.COUNTRY_CLICK and event.country.selectable is True: if from_country is None: from_country = event.country self.set_country_group_selectable(from_country.country, highlight=True) from_country.selectable = False else: to_country = event.country if event.type == Events.BUTTON_CLICK and event.user_data == "skip_move": self.infoBar.hide() self.skip_move_button.enabled = False return None if from_country is not None and to_country is not None: pos = (400, 200) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 popup_rect = pygame.Rect((left, top), pos) popup = Popup(self, popup_rect, Popup.AMOUNT_INPUT, (1, 1, from_country.amount_of_troops - 1)) popup.title_text = "moving troops" input = popup.show() if input is not None: self.statusBarChangeText(player.getName() + " moved " + str(input) + " troops from " + from_country.country.getName() + " to " + to_country.country.getName()) return TroopDisplacement(from_country.country, to_country.country, input) else: from_country = None to_country = None self.set_selectable(player, must_have_group=True) def set_selectable(self, player, minimum_troops=1, must_have_group=False, highlight=False): """Sets countries selectable of a given player. optional arguments: minimum_troops, must_have_group & highlight.""" for drawableCountry in self.countries: drawableCountry.selectable = False drawableCountry.highlighted = False if drawableCountry.amount_of_troops > minimum_troops and drawableCountry.country.player == player: if must_have_group: worldstats.instance.updateCountryGroups() if len( worldstats.instance.getGroup( drawableCountry.country)) > minimum_troops: drawableCountry.selectable = True drawableCountry.highlighted = highlight else: drawableCountry.selectable = True drawableCountry.highlighted = highlight def set_country_group_selectable(self, country, highlight=False): """Sets the group of countries surrounding the given county selectable.""" worldstats.instance.updateCountryGroups() for drawableCountry in self.countries: if drawableCountry.country in worldstats.instance.getGroup( country): drawableCountry.selectable = True drawableCountry.highlighted = highlight else: drawableCountry.selectable = False drawableCountry.highlighted = highlight def statusBarChangeText(self, text): """changes the text in the statusBar""" self.statusBar.set_text(text) def botAttackPopUp(self, bot, player, amount, countryTo): """Displays a popup to let the player know he's under attack.""" self.update_screen(True) pos = (500, 200) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 text = "OH SNAP, " + bot.name + " is attacking " + player.name + " in " + countryTo.name + " with " + str( amount) + " troops!" popup_rect = pygame.Rect((left, top), pos) popup = Popup(self, popup_rect, Popup.CONFIRMATION_INPUT_ATTACK, (text, "ok", "cancel")) popup.show() def worldDominancePopUp(self, player): """Displays a popup to let the player know the game is over.""" self.update_screen(True) pos = (500, 200) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 text = "CONGRATULATIONS!! " + player.name + " [" + player.color.name + "] has won the game!" popup_rect = pygame.Rect((left, top), pos) popup = Popup(self, popup_rect, Popup.CONFIRMATION_INPUT_ATTACK, (text, "ok", "cancel")) popup.show() def playerEliminated(self, player, rounds): """Displays a popup to let the player know another player is out of the game""" self.update_screen(True) pos = (500, 200) left = self.width // 2 - pos[0] // 2 top = self.height // 2 - pos[1] // 2 text = player.name + " [" + player.color.name + "] got eliminated after " + str( rounds) + " rounds!" popup_rect = pygame.Rect((left, top), pos) popup = Popup(self, popup_rect, Popup.CONFIRMATION_INPUT_ATTACK, (text, "ok", "cancel")) popup.show()
def create_action_panel(self): """returns a surface containing the action panel and creates the buttons in the action_panel""" action_panel = pygame.Surface(self.action_panel_area.size) background = pygame.transform.scale( pygame.image.load( 'data/backgrounds/roman_action_panel_background.png'), self.action_panel_area.size).convert() action_panel.blit(background, (0, 0)) # create buttons: self.mute_button = Button( self, pygame.Rect(self.width - 125, self.action_panel_area.top + 30, 100, 50), "Mute", 20, self.button_click_mute) decrease_button = Button( self, pygame.Rect(self.width - 125, self.action_panel_area.top + 80, 50, 25), "-", 20, self.decrease_volume) increase_button = Button( self, pygame.Rect(self.width - 75, self.action_panel_area.top + 80, 50, 25), "+", 20, self.increase_volume) button_width = self.width * 5 // 26 button_height = button_width // 150 * 60 self.finish_add_troops_button = Button( self, pygame.Rect(self.action_panel_area.left + 50, self.action_panel_area.top + 30, button_width, button_height), "finish adding troops", 18) self.finish_add_troops_button.user_data = "finish_add_troops" self.finish_add_troops_button.enabled = False self.finish_attack_button = Button( self, pygame.Rect(self.action_panel_area.left + 100 + button_width, self.action_panel_area.top + 30, button_width, button_height), "finish attack", 25) self.finish_attack_button.user_data = "finish_attack" self.finish_attack_button.enabled = False self.skip_move_button = Button( self, pygame.Rect(self.action_panel_area.left + 150 + 2 * button_width, self.action_panel_area.top + 30, button_width, button_height), "skip move", 25) self.skip_move_button.user_data = "skip_move" self.info_button = Button( self, pygame.Rect(self.action_panel_area.left + 200 + 3 * button_width, self.action_panel_area.top + 30, button_width, button_height), "Info", 25, self.info) self.info_button.user_data = "Info" img = pygame.image.load('data/buttons/bonus_info.png') img_hover = pygame.image.load('data/buttons/bonus_info_h.png') self.BonusInfo_button = Button(self, pygame.Rect(self.width - 260, self.height - 350, 200, 50), "", images=(img, img_hover, img_hover, img), action=self.bonusInfo) # add buttons to button-list: self.buttons.append(self.BonusInfo_button) self.buttons.append(decrease_button) self.buttons.append(increase_button) self.buttons.append(self.mute_button) self.buttons.append(self.skip_move_button) self.buttons.append(self.finish_add_troops_button) self.buttons.append(self.finish_attack_button) self.buttons.append(self.info_button) return action_panel
def show(self): """this will return the input from the user when the popup is closed *AMOUNT_INPUT: the input is 'None' when canceled or no input was given *CONFIRMATION_INPUT:the input is True when confirmed, False otherwize""" #Warning: messy code ahead width = self.rect.width height = self.rect.height left = self.rect.left right = self.rect.right top = self.rect.top self.showing = True self.background = pygame.transform.scale(self.background_image, self.rect.size) pygame.display.get_surface().blit(self.backdrop, (0, 0)) pygame.display.get_surface().blit(self.background, self.rect) pygame.display.flip() if self.type == Popup.AMOUNT_INPUT or self.type == Popup.AMOUNT_INPUT_NO_CANCEL: img = pygame.image.load('data/buttons/plus_button.png') img_h = pygame.image.load('data/buttons/plus_button_h.png') img_d = pygame.image.load('data/buttons/plus_button_d.png') self.up_button = Button(self.screen, pygame.Rect(right - 165, top + 30, 40, 40), images=(img, img_h, img_d, img_d)) self.up_button.user_data = "UP_AMOUNT" img = pygame.image.load('data/buttons/min_button.png') img_h = pygame.image.load('data/buttons/min_button_h.png') img_d = pygame.image.load('data/buttons/min_button_d.png') self.down_button = Button(self.screen, pygame.Rect(left + 125, top + 30, 40, 40), images=(img, img_h, img_d, img_d)) self.down_button.user_data = "DOWN_AMOUNT" self.buttons.append(self.up_button) self.buttons.append(self.down_button) if self.type == Popup.AMOUNT_INPUT_NO_CANCEL: ok_button = Button(self.screen, pygame.Rect(self.rect.centerx - 50, top + height - 80, 100, 50), "Ok", 20) self.buttons.append(ok_button) else: cancel_button = Button(self.screen, pygame.Rect(left + width - 130, top + height - 80, 100, 50), "Cancel", 16) cancel_button.user_data = "CANCEL" ok_button = Button(self.screen, pygame.Rect(left + 30, top + height - 80, 100, 50), "Ok", 16) self.buttons.append(cancel_button) self.buttons.append(ok_button) ok_button.user_data = "CONFIRM" elif self.type == Popup.CONINENT_BONUS_INFO: confirm_button = Button(self.screen, pygame.Rect(left + 130, top + height - 70, 100, 50), "Ok") confirm_button.user_data = "CONFIRM" self.buttons.append(confirm_button) elif self.type == Popup.CONFIRMATION_INPUT: confirm_button = Button(self.screen, pygame.Rect(left + 20, top + height - 70, 100, 50), self.param[1]) cancel_button = Button(self.screen, pygame.Rect(left + width - 120, top + height - 70, 100, 50), self.param[2]) confirm_button.user_data = "CONFIRM" cancel_button.user_data = "CANCEL" self.buttons.append(confirm_button) self.buttons.append(cancel_button) elif self.type == Popup.CONFIRMATION_INPUT_ATTACK: confirm_button = Button(self.screen, pygame.Rect(left + width // 2 - 50, top + height - 80, 100, 50), self.param[1]) confirm_button.user_data = "CONFIRM" self.buttons.append(confirm_button) while self.showing: self.update() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == Events.BUTTON_CLICK: if event.user_data == "CANCEL": self.close() return self.result(True) elif event.user_data == "CONFIRM": self.close() return self.result(False) elif event.user_data == "UP_AMOUNT": self.param[0] += 1 elif event.user_data == "DOWN_AMOUNT": self.param[0] -= 1 if event.type == pygame.KEYDOWN: buttons = {pygame.K_0: 0, pygame.K_KP0: 0, pygame.K_1: 1, pygame.K_KP1: 1, pygame.K_2: 2, pygame.K_KP2: 2, pygame.K_3: 3, pygame.K_KP3: 3, pygame.K_4: 4, pygame.K_KP4: 4, pygame.K_5: 5, pygame.K_KP5: 5, pygame.K_6: 6, pygame.K_KP6: 6, pygame.K_7: 7, pygame.K_KP7: 7, pygame.K_8: 8, pygame.K_KP8: 8, pygame.K_9: 9, pygame.K_KP9: 9, } if event.key == pygame.K_LEFT or event.key == pygame.K_DOWN: self.param[0] -= 1 if event.key == pygame.K_RIGHT or event.key == pygame.K_UP: self.param[0] += 1 if event.key in buttons.keys(): self.prev_keyboard_input = self.keyboard_input self.keyboard_input = int(str(self.keyboard_input) + str(buttons[event.key])) if event.key == pygame.K_BACKSPACE: self.prev_keyboard_input = self.keyboard_input self.keyboard_input = self.keyboard_input // 10 if event.key == pygame.K_RETURN or event.key == pygame.K_KP_ENTER: self.close() return self.result(False) if event.key == pygame.K_ESCAPE: self.close() return self.result(True) if self.type == Popup.AMOUNT_INPUT or self.type == Popup.AMOUNT_INPUT_NO_CANCEL: if self.prev_keyboard_input != self.keyboard_input: self.prev_keyboard_input = self.keyboard_input self.param[0] = self.keyboard_input if self.keyboard_input > self.param[2]: self.keyboard_input = self.param[2] if self.param[0] < self.param[1]: self.param[0] = self.param[1] elif self.param[0] > self.param[2]: self.param[0] = self.param[2]
class SettingsMenu(Menu): """Creates settings screen""" def __init__(self, width, height, screen, settings): """Extends menu.py __init__""" # initiates super __init__ super().__init__(width, height, screen) # uses settings object created in alien_invasion.py self.__settings = settings # Create change screen resolution button self.__changeResButton = Button((width * 0.45, height * 0.6), (width / 9.6, height / 14.4)) self.__changeResButton.add_image("images\change_resolution_button.png") def _draw_buttons(self): """Extends _draw_buttons from menu.py and adds resolution button.""" super()._draw_buttons() # draw change resolution button self.__changeResButton.draw(self._screen) def _check_for_events(self): """Overrides _check_for_events from menu.py and adds event for clicking resolution button.""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # if back button is pressed if self._backButton.isButton_pressed_event_handler(event) == True: self._showPreviousScreen = True # will exit the while loop and return back to Main Menu. # if change resolution is pressed if self.__changeResButton.isButton_pressed_event_handler( event) == True: self.changeScreenResolution( ) # will call method inside this object to change resolution. print(self.__settings.get_res_width()) print(self.__settings.get_res_height()) def changeScreenResolution(self): """Allows user to change the resolution. Calls settings methods. Needs more work done.""" # prompts user for reolution from console try: new_width = int(input("Enter new resolution width: ")) new_height = int(input("Enter new resolution height: ")) except: print( "Error collecting new resolution width and height from user. Res may not be an int." ) # display resolutions in console for confirmation print(f"width = {new_width}, height = {new_height}") # calls set resolution methods from settings object self.__settings.set_res_width(new_width) self.__settings.set_res_height(new_height) self.__screen = pygame.display.set_mode( (self.__settings.get_res_width(), self.__settings.get_res_height()) ) # may need to work with only one screen object for every menu and display.
class MainMenu: """Draws Main Menu and keeps user here until changing to a different window Will call Menu Manager display methods to display settings menu, instrucitons menu, and scoreboard menu. Once user clicks 'Back' button in these menus, they will resume here in the Main Menu.""" def __init__(self, width, height, screen, menuManager): """Initializes main menu __screen elements""" pygame.init() # initialize objects self.__screen = screen self.__menuManag = menuManager # when user clicks a button, turns to True to switch to play screen self.__toPlayScreen = False # load the background image self.__bg = pygame.image.load("images\main_menu_background.png") # create main menu buttons # play button self.__playButton = Button( (width * 0.45, height * 0.4), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__playButton.add_image("images\play_button.png") # instructions button self.__instructionsButton = Button( (width * 0.45, height * 0.5), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__instructionsButton.add_image("images\instructions_button.png") # scoreboard button self.__scoreboardButton = Button( (width * 0.45, height * 0.6), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__scoreboardButton.add_image("images\scoreboard_button.png") # settings button self.__settingsButton = Button( (width * 0.45, height * 0.7), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__settingsButton.add_image("images\settings_button.png") # exit game button self.__exitGameButton = Button( (width * 0.45, height * 0.8), (width / 9.6, height / 14.4)) # width/9.6 in 1920 = 200, height/14.4 in 1080p = 75 self.__exitGameButton.add_image("images\exit_game_button.png") def run_main_menu(self): """Start the main loop for main menu __screen.""" # stays in while loop till user clicks play while self.__toPlayScreen == False: #redraw the __screen during each pass through the loop # draws background image self.draw_background() # draws buttons self.draw_buttons() # Make the most recently drawn __screen visible. pygame.display.flip() # Watch for keyboard and mouse events. self._check_for_events() def draw_buttons(self): """Draws the main menu buttons""" self.__playButton.draw(self.__screen) self.__instructionsButton.draw(self.__screen) self.__scoreboardButton.draw(self.__screen) self.__settingsButton.draw(self.__screen) self.__exitGameButton.draw(self.__screen) def draw_background(self): """Draws the background image""" self.__screen.blit(self.__bg, (0, 0)) def getToPlayScreen(self): """Returns toPlayScreen value for confirmation user actually pressed the button. Prevents the game from 'accidently' proceeding to game play __screen if user has not actually clicked the Play button. Called in menu_manager.py and value is used in alien_invasion.py""" return self.__toPlayScreen def _check_for_events(self): """Checks for events from user""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # if play button is pressed if self.__playButton.isButton_pressed_event_handler(event) == True: self.__toPlayScreen = True # Exits loop # if instructions button is pressed if self.__instructionsButton.isButton_pressed_event_handler( event) == True: self.__menuManag.displayInstructionsMenu() # if settings button is pressed if self.__settingsButton.isButton_pressed_event_handler( event) == True: self.__menuManag.displaySettingsMenu() # if scoreboard button is pressed if self.__scoreboardButton.isButton_pressed_event_handler( event) == True: self.__menuManag.displayScoreboardMenu() # if exit game button is pressed if self.__exitGameButton.isButton_pressed_event_handler( event) == True: sys.exit()