Planetio/fast_and_trash.py
2020-12-16 20:40:19 +01:00

323 lines
11 KiB
Python

import json
import math
import random
import pygame
from pygame.locals import *
pygame.init()
def distance_indicator(cords1, cords2):
x_distance = abs(cords1[0] - cords2[0])
y_distance = abs(cords1[1] - cords2[1])
distance = math.sqrt((x_distance ** 2) + (y_distance ** 2))
return round(distance, 4)
def area_intersection_of_circles(points, radius_list):
try:
dist = distance_indicator(points[0], points[1])
alpha_cos = (pow(radius_list[1], 2) + pow(dist, 2) - pow(radius_list[0], 2)) / (2 * radius_list[1] * dist)
alpha = math.acos(alpha_cos)
beta_cos = (dist - alpha_cos * radius_list[1]) / radius_list[0]
beta = math.acos(beta_cos)
triangles = (alpha_cos * pow(radius_list[1], 2) * math.sin(alpha)) + (
beta_cos * pow(radius_list[0], 2) * math.sin(beta))
arcs = ((math.pi * pow(radius_list[0], 2) * beta * 2) / math.tau) + (
(math.pi * pow(radius_list[1], 2) * alpha * 2) / math.tau)
return arcs - triangles
except:
return False
class Circle:
def __init__(self, radius, center, colorX, color_value):
self.radius = radius
self.center = center
self.color = colorX
self.color_value = color_value
def draw(self, display, scroll):
sur = pygame.Surface((self.radius * 2, self.radius * 2))
pygame.draw.circle(sur, self.color_value, [self.radius, self.radius], self.radius)
sur.set_alpha(self.color_value.a)
sur.set_colorkey((0, 0, 0))
display.blit(sur, [-self.radius + self.center[0] - scroll.scroll[0],
-self.radius + self.center[1] - scroll.scroll[1]])
class Game:
def __init__(self):
self.alive = True
self.circles = []
self.c_template = {"color": "red",
"radius": random.randint(30, 50),
"pos": pygame.mouse.get_pos()}
self.colors = get_colors()
self.color_names = list(self.colors.keys())
self.ended_on_own_will = False
# scroll
self.aditional_scroll = [0, 0]
# consts
self.midpoint = [450, 300]
# for gravity
self.base_limit = 1000
self.limit = 1000
self.black = None
self.collapse = False
# points
self.points = 0
def add_circle(self, pos, radius, colorX, color_value, scroll):
new_pos = [pos[0] + scroll.scroll[0], pos[1] + scroll.scroll[1]]
self.circles.append(Circle(radius, new_pos, colorX, color_value))
def disp_circles(self, display, scroll):
for circle in self.circles:
circle.draw(display, scroll)
def get_new_circle_template(self):
self.c_template = get_circle_template(self.color_names)
def draw_template(self, display):
sur = pygame.Surface((self.c_template["radius"] * 2, self.c_template["radius"] * 2))
pygame.draw.circle(sur, self.colors[self.c_template["color"]],
[self.c_template["radius"],
self.c_template["radius"]], self.c_template["radius"])
sur.set_alpha(self.colors[self.c_template["color"]].a)
sur.set_colorkey((0, 0, 0))
display.blit(sur, [-self.c_template["radius"] + self.c_template["pos"][0],
-self.c_template["radius"] + self.c_template["pos"][1]])
def get_gravity(self):
final_value = [0, 0]
for circle in self.circles:
dist = distance_indicator(circle.center, self.midpoint)
angle = find_angle_between_points(circle.center, self.midpoint)
final_value[0] += round(math.cos(angle) * dist, 2) * (circle.radius / 20)
final_value[1] += round(math.sin(angle) * dist, 2) * (circle.radius / 20)
dist = distance_indicator(self.midpoint, [final_value[0] + self.midpoint[0], final_value[1] + self.midpoint[1]])
if dist > self.limit:
self.collapse = True
self.alive = False
elif dist > self.limit * 0.6:
self.black.color_value.r = round((dist - (self.limit * 0.6)) * (255 / (self.limit * 0.4)))
if self.black.color_value.r > 255:
self.black.color_value.r = 255
else:
self.black.color_value.r = 0
return final_value
# must be called before add circle
def update_points(self, pos, radius, colorX):
collided = []
multiplier = 1
for circle in self.circles:
dist = distance_indicator(circle.center, pos)
if dist < (radius + circle.radius):
collided.append(circle)
for circle in collided:
area = area_intersection_of_circles([pos, circle.center], [circle.radius, radius])
if colorX == "green":
multiplier = 1.1
elif colorX == "yellow":
multiplier = 1.2
elif colorX == "purple":
multiplier = 2
elif colorX == "smaragd":
multiplier = 4
self.points += (area // 10) * multiplier
def update_lim(self):
self.limit = self.base_limit + (self.points / 10)
def rotate_around_mid(self):
for circle in self.circles:
if circle.color != "black":
dist = distance_indicator(circle.center, self.midpoint)
angle = find_angle_between_points(self.midpoint, circle.center)
angle -= 0.005
angle = round(angle, 3)
circle.center = [self.midpoint[0] + (math.cos(angle) * dist),
self.midpoint[1] + (math.sin(angle) * dist)]
# saving & loading
def save(self, path, setup):
save = {"gravity": setup["gravity"],
"next_circle": self.c_template,
"limit": self.limit,
"points": self.points,
"circles": []}
for circle in self.circles:
save["circles"].append({"radius": circle.radius,
"center": circle.center,
"color": circle.color,
"color_value": str(circle.color_value)})
del save["circles"][0]
with open(path, "w") as f:
json.dump(save, f, indent=4)
def load(self, path, setup):
with open(path, "r") as f:
save = json.load(f)
setup["gravity"] = save["gravity"]
self.c_template = save["next_circle"]
for circle in save["circles"]:
self.circles.append(Circle(circle["radius"], circle["center"], circle["color"],
pygame.Color(eval(circle["color_value"]))))
self.points = save["points"]
self.limit = save["limit"]
return setup
class Scroll:
def __init__(self, scroll):
self.scroll = scroll
self.fade = 20
self.safe_fade = 20
self.in_progress = False
self.save_scroll = self.scroll
def move_scroll(self, player, screen, which, space=20):
if which == "y" or which == "both":
self.scroll[1] += (player.rect.y - self.scroll[1] - (screen[1] / 2) + (player.size[1] / 2)) / space
self.scroll[1] = int(self.scroll[1])
if which == "x" or which == "both":
self.scroll[0] += (player.rect.x - self.scroll[0] - (screen[0] / 2) + (player.size[0] / 2)) / space
self.scroll[0] = int(self.scroll[0])
def add_scroll(self, which, how_much, fade=None):
if fade is not None:
self.safe_fade = fade
if self.in_progress is False:
self.load_safe_fade()
self.save_scroll = self.scroll
self.in_progress = True
how_much[0] /= self.fade
how_much[1] /= self.fade
self.fade += 0.01 * self.fade
if which == "x" or which == "both":
self.scroll[0] += how_much[0]
self.scroll[0] = round(self.scroll[0])
if which == "y" or which == "both":
self.scroll[1] += how_much[1]
self.scroll[1] = round(self.scroll[1])
def load_safe_fade(self):
self.fade = self.safe_fade
self.in_progress = False
def get_colors():
colors = {"red": pygame.Color(255, 0, 0, 125), # weight 16
"blue": pygame.Color(0, 0, 220, 125), # weight 20
"green": pygame.Color(0, 220, 0, 125), # weight 20
"yellow": pygame.Color(252, 239, 56, 125), # weight 22
"purple": pygame.Color(105, 0, 158, 125), # weight 4
"smaragd": pygame.Color(0, 214, 168, 125)} # weight 1
return colors
def get_random_color():
colors = []
colors = add_to_list("red", 20, colors)
colors = add_to_list("blue", 20, colors)
colors = add_to_list("green", 20, colors)
colors = add_to_list("yellow", 18, colors)
colors = add_to_list("purple", 4, colors)
colors = add_to_list("smaragd", 1, colors)
return colors[random.randint(0, len(colors) - 1)]
def get_circle_template():
template = {"color": get_random_color(),
"radius": random.randint(10, 50),
"pos": pygame.mouse.get_pos()}
return template
def add_to_list(what, amount, listx):
for i in range(amount):
listx.append(what)
return listx
def find_angle_between_points(center, point):
dists = distances(center, point)
try:
angle = math.atan(dists[1] / dists[0])
if point[0] < center[0]:
if point[1] < center[1]:
return angle + math.pi
else:
return (math.pi / 2 - angle) + (math.pi / 2)
else:
if point[1] < center[1]:
return (math.pi / 2 - angle) + 3 * (math.pi / 2)
else:
return angle
except ZeroDivisionError:
return False
def distances(cords1, cords2):
return [abs(cords1[0] - cords2[0]), abs(cords1[1] - cords2[1])]
def get_circle(color_value, radius):
sur = pygame.Surface((radius * 2, radius * 2))
pygame.draw.circle(sur, color_value, [radius, radius], radius)
sur.set_alpha(color_value.a)
sur.set_colorkey((0, 0, 0))
return sur
def get_gravity_sur(gravity, limit):
ratio = limit / 40
sur = pygame.Surface((100, 100))
pygame.draw.circle(sur, (200, 200, 200), [50, 50], 40)
pygame.draw.circle(sur, (217, 24, 114), [50 + (gravity[0] / ratio), 50 + (gravity[1] / ratio)], 10)
sur.set_alpha(200)
sur.set_colorkey((0, 0, 0))
return sur
def rotate(center, pos, angleX):
dist = distance_indicator(center, pos)
angle = find_angle_between_points(center, pos)
angle += angleX
return [center[0] + (math.cos(angle) * dist), center[1] + (math.sin(angle) * dist)]