#31 ぼちぼち
|
変更前 幅: | 高さ: | サイズ: 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 __future__ import annotations
|
||||||
|
|
||||||
from abc import ABCMeta, abstractmethod
|
import sys
|
||||||
|
from enum import Enum, auto
|
||||||
|
from typing import Callable, TypedDict
|
||||||
|
|
||||||
|
import cv2
|
||||||
import pygame
|
import pygame
|
||||||
|
from cv2 import VideoCapture
|
||||||
|
from pygame import Surface
|
||||||
|
from pygame.time import Clock
|
||||||
|
|
||||||
|
|
||||||
def main (
|
def main (
|
||||||
) -> None:
|
) -> None:
|
||||||
pygame.init ()
|
pygame.init ()
|
||||||
game = Game ()
|
game = Game ()
|
||||||
|
deerjika = Deerjika (game, DeerjikaPattern.RELAXED)
|
||||||
while True:
|
while True:
|
||||||
deerjika = Deerjika (game)
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
|
clock: Clock
|
||||||
|
frame: int
|
||||||
|
redrawers: list[Redrawer]
|
||||||
|
screen: Surface
|
||||||
|
|
||||||
def __init__ (
|
def __init__ (
|
||||||
self,
|
self,
|
||||||
):
|
):
|
||||||
self.screen = pygame.display.set_mode ((CWindow.WIDTH, CWindow.HEIGHT))
|
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 (
|
def redraw (
|
||||||
self,
|
self,
|
||||||
) -> None:
|
) -> 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):
|
class Deerjika (GameObject):
|
||||||
|
surfaces: list[Surface]
|
||||||
|
size: int
|
||||||
|
|
||||||
def __init__ (
|
def __init__ (
|
||||||
self,
|
self,
|
||||||
game: Game,
|
game: Game,
|
||||||
pattern: DeerjikaPattern = DeerjikaPattern.NORMAL,
|
pattern: DeerjikaPattern = DeerjikaPattern.NORMAL,
|
||||||
direction: Direction = Direction.LEFT,
|
direction: Direction = Direction.LEFT,
|
||||||
|
layer: int | None = None,
|
||||||
):
|
):
|
||||||
super ().__init__ (self)
|
super ().__init__ (game, layer)
|
||||||
self.game = game
|
|
||||||
self.pattern = pattern
|
self.pattern = pattern
|
||||||
self.direction = direction
|
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):
|
class DeerjikaPattern (Enum):
|
||||||
@@ -64,5 +125,34 @@ class CWindow:
|
|||||||
HEIGHT = 768
|
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__':
|
if __name__ == '__main__':
|
||||||
main ()
|
main ()
|
||||||
|
|||||||