一次绘制所有移动的对象,而不是先绘制然后移动到下一个

时间:2018-12-16 18:32:54

标签: python pygame

此代码绘制了我的轨道模拟器的基础知识,但是一旦它完成了一个行星的一个轨道,它便移至列表中的下一个轨道,我如何做到这一点,以便它可以同时完成所有不同的轨道时间。

#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 :(得分:0)

问题是您的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()

它以非常慢的帧速率处理跳跃的轨道。