Space_recycling_game / src /asteroids.py
Antoni09's picture
Upload game files
c02cd3b verified
Raw
History Blame Contribute Delete
2.09 kB
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]