This commit is contained in:
2021-09-02 19:56:28 +02:00
parent 9a1c6d95b8
commit 319b85c552
8 changed files with 244 additions and 5 deletions

78
UI/Objects/Multiscene.py Normal file
View File

@@ -0,0 +1,78 @@
import math
import pygame
from numpy import array as a
from Objects.Scene import Scene
class Multiscene(Scene):
def __init__(self, width: float, height: float, scene_size: a):
super().__init__(width, height, scene_size)
self.subscenes = []
self.subscenes_prepared = False
def prepare_subscenes(self):
for subscene in self.subscenes:
subscene.multiscene = self
subscene.subscene_size = subscene.screen_size
subscene.resize_screen(self.to_ints((self.matrix @ subscene.subscene_size).tolist()), True)
self.subscenes_prepared = True
def redraw(self):
if self.subscenes_prepared is False:
self.prepare_subscenes()
self.s_.fill(self.bg)
for object_ in self.r_objects:
object_.blit()
rs = pygame.transform.scale(self.s_, self.screen_size)
self.s.blit(rs, [0, 0])
for scene in self.subscenes:
scene.blit()
for object_ in self.nr_objects:
object_.blit()
pygame.display.update()
def resize_screen(self, new_screen_size, subscene=False):
if self.subscenes_prepared is False:
self.prepare_subscenes()
self.screen_size = a(new_screen_size)
self.matrix = a([
[new_screen_size[0] / self.width, 0],
[0, new_screen_size[1] / self.height]
])
self.pd = abs(self.matrix[0, 0] * self.matrix[1, 1]) # positive determinant
self.pd_ = math.sqrt(self.pd)
if subscene is False:
self.s = pygame.display.set_mode(new_screen_size)
else:
self.s = pygame.Surface(new_screen_size)
self.resize_subscenes()
def progress(self):
self.progress_subscenes()
def resize_subscenes(self):
for subscene in self.subscenes:
subscene.resize_screen(self.to_ints((self.matrix @ subscene.subscene_size).tolist()), True)
def progress_subscenes(self):
for subscene in self.subscenes:
subscene.progress()
@staticmethod
def to_ints(iterable):
for i in range(len(iterable)):
iterable[i] = int(iterable[i])
return iterable

View File

@@ -9,7 +9,10 @@ class Scene(Screen):
self.bg = bg
self.r_objects = [] # resizable Objects
self.nr_objects = [] # non-resizable Objects
self.nr_objects = [] # non-rescalable Objects
self.position = a([0, 0])
self.multiscene = None
def redraw(self):
self.s_.fill(self.bg)
@@ -25,3 +28,9 @@ class Scene(Screen):
pygame.display.update()
def blit(self):
self.redraw()
self.multiscene.s.blit(self.s, self.multiscene.matrix @ self.position)
def progress(self):
pass

View File

@@ -23,6 +23,20 @@ class Screen:
self.center = a([width, height]) / 2
def resize_screen(self, new_screen_size, subscene=False):
self.screen_size = a(new_screen_size)
self.matrix = a([
[new_screen_size[0] / self.width, 0],
[0, new_screen_size[1] / self.height]
])
self.pd = abs(self.matrix[0, 0] * self.matrix[1, 1]) # positive determinant
self.pd_ = math.sqrt(self.pd)
if subscene is False:
self.s = pygame.display.set_mode(new_screen_size)
else:
self.s = pygame.Surface(new_screen_size)
def save(self, path, size=None):
if size is None:
pygame.image.save(self.s, path)

View File

@@ -0,0 +1,49 @@
from numpy import array as a
import pygame
import math
class EquilateralTriangle:
def __init__(self, position, side_length, rotation, color, scene, width=0):
self.position = position
self.side_length = side_length
self.rotation = rotation
self.color = color
self.scene = scene
self.width = width
self.rotation_point = complex(math.cos(rotation), math.sin(rotation))
self.pd_ = self.scene.pd_
self.points = a([
complex(0, self.side_length),
complex(self.side_length, self.side_length),
complex(self.side_length * 0.5,
self.side_length - math.sqrt(self.side_length ** 2 - (self.side_length * 0.5) ** 2))
])
self.points -= complex(self.side_length * 0.5, self.side_length * 0.5)
self.points *= self.rotation_point * self.pd_
self.points += complex(self.side_length * 0.5, self.side_length * 0.5)
rescaled_position = self.scene.matrix @ self.position
self.points += complex(rescaled_position[0], rescaled_position[1])
self.points = [[point.real, point.imag] for point in self.points]
def blit(self):
if self.pd_ != self.scene.pd_:
self.pd_ = self.scene.pd_
self.points = a([
complex(0, self.side_length),
complex(self.side_length, self.side_length),
complex(self.side_length * 0.5,
self.side_length - math.sqrt(self.side_length ** 2 - (self.side_length * 0.5) ** 2))
])
self.points -= complex(self.side_length * 0.5, self.side_length * 0.5)
self.points *= self.rotation_point * self.pd_
self.points += complex(self.side_length * 0.5, self.side_length * 0.5)
rescaled_position = self.scene.matrix @ self.position
self.points += complex(rescaled_position[0], rescaled_position[1])
self.points = [[point.real, point.imag] for point in self.points]
pygame.draw.polygon(self.scene.s, self.color, self.points, self.width)