Как правильно обновить положение и скорость 100 объектов класса, рисуя отдельно с помощью Pygame? - PullRequest
2 голосов
/ 23 января 2020

Я смотрел это видео https://www.youtube.com/watch?v=mhjuuHl6qHM от The Coding Train, и я подумал: "а что если я сделаю это в python?" Я решил использовать Pygame для графики, так как я ужасно разбираюсь в программировании и тоже очень новый, так что это все, что я действительно знаю. Я решил сделать это. Но я быстро понял, что это невозможно для меня. Я все еще хотел сделать одну часть видео в качестве испытания. Часть, где он создает группу кругов, дает им все случайные скорости и позволяет им go из центра экрана. Итак, я создал 100 «boids» со случайным вектором скорости и поместил их положение, скорость и ускорение в список. Это открывает окно пигмея и создает boids, даже обновляя их положение. К сожалению, позиции, которые они имеют, не обновляются правильно, и они превращаются в скопление кругов, которые движутся в одном направлении от экрана. Кто-нибудь может мне помочь с этим?

import pygame
import pygame.locals
import numpy

pygame.init()
screen = (1600, 1200)
display = pygame.display.set_mode(screen)
clock = pygame.time.Clock()
boids = []
j = 0

class Boid:
    position = numpy.array([screen[0] / 2, screen[1] / 2])
    velocity = numpy.array([0, 0])
    acceleration = numpy.array([0, 0])

    def update(self):
        self.position += self.velocity
        self.velocity += self.acceleration

for i in range(100):
    i = Boid()
    i.velocity = (numpy.random.choice([-5, -4, -3. -2. -1, 1, 2, 3, 4, 5]) * (numpy.random.random(2,)) + numpy.array([0.5, 0.5]))
    boids.append(i)
    #print(numpy.random.choice([-5, -4, -3. -2. -1, 1, 2, 3, 4, 5]))
    print(i.position, i.velocity, i.acceleration)

while True:
    j += 1
    display.fill((0, 0, 0))
    for n in range(len(boids)):
        pygame.draw.circle(display, (255 - n, 255 - n, 255 - n), (int(boids[n].position[0]), int(boids[n].position[1])), 20)
        Boid.update(boids[n])
        print(n, boids[n].position, boids[n].velocity, boids[n].acceleration)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    i.update()
    clock.tick(30)
    pygame.display.update()
    if j == 5:
        pygame.quit()
        exit()

1 Ответ

5 голосов
/ 23 января 2020

position, velocity, acceleration являются атрибутами класса . Добавьте конструктор в класс Boid и создайте атрибут экземпляра :

class Boid:
    def __init__(self):
        self.position = numpy.array([screen[0] / 2, screen[1] / 2])
        self.velocity = numpy.array([0, 0])
        self.acceleration = numpy.array([0, 0])

    def update(self):
        self.position += self.velocity
        self.velocity += self.acceleration

Атрибуты класса являются общими для всех экземпляров класса. Но атрибуты экземпляра уникальны для каждого экземпляра. На самом деле у вас есть только один position, общий для всех экземпляров Boid.


Для случайного и различного распределения компонентов x и y вы можете использовать numpy.random.random_sample:

i.velocity = 5 * (numpy.random.random_sample((2)) - numpy.array([0.5, 0.5]))

Или даже решение со случайным вектором направления для кругового распределения:

vec =  numpy.random.random_sample(2) - numpy.array([0.5, 0.5])
i.velocity = 5 * numpy.random.random(1) * vec / numpy.linalg.norm(vec)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...