最近我一直想学习如何编写3D渲染引擎,我在YouTube上找到了如何在pygame中进行教程,这是python的附加组件,它运行正常,但问题是,一旦你正在逐渐渲染100多个块,它变得非常“滞后”,并且FPS下降到大约30左右,并且在添加更多块时从那时开始变得更糟。
我的问题是:如果一次渲染大量的块,我如何使代码更有效或更好地消除滞后。
这是我的代码。
import pygame, sys, math, time #Imports the required Add-Ons needed for the code
def rotate2d(pos,rad):
x,y=pos; s,c = math.sin(rad),math.cos(rad); return x*c-y*s,y*c+x*s
class Cam():
def __init__(self,pos=(0,0,0),rot=(0,0)):
self.pos = list(pos)
self.rot = list(rot)
def events(self,event):
if event.type == pygame.MOUSEMOTION:
x,y = event.rel
x/=200; y/=200
self.rot[0]+=y; self.rot[1]+=x
if self.rot[0] > math.pi/2:
self.rot[0] = math.pi/2
if self.rot[0] < -math.pi/2:
self.rot[0] = -math.pi/2
def update(self,dt,key):
s=dt*10
if key[pygame.K_SPACE]: self.pos[1]-=s
if key[pygame.K_LSHIFT]: self.pos[1]+=s
x,y = s*math.sin(self.rot[1]),s*math.cos(self.rot[1])
if key[pygame.K_w]: self.pos[0]+=x; self.pos[2]+= y
if key[pygame.K_s]: self.pos[0]-=x; self.pos[2]-= y
if key[pygame.K_a]: self.pos[0]-=y; self.pos[2]+= x
if key[pygame.K_d]: self.pos[0]+=y; self.pos[2]-= x
pygame.init() #Initialises PyGame
pygame.font.init()
myfont = pygame.font.SysFont('', 30)
w,h = 1440,900 #Width and height of the screen
cx,cy = w//2,h//2 #Co-ords of the middle of the screen
screen = pygame.display.set_mode((w,h))
screen = pygame.display.set_mode((w,h), pygame.FULLSCREEN)
clock = pygame.time.Clock()
class Cube:
vertices=[(-1,1,-1),(1,1,-1),(1,-1,-1),(-1,-1,-1),(-1,1,1),(1,1,1),(1,-1,1),(-1,-1,1)]
edges= [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(3,7),(2,6)]
def __init__(self,pos=(0,0,0)):
x,y,z = pos
self.verts = [(x+X/2,y+Y/2,z+Z/2) for X,Y,Z in self.vertices]
cam = Cam((0,0,-5))
cubes_p = [(0,-10,0),(0,-10,1),(1,-10,0),(1,-10,1),(2,0,0),(2,0,1),(3,0,0),(3,0,1),(0,+10,0),(0,+10,1),(1,+10,0),(1,+10,1),(0,-11,-1),(0,-11,0),(1,-11,-1),(1,-11,0),(0,-12,-1),(0,-12,0),(1,-12,-1),(1,-12,0)]
cubes = [Cube(cubes_p[i])for i in range(0,len(cubes_p))]
pygame.event.get(); pygame.mouse.get_rel()
pygame.mouse.set_visible(0); pygame.event.set_grab(1)
ctime = time.time()-1
Colour = 0, 0, 0
while True:
key = pygame.key.get_pressed()
ptime = ctime
ctime = time.time()
fps = int(1/(ctime-ptime))
#dt = clock.tick()/1000
dt = (ctime-ptime)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
cam.events(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit(); sys.exit()
screen.fill((0,0,0))
for obj in cubes:
for edge in obj.edges:
points = []
disp = True
for x,y,z in (obj.verts[edge[0]],obj.verts[edge[1]]):
x-=cam.pos[0]
y-=cam.pos[1]
z-=cam.pos[2]
x,z = rotate2d((x,z),cam.rot[1])
y,z = rotate2d((y,z),cam.rot[0])
f = 400/z
x,y = x*f, y*f
if z <= 0:
disp = False
points+=[(cx+int(x),cy+int(y))]
if disp:
pygame.draw.line(screen,colour,points[0],points[1],1)
pygame.draw.line(screen,(200,200,200),(cx,cy-6),(cx,cy+6),1)
pygame.draw.line(screen,(200,200,200),(cx-6,cy),(cx+6,cy),1)
textsurface = myfont.render(str(fps)+ ' ' +str(round(cam.pos[0]))+ ',' +str(-(round(cam.pos[1]+2)))+ ',' +str(round(cam.pos[2])), 1, (255,255,255))
wid,hgt = textsurface.get_width(),textsurface.get_height()
screen.blit(textsurface,(w-wid,0))
pressed1, pressed2, pressed3 = pygame.mouse.get_pressed() #P1 = LC, P2 = MC, P3 = RC
if pressed1:
if (round(cam.pos[0]),round(cam.pos[1]+2),round(cam.pos[2])) in cubes_p:
del cubes_p[len(cubes_p)-1]
cubes_p.append((round(cam.pos[0]),round(cam.pos[1]+2),round(cam.pos[2])))
if key[pygame.K_RETURN]: cubes_p = []; cubes_p.append((0,0,0))
cubes = [Cube(cubes_p[i])for i in range(0,len(cubes_p))]
print(len(cubes))
if (len(cubes_p)) > 200:
del cubes_p[0]
pygame.display.flip()
key = pygame.key.get_pressed()
cam.update(dt,key)
#clock.tick(60)
很抱歉,如果这是一个巨大的代码块或一个糟糕的问题,我真的不知道该怎么做。 PS:我评论时非常糟糕,再次抱歉