Я пытался сделать простенькую гравитацию в 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 шт):

Автор решения: gord1402

Предоставленный код трудно читаем и не понятен стоит вместо создания отдельных переменных занести их в цикл и дать переменным нормальные назания. Этот код создаёт два статичных объекта и случайный динамичный и если тот уничтожается создаёт новый:

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)

→ Ссылка