phantomcastle: universal version + split
This commit is contained in:
91
pygame-wasm/phantomcastle/coords.py
Normal file
91
pygame-wasm/phantomcastle/coords.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from enum import Enum
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
|
||||
class Coords(NamedTuple):
|
||||
"""
|
||||
Вспомогательный класс для упрощения работы с координатами
|
||||
"""
|
||||
|
||||
x: int | float
|
||||
y: int | float
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(self.x + other.x, self.y + other.y)
|
||||
if isinstance(other, (int, float)):
|
||||
return self.__class__(self.x + other, self.y + other)
|
||||
return NotImplemented
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(self.x - other.x, self.y - other.y)
|
||||
if isinstance(other, (int, float)):
|
||||
return self.__class__(self.x - other, self.y - other)
|
||||
return NotImplemented
|
||||
|
||||
def __floordiv__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(self.x // other.x, self.y // other.y)
|
||||
if isinstance(other, (int, float)):
|
||||
return self.__class__(self.x // other, self.y // other)
|
||||
return NotImplemented
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(self.x * other.x, self.y * other.y)
|
||||
if isinstance(other, (int, float)):
|
||||
return self.__class__(self.x * other, self.y * other)
|
||||
return NotImplemented
|
||||
|
||||
def transform(self, ref: "Coords"):
|
||||
return self * ref
|
||||
|
||||
def dir_norm(self):
|
||||
"""нормализация вектора, но только для получения направления
|
||||
x, y могут быть только -1, 0, 1
|
||||
может быть только направление по горизонтали либо по вертикали
|
||||
либо без направления
|
||||
"""
|
||||
src = self
|
||||
if self.x and self.y:
|
||||
src = (
|
||||
self.__class__(self.x, 0)
|
||||
if abs(self.x) > abs(self.y)
|
||||
else self.__class__(0, self.y)
|
||||
)
|
||||
return self.__class__(*((n > 0) - (n < 0) for n in src))
|
||||
|
||||
@classmethod
|
||||
def zero(cls):
|
||||
return cls(0, 0)
|
||||
|
||||
|
||||
class Direction(Enum):
|
||||
LEFT = 1
|
||||
RIGHT = 2
|
||||
UP = 3
|
||||
DOWN = 4
|
||||
|
||||
def as_coords(self):
|
||||
match self:
|
||||
case Direction.LEFT:
|
||||
return Coords(-1, 0)
|
||||
case Direction.RIGHT:
|
||||
return Coords(1, 0)
|
||||
case Direction.UP:
|
||||
return Coords(0, -1)
|
||||
case Direction.DOWN:
|
||||
return Coords(0, 1)
|
||||
|
||||
@staticmethod
|
||||
def from_coords(coords: Coords) -> Optional["Direction"]:
|
||||
match coords.dir_norm():
|
||||
case Coords(-1, 0):
|
||||
return Direction.LEFT
|
||||
case Coords(1, 0):
|
||||
return Direction.RIGHT
|
||||
case Coords(0, -1):
|
||||
return Direction.UP
|
||||
case Coords(0, 1):
|
||||
return Direction.DOWN
|
||||
Reference in New Issue
Block a user