|
- from __future__ import annotations
-
- import sys
- from datetime import datetime
- from enum import Enum, auto
- from typing import Callable, TypedDict
-
- import cv2
- import pygame
- from cv2 import VideoCapture
- from pygame import Surface
- from pygame.font import Font
- from pygame.mixer import Sound
- from pygame.time import Clock
-
- pygame.init ()
-
- FPS = 30
-
- SYSTEM_FONT = pygame.font.SysFont ('notosanscjkjp', 24, bold = True)
- USER_FONT = pygame.font.SysFont ('notosanscjkjp', 32, italic = True)
- DEERJIKA_FONT = pygame.font.SysFont ('07nikumarufont', 50)
-
- def main (
- ) -> None:
- game = Game ()
- bg = Bg (game)
- deerjika = Deerjika (game, DeerjikaPattern.RELAXED,
- x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120)
- CurrentTime (game, SYSTEM_FONT)
- Sound ('assets/bgm.mp3').play (loops = -1)
- while True:
- for event in pygame.event.get ():
- if event.type == pygame.QUIT:
- pygame.quit ()
- sys.exit ()
- game.redraw ()
-
-
- class DeerjikaPattern (Enum):
- NORMAL = auto ()
- RELAXED = auto ()
- SLEEPING = auto ()
-
-
- class Direction (Enum):
- LEFT = auto ()
- RIGHT = auto ()
-
-
- class Game:
- clock: Clock
- frame: int
- redrawers: list[Redrawer]
- screen: Surface
-
- def __init__ (
- self,
- ):
- self.screen = pygame.display.set_mode ((CWindow.WIDTH, CWindow.HEIGHT))
- self.clock = Clock ()
- self.frame = 0
- self.redrawers = []
-
- def redraw (
- self,
- ) -> None:
- for redrawer in sorted (self.redrawers, key = lambda x: x['layer']):
- if redrawer['obj'].enabled:
- redrawer['obj'].redraw ()
- pygame.display.update ()
- self.clock.tick (FPS)
-
-
- class GameObject:
- frame: int
- game: Game
- width: int
- height: int
- x: float
- y: float
- vx: float = 0
- vy: float = 0
- ax: float = 0
- ay: float = 0
- arg: float = 0
- enabled: bool = True
-
- def __init__ (
- self,
- game: Game,
- layer: int | None = None,
- enabled: bool = True,
- x: float = 0,
- y: float = 0,
- ):
- self.game = game
- self.enabled = enabled
- self.frame = 0
- if layer is None:
- if self.game.redrawers:
- layer = max (r['layer'] for r in self.game.redrawers) + 10
- else:
- layer = 0
- self.game.redrawers.append ({ 'layer': layer, 'obj': self })
- self.x = x
- self.y = y
-
- def redraw (
- self,
- ) -> None:
- self.x += self.vx
- self.y += self.vy
- self.vx += self.ax
- self.vy += self.ay
- self.frame += 1
-
-
- class Bg (GameObject):
- surface: Surface
-
- def __init__ (
- self,
- game: Game,
- ):
- super ().__init__ (game)
- self.surface = pygame.image.load ('assets/bg.jpg')
- self.surface = pygame.transform.scale (self.surface, (CWindow.WIDTH, CWindow.HEIGHT))
-
- def redraw (
- self,
- ) -> None:
- self.game.screen.blit (self.surface, (self.x, self.y))
- super ().redraw ()
-
-
- class Deerjika (GameObject):
- surfaces: list[Surface]
- size: int
- width: int
- height: int
- scale: float = .8
-
- def __init__ (
- self,
- game: Game,
- pattern: DeerjikaPattern = DeerjikaPattern.NORMAL,
- direction: Direction = Direction.LEFT,
- layer: int | None = None,
- x: float = 0,
- y: float = 0,
- ):
- super ().__init__ (game, layer, x = x, y = y)
- self.pattern = pattern
- self.direction = direction
- match pattern:
- case DeerjikaPattern.NORMAL:
- ...
- case DeerjikaPattern.RELAXED:
- match direction:
- case Direction.LEFT:
- self.width = 1280
- self.height = 720
- surface = pygame.image.load ('assets/deerjika_relax_left.png')
- self.surfaces = []
- for x in range (0, surface.get_width (), self.width):
- self.surfaces.append (
- surface.subsurface (x, 0, self.width, self.height))
- case Direction.RIGHT:
- ...
- self.size = len (self.surfaces)
-
- def redraw (
- self,
- ) -> None:
- surface = pygame.transform.scale (self.surfaces[self.frame % self.size],
- (self.width * self.scale, self.height * self.scale))
- self.game.screen.blit (surface, surface.get_rect (center = (self.x, self.y)))
- super ().redraw ()
-
-
- class CurrentTime (GameObject):
- font: Font
-
- def __init__ (
- self,
- game: Game,
- font: Font,
- ):
- super ().__init__ (game)
- self.font = font
-
- def redraw (
- self,
- ) -> None:
- for i in range (4):
- self.game.screen.blit (
- self.font.render (str (datetime.now ()), True, (0, 0, 0)),
- (i % 2, i // 2 * 2))
-
-
- class CWindow:
- WIDTH = 1024
- HEIGHT = 768
-
-
- class Redrawer (TypedDict):
- layer: int
- obj: GameObject
-
-
- def get_surfaces_from_video (
- video_path: str,
- ) -> list[Surface]:
- cap = VideoCapture (video_path)
- if not cap.isOpened ():
- return []
-
- fps = cap.get (cv2.CAP_PROP_FPS)
-
- surfaces: list[Surface] = []
- while cap.isOpened ():
- (ret, frame) = cap.read ()
- if not ret:
- break
- frame = cv2.cvtColor (frame, cv2.COLOR_BGR2RGB)
- frame_surface = pygame.surfarray.make_surface (frame)
- frame_surface = pygame.transform.rotate (frame_surface, -90)
- surfaces.append (pygame.transform.flip (frame_surface, True, False))
-
- cap.release ()
-
- return surfaces
-
-
- if __name__ == '__main__':
- main ()
|