AI 移行 #38
|
変更前 幅: | 高さ: | サイズ: 57 KiB 変更後 幅: | 高さ: | サイズ: 57 KiB |
|
変更前 幅: | 高さ: | サイズ: 99 KiB 変更後 幅: | 高さ: | サイズ: 99 KiB |
|
変更前 幅: | 高さ: | サイズ: 53 KiB 変更後 幅: | 高さ: | サイズ: 53 KiB |
|
変更前 幅: | 高さ: | サイズ: 40 KiB 変更後 幅: | 高さ: | サイズ: 40 KiB |
@@ -1,52 +1,113 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import sys
|
||||
from enum import Enum, auto
|
||||
from typing import Callable, TypedDict
|
||||
|
||||
import cv2
|
||||
import pygame
|
||||
from cv2 import VideoCapture
|
||||
from pygame import Surface
|
||||
from pygame.time import Clock
|
||||
|
||||
|
||||
def main (
|
||||
) -> None:
|
||||
pygame.init ()
|
||||
game = Game ()
|
||||
deerjika = Deerjika (game, DeerjikaPattern.RELAXED)
|
||||
while True:
|
||||
deerjika = Deerjika (game)
|
||||
pass
|
||||
|
||||
|
||||
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 = pygame.time.Clock ()
|
||||
self.clock = Clock ()
|
||||
self.frame = 0
|
||||
|
||||
|
||||
class GameObject (metaclass = ABCMeta):
|
||||
def __init__ (
|
||||
self,
|
||||
game: Game,
|
||||
):
|
||||
self.game = game
|
||||
self.redrawer.append (self.redraw)
|
||||
|
||||
@abstractmethod
|
||||
def redraw (
|
||||
self,
|
||||
) -> None:
|
||||
raise NotImplementedError ()
|
||||
for redrawer in sorted (self.redrawers, key = lambda x: x['layer']):
|
||||
redrawer['func'] ()
|
||||
|
||||
|
||||
class GameObject:
|
||||
frame: int
|
||||
game: Game
|
||||
width: int
|
||||
height: int
|
||||
x: float
|
||||
y: float
|
||||
vx: float
|
||||
vy: float
|
||||
ax: float
|
||||
ay: float
|
||||
arg: float
|
||||
|
||||
def __init__ (
|
||||
self,
|
||||
game: Game,
|
||||
layer: int | None = None,
|
||||
):
|
||||
self.game = game
|
||||
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, 'func': self.redraw })
|
||||
|
||||
def redraw (
|
||||
self,
|
||||
) -> None:
|
||||
self.x += self.vx
|
||||
self.y += self.vy
|
||||
self.vx += self.ax
|
||||
self.vy += self.ay
|
||||
self.frame += 1
|
||||
|
||||
|
||||
class Deerjika (GameObject):
|
||||
surfaces: list[Surface]
|
||||
size: int
|
||||
|
||||
def __init__ (
|
||||
self,
|
||||
game: Game,
|
||||
pattern: DeerjikaPattern = DeerjikaPattern.NORMAL,
|
||||
direction: Direction = Direction.LEFT,
|
||||
layer: int | None = None,
|
||||
):
|
||||
super ().__init__ (self)
|
||||
self.game = game
|
||||
super ().__init__ (game, layer)
|
||||
self.pattern = pattern
|
||||
self.direction = direction
|
||||
match pattern:
|
||||
case DeerjikaPattern.NORMAL:
|
||||
...
|
||||
case DeerjikaPattern.RELAXED:
|
||||
match direction:
|
||||
case Direction.LEFT:
|
||||
self.surfaces = get_surfaces_from_video ('deerjika_relax.mp4')
|
||||
case Direction.RIGHT:
|
||||
...
|
||||
self.size = len (self.surfaces)
|
||||
|
||||
def redraw (
|
||||
self,
|
||||
) -> None:
|
||||
surface: Surface = self.surfaces[self.frame % self.size]
|
||||
self.game.screen.blit (surface, surface.get_rect (center = (self.x, self.y)))
|
||||
super ().redraw ()
|
||||
|
||||
|
||||
class DeerjikaPattern (Enum):
|
||||
@@ -64,5 +125,34 @@ class CWindow:
|
||||
HEIGHT = 768
|
||||
|
||||
|
||||
class Redrawer (TypedDict):
|
||||
layer: int
|
||||
func: Callable[[], None]
|
||||
|
||||
|
||||
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 ()
|
||||
|
||||