| @@ -108,16 +108,19 @@ class Game: | |||||
| ゲーム・クラス | ゲーム・クラス | ||||
| Attributes: | Attributes: | ||||
| clock (Clock): Clock オブゼクト | |||||
| frame (int): フレーム・カウンタ | |||||
| redrawers (list[Redrawer]): 再描画するクラスのリスト | |||||
| screen (Surface): 基底スクリーン | |||||
| sky (Sky): 天体情報 | |||||
| clock (Clock): Clock オブゼクト | |||||
| frame (int): フレーム・カウンタ | |||||
| last_answered_at (datetime): 最後に回答した時刻 | |||||
| now (datetime): 基準日時 | |||||
| redrawers (list[Redrawer]): 再描画するクラスのリスト | |||||
| screen (Surface): 基底スクリーン | |||||
| sky (Sky): 天体情報 | |||||
| """ | """ | ||||
| clock: Clock | clock: Clock | ||||
| frame: int | frame: int | ||||
| last_answered_at: datetime | last_answered_at: datetime | ||||
| now: datetime | |||||
| redrawers: list[Redrawer] | redrawers: list[Redrawer] | ||||
| screen: Surface | screen: Surface | ||||
| sky: Sky | sky: Sky | ||||
| @@ -134,6 +137,8 @@ class Game: | |||||
| def redraw ( | def redraw ( | ||||
| self, | self, | ||||
| ) -> None: | ) -> None: | ||||
| self.now = datetime.now () | |||||
| self.sky.observer.date = self.now - timedelta (hours = 9) | |||||
| for redrawer in sorted (self.redrawers, key = lambda x: x['layer']): | for redrawer in sorted (self.redrawers, key = lambda x: x['layer']): | ||||
| if redrawer['obj'].enabled: | if redrawer['obj'].enabled: | ||||
| redrawer['obj'].redraw () | redrawer['obj'].redraw () | ||||
| @@ -339,7 +344,7 @@ class CurrentTime (GameObject): | |||||
| ) -> None: | ) -> None: | ||||
| for i in range (4): | for i in range (4): | ||||
| self.game.screen.blit ( | self.game.screen.blit ( | ||||
| self.font.render (str (datetime.now ()), True, (0, 0, 0)), | |||||
| self.font.render (str (self.game.now), True, (0, 0, 0)), | |||||
| (i % 2, i // 2 * 2)) | (i % 2, i // 2 * 2)) | ||||
| super ().redraw () | super ().redraw () | ||||
| @@ -384,7 +389,7 @@ class Balloon (GameObject): | |||||
| ) -> None: | ) -> None: | ||||
| if self.frame >= self.length: | if self.frame >= self.length: | ||||
| self.enabled = False | self.enabled = False | ||||
| self.game.last_answered_at = datetime.now () | |||||
| self.game.last_answered_at = self.game.now | |||||
| return | return | ||||
| query = self.query | query = self.query | ||||
| if CommonModule.len_by_full (query) > 21: | if CommonModule.len_by_full (query) > 21: | ||||
| @@ -451,7 +456,6 @@ class KitaSun (GameObject): | |||||
| surface = pygame.transform.rotate (self.surface, -(90 + math.degrees (self.arg))) | surface = pygame.transform.rotate (self.surface, -(90 + math.degrees (self.arg))) | ||||
| self.game.screen.blit (surface, surface.get_rect (center = (self.x, self.y))) | self.game.screen.blit (surface, surface.get_rect (center = (self.x, self.y))) | ||||
| super ().redraw () | super ().redraw () | ||||
| self.game.sky.observer.date = datetime.now () - timedelta (hours = 9) | |||||
| self.sun.compute (self.game.sky.observer) | self.sun.compute (self.game.sky.observer) | ||||
| self.alt = self.sun.alt | self.alt = self.sun.alt | ||||
| self.az = self.sun.az | self.az = self.sun.az | ||||
| @@ -488,11 +492,14 @@ class Jojoko (GameObject): | |||||
| Attributes: | Attributes: | ||||
| base (Surface): 満月ヨヨコ Surface | base (Surface): 満月ヨヨコ Surface | ||||
| moon (Moon): ephem の月オブゼクト | moon (Moon): ephem の月オブゼクト | ||||
| surface (Surface): 缺けたヨヨコ Surface | |||||
| surface (Surface): 缺けたヨヨコ | |||||
| """ | """ | ||||
| alt: float | |||||
| az: float | |||||
| base: Surface | base: Surface | ||||
| moon: Moon | moon: Moon | ||||
| surface: Surface | |||||
| def __init__ ( | def __init__ ( | ||||
| self, | self, | ||||
| @@ -500,25 +507,43 @@ class Jojoko (GameObject): | |||||
| ): | ): | ||||
| super ().__init__ (game) | super ().__init__ (game) | ||||
| self.base = pygame.transform.scale (pygame.image.load ('assets/moon.png'), (200, 200)) | self.base = pygame.transform.scale (pygame.image.load ('assets/moon.png'), (200, 200)) | ||||
| self.moon = Moon () | |||||
| self.surface = self._get_surface () | |||||
| def redraw ( | def redraw ( | ||||
| self, | self, | ||||
| ) -> None: | ) -> None: | ||||
| ... | |||||
| if self.frame % 300 == 0: | |||||
| self.surface = self._get_surface () | |||||
| surface = pygame.transform.rotate (self.surface, -(90 + math.degrees (self.arg))) | |||||
| surface.set_colorkey ((0, 255, 0)) | |||||
| self.game.screen.blit (surface, surface.get_rect (center = (self.x, self.y))) | |||||
| super ().redraw () | |||||
| self.moon.compute (self.game.sky.observer) | |||||
| self.alt = self.moon.alt | |||||
| self.az = self.moon.az | |||||
| if abs (self.new_arg - self.arg) > math.radians (15): | |||||
| self.arg = self.new_arg | |||||
| self.x = self.new_x | |||||
| self.y = self.new_y | |||||
| @property | @property | ||||
| def phase ( | def phase ( | ||||
| self, | self, | ||||
| ) -> float: | ) -> float: | ||||
| dt: datetime = ephem.localtime (ephem.previous_new_moon (self.game.sky.observer.date)) | dt: datetime = ephem.localtime (ephem.previous_new_moon (self.game.sky.observer.date)) | ||||
| return (datetime.now () - dt).total_seconds () / 60 / 60 / 24 | |||||
| return (self.game.now - dt).total_seconds () / 60 / 60 / 24 | |||||
| @property | |||||
| def surface ( | |||||
| def _get_surface ( | |||||
| self, | self, | ||||
| ) -> Surface: | ) -> Surface: | ||||
| """ | |||||
| ヨヨコを月齢に応じて缺かす. | |||||
| Returns: | |||||
| Surface: 缺けたヨヨコ | |||||
| """ | |||||
| jojoko = self.base.copy () | jojoko = self.base.copy () | ||||
| jojoko.set_colorkey ((0, 255, 0)) | |||||
| for i in range (200): | for i in range (200): | ||||
| if 1 <= self.phase < 15: | if 1 <= self.phase < 15: | ||||
| pygame.gfxdraw.bezier (jojoko, ((0, 100 + i), (100, 180 * self.phase / 7 - 80 + i), (200, 100 + i)), 3, (0, 255, 0)) | pygame.gfxdraw.bezier (jojoko, ((0, 100 + i), (100, 180 * self.phase / 7 - 80 + i), (200, 100 + i)), 3, (0, 255, 0)) | ||||
| @@ -530,6 +555,26 @@ class Jojoko (GameObject): | |||||
| jojoko.fill ((0, 255, 0)) | jojoko.fill ((0, 255, 0)) | ||||
| return jojoko | return jojoko | ||||
| @property | |||||
| def new_x ( | |||||
| self, | |||||
| ) -> float: | |||||
| return CWindow.WIDTH * (math.degrees (self.az) - 80) / 120 | |||||
| @property | |||||
| def new_y ( | |||||
| self, | |||||
| ) -> float: | |||||
| return ((CWindow.HEIGHT / 2) | |||||
| - ((CWindow.HEIGHT / 2 + 100) * math.sin (self.alt) | |||||
| / math.sin (math.radians (60)))) | |||||
| @property | |||||
| def new_arg ( | |||||
| self, | |||||
| ) -> float: | |||||
| return math.atan2 (self.new_y - self.y, self.new_x - self.x) | |||||
| class Sky: | class Sky: | ||||
| """ | """ | ||||