このコミットが含まれているのは:
2024-12-09 15:40:06 +09:00
コミット 9f705446a8
6個のファイルの変更106行の追加16行の削除
ファイルの表示

変更前

幅:  |  高さ:  |  サイズ: 57 KiB

変更後

幅:  |  高さ:  |  サイズ: 57 KiB

ファイルの表示

変更前

幅:  |  高さ:  |  サイズ: 99 KiB

変更後

幅:  |  高さ:  |  サイズ: 99 KiB

ファイルの表示

変更前

幅:  |  高さ:  |  サイズ: 53 KiB

変更後

幅:  |  高さ:  |  サイズ: 53 KiB

ファイルの表示

変更前

幅:  |  高さ:  |  サイズ: 40 KiB

変更後

幅:  |  高さ:  |  サイズ: 40 KiB

バイナリ
ファイルの表示
バイナリファイルは表示されません.
+106 -16
ファイルの表示
@@ -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 ()