60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
import random
|
|||
|
|
from collections.abc import Callable
|
||
|
|
|
||
|
|
import pygame
|
||
|
|
|
||
|
|
from asteroid import Asteroid
|
||
|
|
from constants import *
|
||
|
|
|
||
|
|
Edge = tuple[pygame.Vector2, Callable[[float], pygame.Vector2]]
|
||
|
|
|
||
|
|
|
||
|
|
class AsteroidField(pygame.sprite.Sprite):
|
||
|
|
containers: pygame.sprite.Group
|
||
|
|
|
||
|
|
edges: list[Edge] = [
|
||
|
|
(
|
||
|
|
pygame.Vector2(1, 0),
|
||
|
|
lambda y: pygame.Vector2(-ASTEROID_MAX_RADIUS, y * SCREEN_HEIGHT),
|
||
|
|
),
|
||
|
|
(
|
||
|
|
pygame.Vector2(-1, 0),
|
||
|
|
lambda y: pygame.Vector2(
|
||
|
|
SCREEN_WIDTH + ASTEROID_MAX_RADIUS, y * SCREEN_HEIGHT
|
||
|
|
),
|
||
|
|
),
|
||
|
|
(
|
||
|
|
pygame.Vector2(0, 1),
|
||
|
|
lambda x: pygame.Vector2(x * SCREEN_WIDTH, -ASTEROID_MAX_RADIUS),
|
||
|
|
),
|
||
|
|
(
|
||
|
|
pygame.Vector2(0, -1),
|
||
|
|
lambda x: pygame.Vector2(
|
||
|
|
x * SCREEN_WIDTH, SCREEN_HEIGHT + ASTEROID_MAX_RADIUS
|
||
|
|
),
|
||
|
|
),
|
||
|
|
]
|
||
|
|
|
||
|
|
def __init__(self) -> None:
|
||
|
|
pygame.sprite.Sprite.__init__(self, self.containers)
|
||
|
|
self.spawn_timer = 0.0
|
||
|
|
|
||
|
|
def spawn(
|
||
|
|
self, radius: float, position: pygame.Vector2, velocity: pygame.Vector2
|
||
|
|
) -> None:
|
||
|
|
asteroid = Asteroid(position.x, position.y, radius)
|
||
|
|
asteroid.velocity = velocity
|
||
|
|
|
||
|
|
def update(self, dt: float) -> None:
|
||
|
|
self.spawn_timer += dt
|
||
|
|
if self.spawn_timer > ASTEROID_SPAWN_RATE_SECONDS:
|
||
|
|
self.spawn_timer = 0
|
||
|
|
|
||
|
|
edge = random.choice(self.edges)
|
||
|
|
speed = random.randint(40, 100)
|
||
|
|
velocity = edge[0] * speed
|
||
|
|
velocity = velocity.rotate(random.randint(-30, 30))
|
||
|
|
position = edge[1](random.uniform(0, 1))
|
||
|
|
kind = random.randint(1, ASTEROID_KINDS)
|
||
|
|
self.spawn(ASTEROID_MIN_RADIUS * kind, position, velocity)
|