89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
import json
|
|
|
|
import pygame
|
|
from pygame import transform, gfxdraw, Vector2, Surface
|
|
from math import sin, cos, pi
|
|
|
|
from time import time, sleep
|
|
from random import random
|
|
|
|
class Star:
|
|
def __init__(self, sid: str, x: int, y: int, alpha: float, rot: float, scale: float, offset: float, image: pygame.Surface):
|
|
self.sid = sid
|
|
self.x = x
|
|
self.y = y
|
|
self.rot = rot
|
|
self.alpha = alpha
|
|
self.scale = scale
|
|
self.offset = offset
|
|
self.image = image
|
|
|
|
|
|
class Screen:
|
|
def __init__(self, stars: list[Star], background: Surface | None) -> None:
|
|
if not pygame.get_init():
|
|
pygame.init()
|
|
self.screen = pygame.display.set_mode((1920, 1080), display=1, flags=pygame.FULLSCREEN | pygame.DOUBLEBUF | pygame.WINDOWTAKEFOCUS)
|
|
self.clock = pygame.time.Clock()
|
|
self.stars = stars
|
|
self.last = time()
|
|
self.brightness = 1.0
|
|
self.active_scene = 0
|
|
self.last_scene = 0
|
|
self.scene_time: float = 0
|
|
if background:
|
|
ratio_x = self.screen.get_width() / background.get_width()
|
|
ratio_y = self.screen.get_height() / background.get_height()
|
|
scaled_background = transform.rotozoom(background, 0, max(ratio_x, ratio_y))
|
|
|
|
self.bg_pos = (
|
|
(self.screen.get_width() - scaled_background.get_width()) / 2,
|
|
(self.screen.get_height() - scaled_background.get_height()) / 2
|
|
)
|
|
self.background = scaled_background
|
|
else:
|
|
self.background = None
|
|
self.bg_pos = None
|
|
|
|
|
|
|
|
def update(self, scene_data):
|
|
self.screen.fill((0, 0, 0))
|
|
now = time()
|
|
delta = now - self.last
|
|
self.last = now
|
|
|
|
self.scene_time += delta
|
|
weight = sin(min(self.scene_time, pi/2)) ** 2
|
|
|
|
def update_star_scene(star, old, new, weight):
|
|
star.x = weight*new[star.sid]['x'] + (1-weight)*old[star.sid]['x']
|
|
star.y = weight*new[star.sid]['y'] + (1-weight)*old[star.sid]['y']
|
|
star.rot = weight*new[star.sid]['rot'] + (1-weight)*old[star.sid]['rot']
|
|
star.scale = weight*new[star.sid]['scale'] + (1-weight)*old[star.sid]['scale']
|
|
|
|
|
|
# first draw the background, if any
|
|
if self.background:
|
|
self.screen.blit(self.background, self.bg_pos)
|
|
|
|
# draw all the star objects
|
|
for star in self.stars:
|
|
update_star_scene(star, scene_data[self.last_scene], scene_data[self.active_scene], weight)
|
|
star.alpha += star.rot * delta
|
|
computed_scale = star.scale * (self.screen.get_width() / star.image.get_width() / 100)
|
|
scaled = transform.rotozoom(star.image, star.alpha, computed_scale)
|
|
(w, h) = scaled.get_size()
|
|
pos = (star.x*self.screen.get_width() - w/2, star.y*self.screen.get_height() - h/2)
|
|
self.screen.blit(scaled, pos)
|
|
|
|
|
|
overlay = pygame.surface.Surface((1920, 1080), depth=32)
|
|
overlay.set_alpha(int(255 * (1 - self.brightness)))
|
|
self.screen.blit(overlay, (0, 0))
|
|
|
|
pygame.display.flip()
|
|
self.clock.tick(60)
|
|
|
|
def close(self):
|
|
pygame.quit() |