1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# A generic, keyboard- or joystick-controlled menu class.
# Draws a list of strings on the screen, and the user can select one of them.
#
# Key configuration is hard-coded:
# Up/down keys or the main vertical axis on the joystick change the selection
# Return, Z, Space or joystick keys 1 or 2 make the selection.
# Esc quits the menu.
#
# To use the module, initialize it with the following parameters:
# screen - standard pygame surface the menu is drawn on
# menu_items - a list of strings in the menu
#
# Optional initialization parameters:
# bgscreen - the menu background covering the entire screen, a pygame surface
# heading_text - a heading for the menu
#
# If the bgscreen isn't specified, the class uses a black screen instead.
#
# After initialization, use the run function. If you want some of the items
# pre-selected, you can supply it with the index of the selection in the
# menu_items list
#
# The run() function returns the index of the selection OR constant MENU_QUIT,
# if the user presses Esc while in the menu.
#
# Menu placement on the screen is controlled by constants in the locals.py.
# The use of the module also requires play_sound from the sound module,
# Util class and render_text from the util module
# and the Variables class from the variables module.
import pygame
import os
from pygame.locals import *
from locals import *
import data
from util import Util, render_text
from variables import Variables
from sound import play_sound
class Menu:
def __init__(self, screen, menu_items, bgscreen = None, heading_text = None):
self.bgscreen = bgscreen
if self.bgscreen == None:
self.bgscreen = Util.blackscreen
self.screen = screen
self.menu_items = menu_items
self.heading_text = heading_text
return
def run(self, menu_choice = 0):
done = False
clock = pygame.time.Clock()
self.screen.blit(self.bgscreen, (0, 0)) #Renders the menu background, usually the faded out game display
#Or a black screen
#Menu loop
while not done:
# Pygame event and keyboard input processing
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
menu_choice = MENU_QUIT
done = True
elif (event.type == KEYDOWN and event.key == K_DOWN) or (event.type == JOYAXISMOTION and event.axis == 1 and event.value > 0.7):
if menu_choice + 1 < len(self.menu_items):
menu_choice += 1
play_sound("click")
elif (event.type == KEYDOWN and event.key == K_UP) or (event.type == JOYAXISMOTION and event.axis == 1 and event.value < -0.7):
if menu_choice > 0:
menu_choice -= 1
play_sound("click")
elif (event.type == KEYDOWN and (event.key == K_z or event.key == K_SPACE or event.key == K_RETURN)) or (event.type == JOYBUTTONDOWN and (event.button == 0 or event.button == 1)):
done = True
#Menu rendering
#Menu offset value centers the menu when the maximum amount of choices is not visible
if len(self.menu_items) < MENU_MAX_VISIBLE:
menu_offset = -(len(self.menu_items) - 5) * 10
else:
menu_offset = -(MENU_MAX_VISIBLE - 5) * 10
menu_bg = pygame.image.load(data.picpath("menu", "bg")).convert_alpha()
rect = menu_bg.get_rect()
rect.centerx = SCREEN_WIDTH / 2
rect.top = GUI_MENU_TOP
self.screen.blit(menu_bg, rect)
if self.heading_text != None:
menu_head = render_text(self.heading_text)
rect = menu_head.get_rect()
rect.centerx = SCREEN_WIDTH / 2
rect.top = GUI_MENU_TOP + 50 + menu_offset
self.screen.blit(menu_head, rect)
#If the menu choice is greater than the second last menu item on screen,
#the menu must be scrolled:
if menu_choice > (MENU_MAX_VISIBLE - 1):
current_menu_index = menu_choice - MENU_MAX_VISIBLE
if (menu_choice + 1) < len(self.menu_items):
current_menu_index += 1
else:
current_menu_index = 0
menu_visible = 0
while (not (menu_visible > MENU_MAX_VISIBLE or (current_menu_index) == len(self.menu_items))):
m = self.menu_items[current_menu_index]
if (menu_choice == current_menu_index):
menu_image = render_text(m, COLOR_GUI_HILIGHT, COLOR_GUI_DARK)
else:
menu_image = render_text(m, COLOR_GUI)
rect = menu_image.get_rect()
rect.centerx = SCREEN_WIDTH / 2
rect.top = GUI_MENU_TOP + 60 + (menu_visible + 1) * 20 + menu_offset
self.screen.blit(menu_image, rect)
current_menu_index += 1
menu_visible += 1
#Display, clock
pygame.display.flip()
clock.tick(FPS)
return menu_choice
|