phantomcastle: universal version + split
This commit is contained in:
91
pygame-wasm/phantomcastle/common.py
Normal file
91
pygame-wasm/phantomcastle/common.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
FONT_NAME = "Arial"
|
||||
|
||||
from sys import platform
|
||||
|
||||
IS_WASM = platform == "emscripten"
|
||||
|
||||
import pygame
|
||||
|
||||
from coords import Coords
|
||||
|
||||
|
||||
class SurfaceWithRect(NamedTuple):
|
||||
surface: pygame.Surface
|
||||
rect: pygame.Rect
|
||||
|
||||
def draw_to(self, target: pygame.Surface):
|
||||
target.blit(self.surface, self.rect)
|
||||
|
||||
|
||||
class DrawableGameObject(ABC):
|
||||
"""обобщение игрового элемента"""
|
||||
|
||||
coords = property(
|
||||
lambda self: self.get_coords(), lambda self, c: self.set_coords(c)
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coords: Coords,
|
||||
parent: Optional["DrawableGameObject"] = None,
|
||||
assets: dict | None = None,
|
||||
):
|
||||
self.parent = parent
|
||||
self.rect = pygame.Rect(coords, coords)
|
||||
self.assets = assets or (parent.assets if parent else None)
|
||||
self._surface = None
|
||||
self._mask = None
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.__class__.__name__}({self.coords})"
|
||||
|
||||
@property
|
||||
def surface(self) -> pygame.Surface | None:
|
||||
return self._surface or (self.parent.surface if self.parent else None)
|
||||
|
||||
@property
|
||||
def mask(self) -> pygame.Mask | None:
|
||||
if not self._mask:
|
||||
self._mask = pygame.mask.from_surface(self.surface.convert_alpha())
|
||||
return self._mask
|
||||
|
||||
def overlap(self, rect: pygame.Rect, mask: pygame.Mask) -> bool:
|
||||
if not self.rect.colliderect(rect):
|
||||
return False
|
||||
|
||||
offset = Coords(*self.rect.topleft) - Coords(*rect.topleft)
|
||||
overlap = mask.overlap(self.mask, offset)
|
||||
return overlap is not None
|
||||
|
||||
@property
|
||||
def scene(self):
|
||||
return self.parent.scene if self.parent else self
|
||||
|
||||
def get_coords(self) -> Coords:
|
||||
return Coords(*self.rect.topleft)
|
||||
|
||||
def set_coords(self, coords: Coords):
|
||||
new_rect = self.rect.copy()
|
||||
new_rect.topleft = coords
|
||||
if self.parent:
|
||||
if self.parent.rect:
|
||||
if not self.parent.rect.contains(new_rect):
|
||||
return
|
||||
self.rect = new_rect
|
||||
|
||||
@abstractmethod
|
||||
def draw(self):
|
||||
pass
|
||||
|
||||
|
||||
class EventHandler(ABC):
|
||||
@abstractmethod
|
||||
def handle_keys(self, keys_pressed):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def handle_event(self):
|
||||
pass
|
||||
Reference in New Issue
Block a user