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



这段代码绘制了我的轨道模拟器的基础,但一旦它与一颗行星完成了一个轨道,它就会移动到列表中的下一个,我该如何使它同时完成所有不同的轨道。

#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()

我也可以这样做,所以列表中只有一个项目,但它从来不会旋转不止一次,所以,如果我加上行星角度+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()

问题出在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()

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

最新更新