File: menu.py

package info (click to toggle)
whichwayisup 0.7.9-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,680 kB
  • ctags: 269
  • sloc: python: 2,370; makefile: 4; sh: 3
file content (135 lines) | stat: -rw-r--r-- 4,950 bytes parent folder | download | duplicates (9)
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