| @@ -8,11 +8,13 @@ from typing import Callable, TypedDict | |||
| import cv2 | |||
| import pygame | |||
| from cv2 import VideoCapture | |||
| from pygame import Surface | |||
| from pygame import Rect, Surface | |||
| from pygame.font import Font | |||
| from pygame.mixer import Sound | |||
| from pygame.time import Clock | |||
| from common_module import CommonModule | |||
| pygame.init () | |||
| FPS = 30 | |||
| @@ -27,6 +29,8 @@ def main ( | |||
| bg = Bg (game) | |||
| deerjika = Deerjika (game, DeerjikaPattern.RELAXED, | |||
| x = CWindow.WIDTH * 3 / 4, y = CWindow.HEIGHT - 120) | |||
| balloon = Balloon (game) | |||
| balloon.talk ('あいうえおかきくけこさしすせそたちつてとなにぬねの', 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやいゆえよらりるれろわゐうゑを') | |||
| CurrentTime (game, SYSTEM_FONT) | |||
| Sound ('assets/bgm.mp3').play (loops = -1) | |||
| while True: | |||
| @@ -197,11 +201,70 @@ class CurrentTime (GameObject): | |||
| self.game.screen.blit ( | |||
| self.font.render (str (datetime.now ()), True, (0, 0, 0)), | |||
| (i % 2, i // 2 * 2)) | |||
| super ().redraw () | |||
| class Balloon (GameObject): | |||
| query: str | |||
| answer: str | |||
| surface: Surface | |||
| query: str = '' | |||
| answer: str = '' | |||
| image_url: str | None = None | |||
| x_flip: bool = False | |||
| y_flip: bool = False | |||
| length: int = 300 | |||
| def __init__ ( | |||
| self, | |||
| game: Game, | |||
| x_flip: bool = False, | |||
| y_flip: bool = False, | |||
| ): | |||
| super ().__init__ (game, enabled = False) | |||
| self.x_flip = x_flip | |||
| self.y_flip = y_flip | |||
| self.surface = pygame.transform.scale (pygame.image.load ('assets/balloon.png'), | |||
| (CWindow.WIDTH, CWindow.HEIGHT / 2)) | |||
| self.surface = pygame.transform.flip (self.surface, self.x_flip, self.y_flip) | |||
| def redraw ( | |||
| self, | |||
| ) -> None: | |||
| if self.frame >= self.length: | |||
| self.enabled = False | |||
| return | |||
| query = self.query | |||
| if CommonModule.len_by_full (query) > 21: | |||
| query = CommonModule.mid_by_full (query, 0, 19.5) + '...' | |||
| answer = Surface ((800, ((CommonModule.len_by_full (self.answer) - 1) // 16 + 1) * 50), | |||
| pygame.SRCALPHA) | |||
| for i in range (int (CommonModule.len_by_full (self.answer) - 1) // 16 + 1): | |||
| answer.blit (DEERJIKA_FONT.render ( | |||
| CommonModule.mid_by_full (self.answer, 16 * i, 16), True, (192, 0, 0)), | |||
| (0, 50 * i)) | |||
| surface = self.surface.copy () | |||
| surface.blit (USER_FONT.render ('>' + query, True, (0, 0, 0)), (120, 70)) | |||
| y: int | |||
| if self.frame < 30: | |||
| y = 0 | |||
| elif self.frame >= self.length - 90: | |||
| y = answer.get_height () - 100 | |||
| else: | |||
| y = int ((answer.get_height () - 100) * (self.frame - 30) / (self.length - 120)) | |||
| surface.blit (answer, (100, 150), Rect (0, y, 800, 100)) | |||
| self.game.screen.blit (surface, (0, 0)) | |||
| super ().redraw () | |||
| def talk ( | |||
| self, | |||
| query: str, | |||
| answer: str, | |||
| image_url: str | None = None, | |||
| ) -> None: | |||
| self.query = query | |||
| self.answer = answer | |||
| self.image_url = image_url | |||
| self.frame = 0 | |||
| self.enabled = True | |||
| class CWindow: | |||