first commit
This commit is contained in:
commit
26c91ea093
BIN
logo_new.png
Normal file
BIN
logo_new.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
288
main.py
Normal file
288
main.py
Normal file
@ -0,0 +1,288 @@
|
||||
import pygame
|
||||
import pygame.gfxdraw
|
||||
from PIL import Image
|
||||
import random
|
||||
from math import cos, sin
|
||||
|
||||
##### CONFIG #####
|
||||
window_size = (1280, 720)
|
||||
|
||||
fps = 60
|
||||
|
||||
# pixel size in percentage of window height (0.0 - 1.0)
|
||||
pixel_size = 0.018
|
||||
|
||||
# min and max distance from screen edge to pixel in window height percentage (0.0 - 1.0)
|
||||
min_distribution_edge_dist = 0.1
|
||||
max_distribution_edge_dist = 0.2
|
||||
|
||||
initial_vel_randomness = 1
|
||||
|
||||
# max random delay of pixel simulation start in seconds
|
||||
max_random_delay = 2
|
||||
|
||||
|
||||
## simulation settings
|
||||
# 0.0 - inf
|
||||
stiffness = 40
|
||||
|
||||
# 0.0 - 1.0
|
||||
damping = 0.08
|
||||
|
||||
##################
|
||||
|
||||
damping_multiplier = 1 - damping
|
||||
|
||||
target_delta_time = 1 / fps
|
||||
|
||||
half_window_size = (window_size[0] / 2, window_size[1] / 2)
|
||||
|
||||
print("=====================")
|
||||
|
||||
aspect_ratio = window_size[0] / window_size[1]
|
||||
half_aspect_ratio = aspect_ratio / 2
|
||||
print(f"Aspect ratio: {aspect_ratio}")
|
||||
|
||||
pixel_size_px = pixel_size * window_size[1]
|
||||
half_pixel_size_px = round(pixel_size_px / 2)
|
||||
print(f"Pixel size: {pixel_size_px}px")
|
||||
|
||||
|
||||
# import logo image
|
||||
logo = Image.open("logo_new.png").convert("1")
|
||||
|
||||
|
||||
logo_size = (logo.size[0] * pixel_size, logo.size[1] * pixel_size)
|
||||
print(f"Logo size: {logo_size}")
|
||||
|
||||
# offset in world space so the logo is in the center
|
||||
#logo_offset = ((aspect_ratio - logo_size[0]) / 2, (1 - logo_size[1]) / 2)
|
||||
logo_offset = (logo_size[0] / 2, logo_size[1] / 2)
|
||||
print(f"Logo offset: {logo_offset}")
|
||||
|
||||
|
||||
print("=====================")
|
||||
|
||||
|
||||
|
||||
|
||||
pixels_target_pos = []
|
||||
|
||||
for y in range(logo.size[1]):
|
||||
for x in range(logo.size[0]):
|
||||
if logo.getpixel((x, y)) == 255:
|
||||
pixels_target_pos.append((x * pixel_size - logo_offset[0], y * pixel_size - logo_offset[1]))
|
||||
|
||||
pixels_target_pos = tuple(pixels_target_pos)
|
||||
|
||||
|
||||
## distribute pixels in random positions off the screen
|
||||
|
||||
pixels_pos_and_vel = []
|
||||
|
||||
for pixel in pixels_target_pos:
|
||||
# select random screen edge axis using 1 and aspect_ratio as weights | 0 = x, 1 = y
|
||||
edge_axis = random.choices((0, 1), weights=[1, aspect_ratio])[0]
|
||||
|
||||
# select random edge | (x axis): 0 = left, 1 = right | (y axis): 0 = top, 1 = bottom
|
||||
edge = random.choice((-1, 1))
|
||||
|
||||
# random position on edge
|
||||
if edge_axis == 0: # x axis (vertical edges)
|
||||
pos = [half_aspect_ratio * edge, random.uniform(-.5, .5)]
|
||||
else: # y axis (horizontal edges)
|
||||
pos = [random.uniform(-half_aspect_ratio, half_aspect_ratio), edge / 2]
|
||||
|
||||
# offset pos by random 0 to distribution_edge_dist_px
|
||||
pos[edge_axis] += random.uniform(min_distribution_edge_dist, max_distribution_edge_dist) * edge
|
||||
|
||||
|
||||
# pos, velocity, delay
|
||||
pixels_pos_and_vel.append([
|
||||
pos,
|
||||
[random.uniform(-initial_vel_randomness, initial_vel_randomness), random.uniform(-initial_vel_randomness, initial_vel_randomness)],
|
||||
random.uniform(0, max_random_delay) + 1
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# pygame init
|
||||
pygame.init()
|
||||
window = pygame.display.set_mode(window_size)
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rot_zoom_delay = 6
|
||||
rot_speed_increase = 0.2
|
||||
zoom_speed_increase = 0.65
|
||||
|
||||
rot_speed = 0
|
||||
zoom_speed = 0.04
|
||||
|
||||
fade_delay = 1.5
|
||||
fade_speed = 255/1.5
|
||||
|
||||
angle = 0
|
||||
zoom = 1
|
||||
fade_val = 255
|
||||
|
||||
can_rot = False
|
||||
|
||||
|
||||
# main loop
|
||||
while True:
|
||||
# events
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
quit()
|
||||
|
||||
|
||||
window.fill((0, 0, 0))
|
||||
|
||||
if fade_val > 0:
|
||||
if rot_zoom_delay > 0:
|
||||
rot_zoom_delay -= target_delta_time
|
||||
else: # zooming more and rotating
|
||||
rot_speed += rot_speed_increase * target_delta_time
|
||||
zoom_speed += zoom_speed_increase * target_delta_time
|
||||
|
||||
angle += rot_speed * target_delta_time
|
||||
|
||||
# rotate and zoom
|
||||
rot_cos = cos(angle)
|
||||
rot_sin = sin(angle)
|
||||
|
||||
if not can_rot:
|
||||
can_rot = True
|
||||
|
||||
# fade
|
||||
if fade_delay > 0:
|
||||
fade_delay -= target_delta_time
|
||||
else:
|
||||
fade_val -= fade_speed * target_delta_time
|
||||
if fade_val < 0:
|
||||
continue
|
||||
|
||||
zoom *= 1 + zoom_speed * target_delta_time
|
||||
|
||||
# calculate pixel points positions
|
||||
scaled_pixel_size_px = pixel_size_px * zoom
|
||||
half_scaled_pixel_size_px = round(scaled_pixel_size_px / 2)
|
||||
scaled_pixel_size_px = round(scaled_pixel_size_px)
|
||||
|
||||
pixel_points = (
|
||||
(0, 0),
|
||||
(scaled_pixel_size_px, 0),
|
||||
(scaled_pixel_size_px, scaled_pixel_size_px),
|
||||
(0, scaled_pixel_size_px)
|
||||
)
|
||||
|
||||
pixel_points = tuple(
|
||||
(
|
||||
pixel_point[0] - half_scaled_pixel_size_px,
|
||||
pixel_point[1] - half_scaled_pixel_size_px
|
||||
)
|
||||
for pixel_point in pixel_points
|
||||
)
|
||||
|
||||
# rotate pixel points
|
||||
if can_rot:
|
||||
pixel_points = tuple(
|
||||
(
|
||||
pixel_point[0] * rot_cos - pixel_point[1] * rot_sin,
|
||||
pixel_point[0] * rot_sin + pixel_point[1] * rot_cos
|
||||
)
|
||||
for pixel_point in pixel_points
|
||||
)
|
||||
|
||||
|
||||
# draw pixels
|
||||
for pixel_idx, pixel in enumerate(pixels_pos_and_vel):
|
||||
# check if delay is over
|
||||
if pixel[2] > 0:
|
||||
pixel[2] -= target_delta_time
|
||||
continue
|
||||
|
||||
## simulation (take target_delta_time into account)
|
||||
|
||||
# get pixel pos and vel
|
||||
pos = pixel[0]
|
||||
vel = pixel[1]
|
||||
|
||||
# delta pos (target pos - current pos)
|
||||
delta_pos = [pixels_target_pos[pixel_idx][0] - pos[0], pixels_target_pos[pixel_idx][1] - pos[1]]
|
||||
|
||||
# update velocity
|
||||
vel[0] += delta_pos[0] * stiffness * target_delta_time
|
||||
vel[1] += delta_pos[1] * stiffness * target_delta_time
|
||||
|
||||
# damping
|
||||
vel[0] *= damping_multiplier
|
||||
vel[1] *= damping_multiplier
|
||||
|
||||
# update pos
|
||||
pos[0] += vel[0] * target_delta_time
|
||||
pos[1] += vel[1] * target_delta_time
|
||||
|
||||
# update pixel pos and vel
|
||||
pixels_pos_and_vel[pixel_idx][0:2] = [pos, vel]
|
||||
|
||||
|
||||
## draw pixel
|
||||
|
||||
# rotate
|
||||
if can_rot:
|
||||
pixel_draw_pos = (
|
||||
pos[0] * rot_cos - pos[1] * rot_sin,
|
||||
pos[0] * rot_sin + pos[1] * rot_cos
|
||||
)
|
||||
else:
|
||||
pixel_draw_pos = pos
|
||||
|
||||
# zoom
|
||||
perceived_zoom = zoom
|
||||
pixel_draw_pos = (pixel_draw_pos[0] * perceived_zoom, pixel_draw_pos[1] * perceived_zoom)
|
||||
|
||||
# convert to screen space
|
||||
pixel_draw_pos = (
|
||||
pixel_draw_pos[0] * window_size[1] + half_window_size[0],
|
||||
pixel_draw_pos[1] * window_size[1] + half_window_size[1]
|
||||
)
|
||||
|
||||
|
||||
# DEBUG draw sphere
|
||||
#pygame.draw.circle(window, (255, 255, 255), (round(pixel_draw_pos[0]), round(pixel_draw_pos[1])), 200, 5)
|
||||
|
||||
# DEBUG draw dot
|
||||
#pygame.draw.circle(window, (255, 0, 0), (round(pixel_draw_pos[0]), round(pixel_draw_pos[1])), 1)
|
||||
|
||||
# draw pixel
|
||||
points = tuple(
|
||||
(round(pixel_draw_pos[0] + pixel_point[0]),
|
||||
round(pixel_draw_pos[1] + pixel_point[1])) for pixel_point in pixel_points
|
||||
)
|
||||
|
||||
pygame.gfxdraw.aapolygon(
|
||||
window,
|
||||
points,
|
||||
(fade_val,)*3
|
||||
)
|
||||
|
||||
pygame.gfxdraw.filled_polygon(
|
||||
window,
|
||||
points,
|
||||
(fade_val,)*3
|
||||
)
|
||||
|
||||
|
||||
|
||||
# update
|
||||
pygame.display.update()
|
||||
clock.tick(60)
|
Loading…
Reference in New Issue
Block a user