Spaces:
Running
Running
| from __future__ import annotations | |
| import random | |
| from typing import Dict, Tuple | |
| import pygame | |
| from config import constants | |
| from src.items import Item, random_metal_drop | |
| class Asteroid(pygame.sprite.Sprite): | |
| """Simple asteroid obstacle with HP and contact damage.""" | |
| def __init__(self, variant: str, spawn_pos: Tuple[float, float], speed: float = 120.0, sprite: pygame.Surface | None = None): | |
| super().__init__() | |
| data: Dict[str, float] = constants.ASTEROID_TYPES[variant] | |
| self.variant = variant | |
| self.hp = data["hp"] | |
| self.damage = data["damage"] | |
| self.speed = speed | |
| if sprite is None: | |
| sprite = pygame.Surface((32, 24), pygame.SRCALPHA) | |
| color = (120, 120, 120) if variant == "small" else (140, 110, 110) | |
| if variant == "wreck_fragment": | |
| color = (90, 90, 130) | |
| sprite.fill(color) | |
| self.image = sprite | |
| self.rect = self.image.get_rect(center=spawn_pos) | |
| self.pos = pygame.Vector2(spawn_pos) | |
| self.vel = pygame.Vector2(-self.speed, random.uniform(-40, 40)) | |
| def update(self, dt: float): | |
| self.pos += self.vel * dt | |
| self.rect.center = (int(self.pos.x), int(self.pos.y)) | |
| def take_damage(self, amount: float): | |
| self.hp -= amount | |
| def is_dead(self) -> bool: | |
| return self.hp <= 0 | |
| def drop_loot(self) -> list[Item]: | |
| data: Dict[str, float] = constants.ASTEROID_TYPES[self.variant] | |
| drop_min, drop_max = data["drop_range"] | |
| drops = [] | |
| for _ in range(random.randint(drop_min, drop_max)): | |
| drops.append(Item(random_metal_drop(), self.rect.center)) | |
| return drops | |
| def choose_variant() -> str: | |
| variants = list(constants.ASTEROID_TYPES.keys()) | |
| weights = [constants.ASTEROID_TYPES[v]["spawn_weight"] for v in variants] | |
| total = sum(weights) | |
| r = random.uniform(0, total) | |
| cumulative = 0.0 | |
| for variant, w in zip(variants, weights): | |
| cumulative += w | |
| if r <= cumulative: | |
| return variant | |
| return variants[-1] | |