122 lines
2.9 KiB
Python
122 lines
2.9 KiB
Python
from dataclasses import dataclass, field
|
|
from typing import cast
|
|
|
|
from pyglet.shapes import Circle, Line
|
|
from libs.ecs.world import World
|
|
from components import (
|
|
Color,
|
|
PlanetMarker,
|
|
Position,
|
|
Radius,
|
|
SpaceShipMarker,
|
|
Destination,
|
|
)
|
|
from random import choice, randint, sample
|
|
from settings import (
|
|
MIN_PLANET_RADIUS,
|
|
MAX_PLANET_RADIUS,
|
|
PLANET_COLORS,
|
|
SCREEN_WIDTH,
|
|
SCREEN_HEIGHT,
|
|
SPACESHIP_COLOR,
|
|
SPACESHIP_PATH_COLOR,
|
|
SPACESHIP_RADIUS,
|
|
)
|
|
from libs.ecs.state import BaseGameState
|
|
|
|
|
|
@dataclass
|
|
class GameState(BaseGameState):
|
|
selected_planet: int | None = None
|
|
routes: dict[tuple[int, int], "Line"] = field(default_factory=dict)
|
|
|
|
|
|
def create_planet(
|
|
world: World,
|
|
x: float,
|
|
y: float,
|
|
radius: int,
|
|
color: tuple[int, int, int, int],
|
|
) -> int:
|
|
return world.spawn(
|
|
PlanetMarker(),
|
|
Position(x=x, y=y),
|
|
Color(value=color),
|
|
Circle(x=x, y=y, radius=radius, color=color),
|
|
Radius(radius),
|
|
)
|
|
|
|
|
|
def create_spaceship(
|
|
world: World,
|
|
src_x: float,
|
|
src_y: float,
|
|
dest_x: float,
|
|
dest_y: float,
|
|
approach_radius: int,
|
|
):
|
|
return world.spawn(
|
|
SpaceShipMarker(),
|
|
Position(x=src_x, y=src_y),
|
|
Destination(x=dest_x, y=dest_y),
|
|
Radius(approach_radius),
|
|
Circle(
|
|
x=src_x,
|
|
y=src_y,
|
|
radius=SPACESHIP_RADIUS,
|
|
color=SPACESHIP_COLOR,
|
|
),
|
|
)
|
|
|
|
|
|
def generate_random_planet(world: World) -> int:
|
|
radius: int = randint(MIN_PLANET_RADIUS, MAX_PLANET_RADIUS)
|
|
x: float = float(randint(radius, SCREEN_WIDTH - radius))
|
|
y: float = float(randint(radius, SCREEN_HEIGHT - radius))
|
|
# color = (randint(0, 255), randint(0, 255), randint(0, 255), 255)
|
|
color = choice(PLANET_COLORS) + (255,)
|
|
return create_planet(world, x, y, radius, color)
|
|
|
|
|
|
def create_travelling_spaceship(
|
|
world: World,
|
|
src_planet: int,
|
|
dest_planet: int,
|
|
):
|
|
src_planet_cs = world.get_components(src_planet)
|
|
if src_planet_cs is None:
|
|
raise Exception("invalid_planet")
|
|
dest_planet_cs = world.get_components(dest_planet)
|
|
if dest_planet_cs is None:
|
|
raise Exception("invalid_planet")
|
|
|
|
source_pos = src_planet_cs[Position]
|
|
dest_pos = dest_planet_cs[Position]
|
|
approach_radius = dest_planet_cs[Radius].value
|
|
return create_spaceship(
|
|
world,
|
|
src_x=source_pos.x,
|
|
src_y=source_pos.y,
|
|
dest_x=dest_pos.x,
|
|
dest_y=dest_pos.y,
|
|
approach_radius=approach_radius,
|
|
)
|
|
|
|
|
|
def generate_random_spaceship(world: World) -> int:
|
|
planets = [entity for entity, _ in world.query(PlanetMarker)]
|
|
|
|
_planet_sample = sample(planets, 2)
|
|
|
|
return create_travelling_spaceship(world, *_planet_sample)
|
|
|
|
|
|
def load_items(path: str) -> list[str]:
|
|
with open(path) as f:
|
|
data = [l.rstrip("\n") for l in f.readlines()]
|
|
return data
|
|
|
|
|
|
def normalize_name(name: str) -> str:
|
|
return name.replace("_", " ").title()
|