Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 36 additions & 94 deletions intro_scene.py → intro_scenesunet.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@


class TypewriterText:
def __init__(self, full_text: str, font: pygame.font.Font, max_width: int, speed_frames: int):
def __init__(
self,
full_text: str,
font: pygame.font.Font,
max_width: int,
speed_frames: int,
sound: pygame.mixer.Sound | None = None,
):
self.full_text = full_text or ""
self.font = font
self.max_width = max_width
self.speed = max(1, speed_frames)
self.sound = sound

self.frame_counter = 0
self.done = (self.full_text == "")
Expand Down Expand Up @@ -51,10 +59,16 @@ def _wrap_text(self, text: str):
def update(self):
if self.done:
return

self.frame_counter += 1
if self.frame_counter >= self.speed:
self.frame_counter = 0
self.visible_chars += 1

if self.sound:
self.sound.stop()
self.sound.play()

if self.visible_chars >= self.total_chars:
self.visible_chars = self.total_chars
self.done = True
Expand Down Expand Up @@ -93,123 +107,48 @@ def draw(self, surface: pygame.Surface, box_rect: pygame.Rect):
def _load_and_fit_bg(path: Path) -> pygame.Surface:
img = pygame.image.load(str(path)).convert()
iw, ih = img.get_size()
scale = max(SCREEN_W / iw, SCREEN_H / ih) # cover
scale = max(SCREEN_W / iw, SCREEN_H / ih)
nw, nh = int(iw * scale), int(ih * scale)
img = pygame.transform.smoothscale(img, (nw, nh))
x = (nw - SCREEN_W) // 2
y = (nh - SCREEN_H) // 2
return img.subsurface(pygame.Rect(x, y, SCREEN_W, SCREEN_H)).copy()


class MenuScene:
"""
Meniu simplu: doar Play (mouse click). NIMIC pe tastatura.
"""
def __init__(self, manager, game_assets, hub_scene_ctor, intro_dir: Path):
self.manager = manager
self.game_assets = game_assets
self.hub_scene_ctor = hub_scene_ctor

self.intro_dir = Path(intro_dir)
pygame.font.init()
self.font = pygame.font.SysFont("monospace", 28, bold=True)
self.small = pygame.font.SysFont("monospace", 18)

# optional: background = frame5, daca exista
bg_path = self.intro_dir / "frame5.jpg"
try:
self.bg = _load_and_fit_bg(bg_path)
except Exception:
self.bg = pygame.Surface((SCREEN_W, SCREEN_H))
self.bg.fill((10, 10, 15))

# logo
logo_path = self.intro_dir / "logo.png"
try:
self.logo = pygame.image.load(str(logo_path)).convert_alpha()
except Exception:
self.logo = pygame.Surface((420, 220), pygame.SRCALPHA)
self.logo.fill((255, 255, 255, 60))

max_w = 520
lw, lh = self.logo.get_size()
if lw > max_w:
s = max_w / lw
self.logo = pygame.transform.smoothscale(self.logo, (int(lw * s), int(lh * s)))

label = self.font.render("Play", True, (255, 255, 255))
pad = 18
bw = label.get_width() + pad * 2
bh = label.get_height() + pad * 2
self.btn_label = label
self.btn_rect = pygame.Rect(0, 0, bw, bh)

def handle_event(self, event):
# STRICT mouse play
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
ipos = self.manager.window_to_internal(event.pos)
if ipos is None:
return
mx, my = ipos
if self.btn_rect.collidepoint(mx, my):
self.manager.start_game() # reset maps + go hub

def update(self, dt):
pass

def draw(self, surface):
surface.blit(self.bg, (0, 0))

# logo centered
lx = SCREEN_W // 2 - self.logo.get_width() // 2
ly = int(SCREEN_H * 0.55) - self.logo.get_height() // 2
surface.blit(self.logo, (lx, ly))

# button centered
self.btn_rect.centerx = SCREEN_W // 2
self.btn_rect.top = ly + self.logo.get_height() + 28

mx, my = self.manager.mouse_internal()
hovered = self.btn_rect.collidepoint(mx, my)
color = (150, 150, 150, 240) if hovered else (100, 100, 100, 220)

btn_s = pygame.Surface(self.btn_rect.size, pygame.SRCALPHA)
btn_s.fill(color)
btn_s.blit(self.btn_label, ((self.btn_rect.w - self.btn_label.get_width()) // 2,
(self.btn_rect.h - self.btn_label.get_height()) // 2))
surface.blit(btn_s, self.btn_rect)

hint = self.small.render("Click Play (mouse only)", True, (220, 220, 220))
surface.blit(hint, (SCREEN_W // 2 - hint.get_width() // 2, self.btn_rect.bottom + 12))


class IntroScene:
"""
Intro frames + typewriter.
La final -> trece automat la MenuScene.
"""
def __init__(self, manager, game_assets, hub_scene_ctor, intro_dir: Path):
self.manager = manager
self.game_assets = game_assets
self.hub_scene_ctor = hub_scene_ctor
self.intro_dir = Path(intro_dir)

pygame.font.init()
pygame.mixer.init()

self.font = pygame.font.SysFont("monospace", FONT_SIZE)
self.prompt_font = pygame.font.SysFont("monospace", 18)

self.type_sound = pygame.mixer.Sound("mixkit-hard-typewriter-click-1119.wav")
self.type_sound.set_volume(0.5)

self.script = [
("frame1.jpg", "The Dodo was always a suspicious bird, so the caveman wanted to follow it"),
("frame2.jpg", "Curious, he follows it inside..."),
("frame3.png", "Suddenly, everything begins to spin..."),
("frame4.jpg", "What is actually this Dodo..."),
("frame5.jpg", ""), # la final -> menu
("frame5.jpg", ""),
]

self.frames = []
for fname, text in self.script:
bg = _load_and_fit_bg(self.intro_dir / fname)
tw = TypewriterText(text, self.font, TEXT_BOX_W - TEXT_PADDING * 2, TYPING_SPEED_FRAMES)
tw = TypewriterText(
text,
self.font,
TEXT_BOX_W - TEXT_PADDING * 2,
TYPING_SPEED_FRAMES,
self.type_sound,
)
self.frames.append({"bg": bg, "tw": tw, "is_last": (fname == "frame5.jpg")})

self.index = 0
Expand All @@ -221,7 +160,6 @@ def handle_event(self, event):
cur = self._cur()
tw = cur["tw"]

# last frame: orice key/click -> menu
if cur["is_last"]:
if event.type in (pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN):
self.manager.go_menu()
Expand All @@ -242,7 +180,6 @@ def draw(self, surface):
surface.blit(cur["bg"], (0, 0))

if cur["is_last"]:
# hint
hint = self.prompt_font.render("[ Press any key to continue ]", True, (220, 220, 220))
surface.blit(hint, (SCREEN_W // 2 - hint.get_width() // 2, SCREEN_H - 60))
return
Expand All @@ -257,5 +194,10 @@ def draw(self, surface):

if cur["tw"].done and cur["tw"].full_text != "":
prompt = self.prompt_font.render("[ Press any key to continue ]", True, PROMPT_COLOR)
surface.blit(prompt, (TEXT_BOX_X + TEXT_BOX_W - prompt.get_width() - TEXT_PADDING,
TEXT_BOX_Y + TEXT_BOX_H - prompt.get_height() - 8))
surface.blit(
prompt,
(
TEXT_BOX_X + TEXT_BOX_W - prompt.get_width() - TEXT_PADDING,
TEXT_BOX_Y + TEXT_BOX_H - prompt.get_height() - 8,
),
)