рисование движущихся объектов одновременно вместо рисования одного, а затем переход к следующему - PullRequest
0 голосов
/ 16 декабря 2018

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

#import the library

import pygame,math



#classes
class planet():
    def __init__(self,name,colour,distance,eccentricity,radius,x,y,angle):
        self.screen = screen
        self.name = name
        self.colour = colour
        self.distance = distance
        self.eccentricity = eccentricity
        self.radius = radius
        self.x = x
        self.y = y
        self.angle = angle
    def draw(self):
        pygame.draw.circle(self.screen,self.colour,(self.x,self.y),self.radius,)


def draw_orbit(screen,colour,x,y,r):
    screen.fill(Black)
    int(r)
    pygame.draw.circle(screen,colour,[x,y],r)
    pygame.display.flip
    orbit()

также я могу сделать так, чтобы в списке был только один элемент, но он никогда не делал больше одного поворота, поэтому, если я добавляю planet.angle + 360 вместо только 360, он делает первыйодин, но никогда не двигается от него.

def orbit(planet):

        while planet.angle <= 360:
            a = planet.distance*(1.496*10**8)
            e = planet.eccentricity

            angle_radians = math.radians(planet.angle)
            r = a*(1-(e*math.cos(angle_radians)))

            planet.x = int(math.cos(angle_radians)*r/10**6)
            planet.y = int(math.sin(angle_radians)*r/10**6)


            planet.angle +=1
##            print(planet.angle)
##            print(planet.x,planet.y)

            planet.x +=800
            planet.y +=400





            screen.fill(Black)
            pygame.draw.circle(screen,Red,center,10)
        ##            pygame.draw.circle(screen,White,center,r,1)
            pygame.draw.circle(screen,planet.colour,[planet.x,planet.y],planet.radius)

            pygame.display.flip()








#define colours

Black = (0,0,0)

White = (255,255,255)

Green = (0,255,0)

Red = (255,0,0)

Blue = (0,0,255)





#initialise the engine

pygame.init()



#Opening a window

size = (1600,800)

screen = pygame.display.set_mode(size)
center = [800,400]

planets =[]
planet_draw =[]
# screen,name,colour,distance,eccentricity,radius,x,y
planet_list = [
            ['Mercury',White,0.387,0.2056,5,0,0,120],
            ['Venus',Green,0.723,0.0068,10,0,0,60],
            ['Earth',Blue,1,0.0167,10,0,0,0],
            ['Mars',White,1.524,0.0934,10,0,0,150],
            ['Jupiter',Green,5.203,0.0484,30,0,0,330],
##            [screen,'Saturn',Red,9.537,0.0542,10,0,0],
##            [screen,'Uranus',Red,19.191,0.0472,10,0,0],
##            [screen,'Neptune',Green,30.069,0.0086,10,0,0]
]


for i in planet_list:
    planet_draw.append(planet(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7]))


#set window title

pygame.display.set_caption("Orbit Simulator")

#loop unti the user clicks the close button

done = False

#used to manage how fast the screen updates

clock = pygame.time.Clock()



#------ Main program Loop ------

while not done:

    #--- Main event loop

    for event in pygame.event.get(): #user did something

        if event.type == pygame.QUIT: #if user clicked close

            done = True #flag that we are done and exit the loop




    #------ Game logic should go here ------

    for planet in planet_draw:
        orbit(planet)

    #------ Drawing code should go here -------

    #first, clear the screen to white. Don't put other drawing commands above this or they will be erased with this command.


    #update the screen

    pygame.display.flip()

    #------ Limit to 60 frames per second ------

    clock.tick(60)

#------ When the loop ends, quit ------

pygame.quit()

1 Ответ

0 голосов
/ 18 декабря 2018

Проблема в вашей orbit() функции.Он очищает и перекрашивает весь экран, каждый раз рисуется новая планета.

Функция должна только рисовать планету, очистка экрана и переворачивание должны выполняться в другом месте.

Некоторые псевдокод ~

  1. Обновление орбит (только позиции)
  2. Очистить экран
  3. Рисовать N Планеты
  4. Отражение страницы
  5. Ожидание отметки времени таймера

Код выдачи:

def orbit(planet):
    while planet.angle <= 360:
        a = planet.distance*(1.496*10**8)
        e = planet.eccentricity

        angle_radians = math.radians(planet.angle)
        r = a*(1-(e*math.cos(angle_radians)))

        planet.x = int(math.cos(angle_radians)*r/10**6)
        planet.y = int(math.sin(angle_radians)*r/10**6)
        planet.angle +=1
        # Note: Don't paint, Don't offset for screen size

while not done:

    #--- Main event loop
    for event in pygame.event.get(): #user did something
        if event.type == pygame.QUIT: #if user clicked close
            done = True #flag that we are done and exit the loop

    #------ Game logic should go here ------

    # ---- move the planets -----
    for planet in planet_draw:
        orbit(planet)

    # ------ Re-paint the current state of the screen ------
    screen.fill(Black)
    for planet in planet_draw:
        planet.draw()
    pygame.display.flip()

    #------ Limit to 60 frames per second ------
    clock.tick(60)

Может оказаться проще изменить объект planet так, чтобыучитывая временную метку (или некоторый счетчик), он пересчитывает координаты орбиты в это время.Это может дать вам код вроде:

 while ( True ):
     frame_counter = pygame.get_ticks()

     screen.fill(Black)
     for planet in planet_draw:
         planet.calcuateOrbitAt( frame_counter )
         planet.draw()
     pygame.display.flip()

И он обрабатывает скачкообразные орбиты с очень медленной частотой кадров.

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