Я пытался сделать простенькую гравитацию в pygame для трех тел (два статичных -- Blue и Yellow) и один динамичный - Red
Я пытался сделать простенькую гравитацию в pygame для трех тел (два статичных -- Blue и Yellow) и один динамичный - Red.
Симуляцию я сделал, но появился вопрос: Можно ли сделать так, чтобы создавалось множество объектов Red (в разных координатах(в центре квадратов(см.рис1))) только по оси x и как-только все эти объекты столкнулись со статичными, они исчезали и появлялось новое множество объектов, ничем не отличающихся от предыдущего, но уже с другим значение по y (все также в центре квадратов)?
Вот и весь код:`
import time
from random import randint
import pygame
import math
#import self
from pygame.locals import *
rects = []
A, B, g, m1, m2 = 992, 992, 10, 5, 5
Bool = True
y = 0
x = 0
color = 'white'
window_size = (A, B)
c = 32
square_size = window_size[0] // c
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((A, B))
dy_sprites = pygame.sprite.Group()
st_sprites = pygame.sprite.Group()
def draw_grid():
for i in range(0, window_size[0], square_size):
pygame.draw.line(screen, pygame.Color('black'), (i, 0), (i, window_size[1]))
for j in range(0, window_size[1], square_size):
pygame.draw.line(screen, pygame.Color('black'), (0, j), (window_size[0], j))
def distance(x1, y1, x2, y2):
return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
draw_grid()
class Static():
def __init__(self, x, y, mass):
self.x = x
self.y = y
self.mass = mass
def update(self):
self.x +=0
class Dynamic(pygame.sprite.Sprite):
def __init__(self, x, y, v, d, mass):
self.x = x
self.y = y
self.i0x = v
self.i0y = d
self.mass = mass
self.vector_fx, self.f, self.fy = 0, 0, 0
def update(self):
if distance(self.x, self.y, Blue.x, Blue.y) > 17 and distance(self.x, self.y, Yellow.x, Yellow.y) > 17:
self.vector_fxy = 1 if self.x < Yellow.x else -1
self.vector_fyy = 1 if self.y < Yellow.y else -1
self.vector_fxb = 1 if self.x < Blue.x else -1
self.vector_fyb = 1 if self.y < Blue.y else -1
self.fb = +(g * self.mass * Blue.mass) / ((distance(self.x, self.y, Blue.x, Blue.y)) ** 2) * self.vector_fxb
self.fyb = +(g * self.mass * Blue.mass) / ((distance(self.x, self.y, Blue.x, Blue.y)) ** 2) * self.vector_fyb
self.fy = +(g * self.mass * Yellow.mass) / ((distance(self.x, self.y, Yellow.x, Yellow.y)) ** 2) * self.vector_fxy
self.fyy = +(g * self.mass * Yellow.mass) / ((distance(self.x, self.y, Yellow.x, Yellow.y)) ** 2) * self.vector_fyy
self.ixb = self.fb + self.i0x
self.iyb = self.fyb + self.i0y
self.ixy = self.fy + self.i0x
self.iyy = self.fyy + self.i0y
self.x += self.ixb
self.y += self.iyb
self.i0x = self.ixb
self.i0y = self.iyb
self.x += self.ixy
self.y += self.iyy
self.i0x = self.ixy
self.i0y = self.iyy
else:
pass
#self.kill()
#time.sleep(0.1)
Blue = Static(558, 496, 10)
Yellow = Static(434, 496, 10)
while Bool:
pygame.display.update()
x_mouse, y_mouse = pygame.mouse.get_pos()
mouse_pos = [x_mouse, y_mouse]
# print(mouse_pos)
target = x_mouse * y_mouse
pygame.display.flip()
pygame.display.update()
Blue.update()
#dy_sprites.update()
screen.fill(color)
draw_grid()
pygame.draw.circle(screen, 'blue', (Blue.x, Blue.y), square_size//2)
pygame.draw.circle(screen, 'yellow', (Yellow.x, Yellow.y), square_size//2)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
`
Ответы (1 шт):
Предоставленный код трудно читаем и не понятен стоит вместо создания отдельных переменных занести их в цикл и дать переменным нормальные назания. Этот код создаёт два статичных объекта и случайный динамичный и если тот уничтожается создаёт новый:
import numpy as np
import pygame
G = 10.
def distance(p1, p2):
return np.linalg.norm(p1 - p2)
def draw_grid():
for i in range(0, window_size[0], square_size):
pygame.draw.line(screen, pygame.Color('black'), (i, 0), (i, window_size[1]))
for j in range(0, window_size[1], square_size):
pygame.draw.line(screen, pygame.Color('black'), (0, j), (window_size[0], j))
# Желательно поместить в отдельный файл
class SimulatingSpace:
def __init__(self):
self.objects = []
self.count_dynamic = 0
def update(self, dt):
for obj in self.objects:
obj.update(dt)
def draw(self):
for obj in self.objects:
obj.draw()
def add_object(self, obj):
if isinstance(obj, DynamicGravityObject):
self.count_dynamic += 1
self.objects.append(obj)
def remove_object(self, obj):
if isinstance(obj, DynamicGravityObject):
self.count_dynamic -= 1
self.objects.remove(obj)
class GravityObject:
def __init__(self, pos, mass, color, space):
self.space = space
self.pos = pos
self.color = color
self.mass = mass
space.add_object(self)
def update(self, dt):
pass
def destroy(self):
self.space.remove_object(self)
del self
def draw(self):
pygame.draw.circle(screen, self.color, self.pos, square_size // 2)
class DynamicGravityObject(GravityObject):
def __init__(self, pos, velocity, mass, color, space):
super().__init__(pos, mass, color, space)
self.velocity = velocity
def update(self, dt):
force = np.array([0., 0.])
for obj in self.space.objects:
dst = distance(self.pos, obj.pos)
if dst == 0:
continue
if dst < square_size:
self.destroy()
force += ((G * self.mass * obj.mass) / (dst * dst * dst)) * (obj.pos - self.pos)
self.velocity += force * dt
self.pos += self.velocity * dt
#######################
running = True
background_color = 'white'
window_size = (992, 992)
squares_count = 32
square_size = window_size[0] // squares_count
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode(window_size)
space = SimulatingSpace()
GravityObject(np.array([558., 496.]), 10., "blue", space)
GravityObject(np.array([434., 496.]), 10., "blue", space)
draw_grid()
delta_time = 0
while running:
screen.fill(background_color)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if space.count_dynamic == 0:
DynamicGravityObject(np.random.random(2) * min(window_size),
(np.random.random(2) - 0.5), 1., "red", space)
space.update(delta_time)
draw_grid()
space.draw()
pygame.display.flip()
pygame.display.update()
delta_time = clock.tick(60)
