437 lines
17 KiB
Python
437 lines
17 KiB
Python
import sys
|
|
import time
|
|
|
|
import pygame
|
|
|
|
from .screen import Screen
|
|
from .text import Text, Title
|
|
|
|
SCREEN_BG_COLOR = (50, 50, 50)
|
|
|
|
MOB_ASSETS = {
|
|
'Yanaar': 'assets/orc.png',
|
|
'Ulnarain': 'assets/orc2.jpg',
|
|
'Skroll': 'assets/potato_man.jpg',
|
|
}
|
|
|
|
PLAYER_ASSET = 'assets/succube.png'
|
|
|
|
|
|
class PygameUi:
|
|
|
|
def __init__(self):
|
|
self.screen = Screen()
|
|
self.show_title()
|
|
|
|
def show_title(self):
|
|
title = Title().set_position(center=self.screen.rect.center)
|
|
space = Text('press space').set_position(midtop=title.rect.midbottom)
|
|
|
|
loop_start = time.time()
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key == pygame.K_SPACE:
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
|
|
loop_time = time.time() - loop_start
|
|
if loop_time % 2.0 > 1.0:
|
|
space.show(self.screen.surface)
|
|
|
|
self.screen.refresh()
|
|
|
|
def empty_room(self):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('Room empty', font_size=48).set_position(center=inner_box.center)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def meet_mob(self, mob):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('Mob in the room', font_size=48).set_position(midtop=inner_box.midtop)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
spec_margin = 16
|
|
spec_box = pygame.Rect(
|
|
inner_box.left,
|
|
title.rect.bottom + spec_margin,
|
|
inner_box.width,
|
|
instructions.rect.top - title.rect.bottom - (spec_margin * 2)
|
|
)
|
|
|
|
img = pygame.image.load(MOB_ASSETS[mob.name])
|
|
img_rect = img.get_rect().fit(pygame.Rect(0, 0, spec_box.height, spec_box.height))
|
|
img = pygame.transform.smoothscale(img, img_rect.size)
|
|
img_rect = img.get_rect(midleft=spec_box.midleft)
|
|
|
|
props_box = pygame.Rect(
|
|
img_rect.right,
|
|
spec_box.top,
|
|
spec_box.width - img_rect.width,
|
|
spec_box.height,
|
|
)
|
|
|
|
mob_name = Text(mob.name, font_size=36)
|
|
mob_name = mob_name.set_position(midtop=props_box.midtop)
|
|
|
|
mob_pv = Text(f"PV: {mob.current_pv}/{mob.max_pv}")
|
|
mob_pv = mob_pv.set_position(top=mob_name.rect.bottom + 36, left=props_box.left + 16)
|
|
|
|
mob_strength = Text(f"Force: {mob.strength}")
|
|
mob_strength = mob_strength.set_position(top=mob_pv.rect.bottom + 24, left=props_box.left + 16)
|
|
|
|
mob_protection = Text(f"Protection: {mob.protection}")
|
|
mob_protection = mob_protection.set_position(top=mob_strength.rect.bottom + 24,
|
|
left=props_box.left + 16)
|
|
|
|
mob_speed = Text(f"Vitesse: {mob.speed}")
|
|
mob_speed = mob_speed.set_position(top=mob_protection.rect.bottom + 24, left=props_box.left + 16)
|
|
|
|
texts = [
|
|
title,
|
|
mob_name,
|
|
mob_pv,
|
|
mob_strength,
|
|
mob_protection,
|
|
mob_speed,
|
|
instructions,
|
|
]
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
self.screen.surface.blit(img, img_rect)
|
|
for text in texts:
|
|
text.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def player_dead(self):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('You are dead', font_size=48).set_position(center=inner_box.center)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def mob_dead(self, mob):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('You win', font_size=48).set_position(center=inner_box.center)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def run_away(self):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('You are running away', font_size=48).set_position(center=inner_box.center)
|
|
|
|
for _ in range(60): # 60 tick at 60fps => loop for 1sec
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def leave(self, player):
|
|
title = Text(f'Goodbye {player.name}', font_size=48).set_position(center=self.screen.surface.get_rect().center)
|
|
for _ in range(60): # 60 tick at 60fps => loop for 1sec
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def select_player(self, player):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('Player selection', font_size=48).set_position(midtop=inner_box.midtop)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
spec_margin = 16
|
|
spec_box = pygame.Rect(
|
|
inner_box.left,
|
|
title.rect.bottom + spec_margin,
|
|
inner_box.width,
|
|
instructions.rect.top - title.rect.bottom - (spec_margin * 2)
|
|
)
|
|
|
|
img = pygame.image.load(PLAYER_ASSET)
|
|
img_rect = img.get_rect().fit(pygame.Rect(0, 0, spec_box.height, spec_box.height))
|
|
img = pygame.transform.smoothscale(img, img_rect.size)
|
|
img_rect = img.get_rect(midleft=spec_box.midleft)
|
|
|
|
props_box = pygame.Rect(
|
|
img_rect.right,
|
|
spec_box.top,
|
|
spec_box.width - img_rect.width,
|
|
spec_box.height,
|
|
)
|
|
|
|
player_name = Text(player.name, font_size=36)
|
|
player_name = player_name.set_position(midtop=props_box.midtop)
|
|
|
|
player_pv = Text(f"PV: {player.current_pv}/{player.max_pv}")
|
|
player_pv = player_pv.set_position(top=player_name.rect.bottom + 36, left=props_box.left + 16)
|
|
|
|
player_strength = Text(f"Force: {player.strength}")
|
|
player_strength = player_strength.set_position(top=player_pv.rect.bottom + 24, left=props_box.left + 16)
|
|
|
|
player_protection = Text(f"Protection: {player.protection}")
|
|
player_protection = player_protection.set_position(
|
|
top=player_strength.rect.bottom + 24, left=props_box.left + 16)
|
|
|
|
player_speed = Text(f"Vitesse: {player.speed}")
|
|
player_speed = player_speed.set_position(top=player_protection.rect.bottom + 24, left=props_box.left + 16)
|
|
|
|
texts = [
|
|
title,
|
|
player_name,
|
|
player_pv,
|
|
player_strength,
|
|
player_protection,
|
|
player_speed,
|
|
instructions,
|
|
]
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
self.screen.surface.blit(img, img_rect)
|
|
for text in texts:
|
|
text.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def entering_room(self, room_name):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text(f'Room {room_name + 1}', font_size=48).set_position(center=inner_box.center)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def last_room(self):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('End of level', font_size=48).set_position(center=inner_box.center)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def entering_donjon(self, level):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text(f'Level 1 - {len(level.rooms)} rooms', font_size=48).set_position(center=inner_box.center)
|
|
|
|
instructions = Text('Press enter to continue', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
loop = True
|
|
while loop:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
loop = False
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def action_menu(self, actions_autorisees):
|
|
texts = [Text(action.libelle) for n, action in enumerate(actions_autorisees)]
|
|
arrow = Text('> ')
|
|
action_index = 0
|
|
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('Select action', font_size=48).set_position(midtop=inner_box.midtop)
|
|
|
|
instructions = Text('Press enter to continue; Press up or down to move arrow', font_size=24)
|
|
instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)
|
|
|
|
action_box = pygame.Rect(inner_box.left + 64, title.rect.bottom + 64, inner_box.width, inner_box.height)
|
|
last_bottom = action_box.top
|
|
for text in texts:
|
|
text.set_position(left=action_box.left, top=last_bottom)
|
|
last_bottom = text.rect.bottom + 24
|
|
|
|
while True:
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
|
|
return actions_autorisees[action_index]
|
|
elif event.key == pygame.K_DOWN:
|
|
action_index = min(action_index + 1, len(actions_autorisees) - 1)
|
|
elif event.key == pygame.K_UP:
|
|
action_index = max(action_index - 1, 0)
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
for text in texts:
|
|
text.show(self.screen.surface)
|
|
arrow.set_position(midright=texts[action_index].rect.midleft).show(self.screen.surface)
|
|
instructions.show(self.screen.surface)
|
|
self.screen.refresh()
|
|
|
|
def fight_pvs(self, player, mob, pvs):
|
|
margin = 16
|
|
inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))
|
|
|
|
title = Text('Fight', font_size=48).set_position(midtop=inner_box.midtop)
|
|
|
|
player_img = pygame.image.load(PLAYER_ASSET)
|
|
player_img_rect = player_img.get_rect().fit(pygame.Rect(0, 0, 128, 128))
|
|
player_img = pygame.transform.smoothscale(player_img, player_img_rect.size)
|
|
player_img_rect = player_img.get_rect(left=inner_box.left + 48, centery=inner_box.centery)
|
|
|
|
mob_img = pygame.image.load(MOB_ASSETS[mob.name])
|
|
mob_img_rect = mob_img.get_rect().fit(pygame.Rect(0, 0, 128, 128))
|
|
mob_img = pygame.transform.smoothscale(mob_img, mob_img_rect.size)
|
|
mob_img_rect = mob_img.get_rect(right=inner_box.right - 48, centery=inner_box.centery)
|
|
|
|
init_fight = [{
|
|
'player': player.max_pv,
|
|
'mob': mob.max_pv,
|
|
}]
|
|
|
|
all_pvs = init_fight + pvs
|
|
|
|
for pv in all_pvs:
|
|
for _ in range(60): # 60 tick at 60fps => loop for 1sec
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
sys.exit()
|
|
|
|
self.screen.surface.fill(SCREEN_BG_COLOR)
|
|
title.show(self.screen.surface)
|
|
self.screen.surface.blit(player_img, player_img_rect)
|
|
self.screen.surface.blit(mob_img, mob_img_rect)
|
|
|
|
(Text(f"{pv['player']}/{player.max_pv}", font_size=36)
|
|
.set_position(midtop=player_img_rect.midbottom)
|
|
.show(self.screen.surface))
|
|
(Text(f"{pv['mob']}/{mob.max_pv}", font_size=36)
|
|
.set_position(midtop=mob_img_rect.midbottom)
|
|
.show(self.screen.surface))
|
|
|
|
self.screen.refresh()
|