Commit dd51820c authored by captnfab's avatar captnfab 🦃
Browse files

Continue code cleaning

- document GuiOptions (WIP #38)
- prepare for sprites (WIP #37)
- cleaner options logic
parent 13ad0fd2
......@@ -40,11 +40,10 @@ class GuiMenu:
self.rnd = rnd
# Precompute background
splashscreen = pygame.image.load("gfx/splashscreen.jpg").convert()
self.bg = pygame.image.load("gfx/splashscreen.jpg").convert()
title_font = pygame.font.Font(FONT, 20)
title = title_font.render(_("Pirate Battleship"), 1, WHITE)
splashscreen.blit(title, (30, 100))
self.bg = splashscreen
self.bg.blit(title, (30, 100))
# Precompute menu
self.menu_entries = []
......@@ -69,13 +68,13 @@ class GuiMenu:
menu_topleft = (int(WIDTH*0.7), int(HEIGHT*0.7))
## Font face/size for menu entries
self.menu_font = pygame.font.Font(FONT, 20)
menu_font = pygame.font.Font(FONT, 20)
## Generate menu's sprites
self.menu_sprites = []
for n,(text, key, stage) in enumerate(self.menu_entries):
active = self.menu_font.render(text, 1, ORANGE)
inactive = self.menu_font.render(text, 1, WHITE)
active = menu_font.render(text, 1, ORANGE)
inactive = menu_font.render(text, 1, WHITE)
rect = active.get_rect()
rect.topleft = menu_topleft
......@@ -116,7 +115,8 @@ class GuiMenu:
elif event.type == pygame.KEYDOWN:
for n, (text,key,stage) in enumerate(self.menu_entries):
if event.unicode == key:
rnd.state.options['choice'] = key
rnd.state.options['choice'] = stage
rnd.state.options['needs_redraw'] = True
if event.key == pygame.K_DOWN:
self.menu_index += 1
self.menu_index %= len(self.menu_entries)
......@@ -126,8 +126,9 @@ class GuiMenu:
self.menu_index %= len(self.menu_entries)
rnd.state.options['needs_redraw'] = True
elif event.key == pygame.K_RETURN:
rnd.state.options['choice'] = self.menu_entries[self.menu_index][2]
rnd.state.options['needs_redraw'] = True
if self.menu_index is not None:
rnd.state.options['choice'] = self.menu_entries[self.menu_index][2]
rnd.state.options['needs_redraw'] = True
elif event.type == pygame.MOUSEMOTION:
for n, ((rect,inactive,active), (text,key,stage)) in enumerate(zip(self.menu_sprites, self.menu_entries)):
if rect.collidepoint(event.pos):
......@@ -136,33 +137,39 @@ class GuiMenu:
class GuiOptions:
def __init__(self, rnd):
options = pygame.image.load("gfx/options.jpg").convert()
self.rnd = rnd
self.bg = options
# Precompute background
self.bg = pygame.image.load("gfx/options.jpg").convert()
menu_font = pygame.font.Font(FONT, 20)
self.menu_items = []
self.menu_items.append((
menu_font.render(_("Menu"), 1, ORANGE),
menu_font.render(_("Menu"), 1, WHITE),
'm',
Stage.MENU,
# Precompute menu
self.menu_entries = []
self.menu_entries.append((
_("Menu"), 'm', Stage.MENU,
))
self.menu_center = (WIDTH//2, int(HEIGHT*0.9))
self.menu_rects = []
x,y = self.menu_center
for (n,(active, inactive, key, stage)) in enumerate(self.menu_items):
## Reference point for menu
menu_center = (WIDTH//2, int(HEIGHT*0.9))
## Font face/size for menu entries
menu_font = pygame.font.Font(FONT, 20)
self.menu_sprites = []
for n,(text, key, stage) in enumerate(self.menu_entries):
active = menu_font.render(text, 1, ORANGE)
inactive = menu_font.render(text, 1, WHITE)
rect = active.get_rect()
rect.center = (x,y)
self.menu_rects.append(rect)
y += rect.height + 10
x += 20
rect.center = menu_center
font_options = pygame.font.Font(FONT, 20)
font_items = pygame.font.Font(FONT, 18)
self.menu_sprites.append((rect, inactive, active))
options_options = [
# Initially don't select any entry
self.menu_index = None
# Precompute options menu
self.options_entries = [
(_("Difficulty"), [
(_("Cheat"), AI.CHEAT),
(_("Easy"), AI.EASY),
......@@ -204,148 +211,170 @@ class GuiOptions:
"fullscreen"),
]
self.options_config = {}
self.options_menu = [{
"active": font_options.render(label, 1, ORANGE),
"inactive": font_options.render(label, 1, WHITE),
"option": name,
"items": [{
"active": font_options.render(ilabel, 1, ORANGE),
"inactive": font_options.render(ilabel, 1, WHITE),
"active_u": font_options.render(ilabel, 1, LIGHTGRAY),
"inactive_u": font_options.render(ilabel, 1, MEDIUMGRAY),
"value": ivalue,
}
for (ilabel, ivalue) in items ],
}
for (label, items, name) in options_options ]
## Reference point for options
options_topleft = (WIDTH//4, 150)
## Font face/size for options menu entries
options_font = pygame.font.Font(FONT, 20)
items_font = pygame.font.Font(FONT, 18)
options_topleft = (WIDTH//4, 150)
## Generate options menu's sprites
self.options_sprites = []
self.items_sprites = []
max_option_width = 0
for n,(o_text,items,o_name) in enumerate(self.options_entries):
active = options_font.render(o_text, 1, ORANGE)
inactive = options_font.render(o_text, 1, WHITE)
x,y = options_topleft
for option in self.options_menu:
r = option['active'].get_rect()
r.topleft = (x, y)
option['rect'] = r
(ix, iy) = (WIDTH//2, r.bottom)
for item in option['items']:
ir = item['active'].get_rect()
ir.bottomleft = (ix + 30, iy)
item['rect'] = ir
(ix, iy) = ir.bottomright
x,y = r.bottomleft
y+=60
o_rect = active.get_rect()
o_rect.topleft = options_topleft
o_rect.top += 60*n
self.reset()
self.options_sprites.append((o_rect, inactive, active))
self.items_sprites.append([])
max_option_width = max(max_option_width, o_rect.width)
for n,(o_text,items,o_name) in enumerate(self.options_entries):
i_topleft = self.options_sprites[n][0].topleft
i_topleft = i_topleft[0] + max_option_width, i_topleft[1]
### Generate option's items sprites
for m,(i_text, i_val) in enumerate(items):
a_active = items_font.render(i_text, 1, ORANGE)
a_inactive = items_font.render(i_text, 1, MEDIUMGRAY)
i_active = items_font.render(i_text, 1, LIGHTGRAY)
i_inactive = items_font.render(i_text, 1, DARKGRAY)
i_rect = a_active.get_rect()
i_rect.topleft = i_topleft[0]+30, i_topleft[1]
i_topleft = i_rect.topright
self.items_sprites[n].append((i_rect, a_active, a_inactive, i_active, i_inactive))
# Initially select first entry
self.options_index = 0
# Initially select configured entry
self.items_index = []
for n,option in enumerate(self.options_entries):
for m,item in enumerate(option[1]):
## If item's value is the current configured option
if item[1] == rnd.params.get(option[2], None):
self.items_index.append(m)
break
## fallback on first value
if len(self.items_index)<=n:
self.items_index.append(0)
def reset(self):
self.menu_index = 0
self.options_active = 0
self.options_config.clear()
self.options_config_loaded = False
def draw(self, s):
update_rects = []
# Draw background
s.blit(self.bg, (0, 0))
for n, option in enumerate(self.options_menu):
if n == self.options_active:
s.blit(option['active'], option['rect'])
# Draw options menu
for n, ((o_rect,inactive,active),items) in enumerate(zip(self.options_sprites,self.items_sprites)):
## Update option entry
if n == self.options_index:
s.blit(active, o_rect)
else:
s.blit(option['inactive'], option['rect'])
update_rects.append(option['rect'])
for m, item in enumerate(option['items']):
if n == self.options_active:
if self.options_config.get(n, None) == m:
s.blit(item['active'], item['rect'])
s.blit(inactive, o_rect)
update_rects.append(o_rect)
for m, (r, a_a, a_i, i_a, i_i) in enumerate(items):
if n == self.options_index:
if self.items_index[n] == m:
s.blit(a_a, r)
else:
s.blit(item['inactive'], item['rect'])
update_rects.append(item['rect'])
s.blit(a_i, r)
else:
if self.options_config.get(n, None) == m:
s.blit(item['active_u'], item['rect'])
if self.items_index[n] == m:
s.blit(i_a, r)
else:
s.blit(item['inactive_u'], item['rect'])
update_rects.append(item['rect'])
s.blit(i_i, r)
update_rects.append(r)
for (n, (active, inactive, key, stage)) in enumerate(self.menu_items):
# Draw menu
for (n, (rect, inactive, active)) in enumerate(self.menu_sprites):
if self.menu_index == n:
item = active
else:
item = inactive
s.blit(item, self.menu_rects[n])
update_rects.append(self.menu_rects[n])
s.blit(item, rect)
update_rects.append(rect)
return update_rects
def update(self, rnd, params):
# Load config options
if not self.options_config_loaded:
for n,option in enumerate(self.options_menu):
for m,item in enumerate(option['items']):
if item['value'] == params.get(option['option'], None):
self.options_config[n] = m
# fallback on first value
if self.options_config.get(n, None) is None:
self.options_config[n] = self.options_menu[n]['items'][0]['value']
self.options_config_loaded = True
# Apply config options
for (n, v) in self.options_config.items():
name = self.options_menu[n]['option']
params[name] = self.options_menu[n]['items'][v]['value']
for (n, v) in enumerate(self.items_index):
name = self.options_entries[n][2]
rnd.params[name] = self.options_entries[n][1][v][1]
def input(self, event, rnd):
if event.type == pygame.MOUSEBUTTONDOWN:
for (n, (active, inactive, key, stage)) in enumerate(self.menu_items):
if self.menu_rects[n].collidepoint(event.pos):
for n, ((rect,inactive,active), (text,key,stage)) in enumerate(zip(self.menu_sprites, self.menu_entries)):
if rect.collidepoint(event.pos):
rnd.state.options['choice'] = stage
for n, option in enumerate(self.options_menu):
for m, item in enumerate(option['items']):
if item['rect'].collidepoint(event.pos):
self.options_config[n] = m
for n,items_sprites in enumerate(self.items_sprites):
for m,(i_r, iaa, iai, iia, iii) in enumerate(items_sprites):
if i_r.collidepoint(event.pos):
self.items_index[n] = m
rnd.state.options['needs_redraw'] = True
return
elif event.type == pygame.KEYDOWN:
for (active, inactive, k, stage) in self.menu_items:
if event.unicode == k:
for n, (text,key,stage) in enumerate(self.menu_entries):
if event.unicode == key:
rnd.state.options['choice'] = stage
rnd.state.options['needs_redraw'] = True
if event.key in [pygame.K_RETURN, pygame.K_ESCAPE]:
rnd.state.options['choice'] = self.menu_items[self.menu_index][3]
elif event.key in [pygame.K_DOWN, pygame.K_UP, pygame.K_LEFT, pygame.K_RIGHT] and self.options_active is not None and self.options_config.get(self.options_active, None) is not None:
if self.menu_index is not None:
rnd.state.options['choice'] = self.menu_entries[self.menu_index][2]
rnd.state.options['needs_redraw'] = True
elif event.key in [pygame.K_DOWN, pygame.K_UP, pygame.K_LEFT, pygame.K_RIGHT]:
rnd.state.options['needs_redraw'] = True
if self.options_active is None:
self.options_active = 0
elif event.key == pygame.K_DOWN:
self.options_active += 1
self.options_active %= len(self.options_menu)
if event.key == pygame.K_DOWN:
if self.menu_index is not None:
self.menu_index += 1
elif self.options_index is not None:
self.options_index += 1
elif event.key == pygame.K_UP:
self.options_active += len(self.options_menu) - 1
self.options_active %= len(self.options_menu)
elif event.key == pygame.K_LEFT:
self.options_config[self.options_active] += len(self.options_menu[self.options_active]['items']) - 1
self.options_config[self.options_active] %= len(self.options_menu[self.options_active]['items'])
elif event.key == pygame.K_RIGHT:
self.options_config[self.options_active] += 1
self.options_config[self.options_active] %= len(self.options_menu[self.options_active]['items'])
if self.menu_index is not None:
self.menu_index -= 1
elif self.options_index is not None:
self.options_index -= 1
elif event.key == pygame.K_LEFT and self.options_index is not None:
self.items_index[self.options_index] += len(self.options_entries[self.options_index][1]) - 1
self.items_index[self.options_index] %= len(self.options_entries[self.options_index][1])
elif event.key == pygame.K_RIGHT and self.options_index is not None:
self.items_index[self.options_index] += 1
self.items_index[self.options_index] %= len(self.options_entries[self.options_index][1])
if self.menu_index == len(self.menu_entries):
self.menu_index = None
self.options_index = 0
elif self.menu_index == -1:
self.menu_index = None
self.options_index = len(self.options_entries)-1
elif self.options_index in [-1, len(self.options_entries)]:
self.options_index = None
self.menu_index = 0
elif event.type == pygame.MOUSEMOTION:
for i, r in enumerate(self.menu_rects):
if r.collidepoint(event.pos):
self.menu_index = i
for n, ((rect,inactive,active), (text,key,stage)) in enumerate(zip(self.menu_sprites, self.menu_entries)):
if rect.collidepoint(event.pos):
self.menu_index = n
self.options_index = None
rnd.state.options['needs_redraw'] = True
for n, option in enumerate(self.options_menu):
if option['rect'].collidepoint(event.pos):
self.options_active = n
for n, (o_r, oa, oi) in enumerate(self.options_sprites):
if r.collidepoint(event.pos):
self.options_index = n
self.menu_index = None
rnd.state.options['needs_redraw'] = True
return
for m, item in enumerate(option['items']):
if item['rect'].collidepoint(event.pos):
self.options_active = n
for m, (i_r, iaa, iai, iia, iii) in enumerate(self.items_sprites[n]):
if i_r.collidepoint(event.pos):
self.options_index = n
self.menu_index = None
rnd.state.options['needs_redraw'] = True
return
class GuiCredits:
def __init__(self, rnd):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment