我已经尽可能地从主循环中删除了所有内容。我还优化了动态和静态对象的碰撞,大大减少了迭代次数。但在他的机器上,它仍然很慢。我将发布整个文件,以防有人想测试它,但您可以跳转到"while Exit==false:“处的主循环。
import pygame
from pyeuclid import Vector2
from math import sin,cos,pi
from random import random
class Thing:
def __init__(self,pos):
self.pos = pos
things.append(self)
def update(self): pass
def draw(self,img): pass
def collide(self,who): pass
class DynamicThing(Thing):
def __init__(self,pos):
Thing.__init__(self,pos)
self.vel = Vector2(0,0)
self.lastPos = pos
self.col = (255,255,0)
self.r = 12
dynamic_things.append(self)
def update(self):
self.lastPos = self.pos
self.pos = self.pos + self.vel
def draw(self,img):
pygame.draw.circle(img, (0,0,0), [int(n) for n in self.pos], self.r, self.r)
pygame.draw.circle(img, self.col, [int(n) for n in self.pos], self.r-2, self.r-2)
def collide(self,obj):
Thing.collide(self,obj)
if isinstance(obj,Wall):
self.pos = self.lastPos
class Wall(Thing):
def draw(self,img):
x,y = self.pos.x, self.pos.y
pygame.draw.rect(img, (90,90,200), (x-16,y-16,32,32), 0)
class Pacman(DynamicThing):
def __init__(self):
DynamicThing.__init__(self,Vector2(32*9+16,32*12+16))
self.col = (255,255,0)
def update(self):
DynamicThing.update(self)
if (keyPressed[pygame.K_LEFT]): self.vel.x = -1
if (keyPressed[pygame.K_RIGHT]): self.vel.x = 1
if (keyPressed[pygame.K_DOWN]): self.vel.y = 1
if (keyPressed[pygame.K_UP]): self.vel.y = -1
if (self.vel.x==-1 and not keyPressed[pygame.K_LEFT]): self.vel.x = 0
if (self.vel.x==1 and not keyPressed[pygame.K_RIGHT]): self.vel.x = 0
if (self.vel.y==1 and not keyPressed[pygame.K_DOWN]): self.vel.y = 0
if (self.vel.y==-1 and not keyPressed[pygame.K_UP]): self.vel.y = 0
def collide(self,obj):
DynamicThing.collide(self,obj)
if isinstance(obj,Ghost):
self.pos = Vector2(32*9+16,32*12+16)
class Ghost(DynamicThing):
def __init__(self):
DynamicThing.__init__(self,Vector2(32*9+16,32*10+16))
self.col = (int(random()*255),int(random()*255),int(random()*255))
self.vel = Vector2(0,-2)
def update(self):
DynamicThing.update(self)
if random()<0.01:
self.vel = [Vector2(2,0),Vector2(-2,0),Vector2(0,2),Vector2(0,-2)][int(random()*4)]
def collide(self,obj):
DynamicThing.collide(self,obj)
if isinstance(obj,Wall):
self.vel = [Vector2(2,0),Vector2(-2,0),Vector2(0,2),Vector2(0,-2)][int(random()*4)]
def thingAtPos(pos):
tile_pos = Vector2(int(pos.x/32),int(pos.y/32))
return map[tile_pos.y][tile_pos.x]
# initializate stuff
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([32*19,32*22])
points_in_unit_circle_border = [Vector2(cos(float(a)/8*2*pi),sin(float(a)/8*2*pi)) for a in xrange(8)]
things = []
dynamic_things = []
exit = False
map = [[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1],
[1,0,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,0,1],
[1,0,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,1],
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1],
[1,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1],
[1,1,1,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1],
[1,1,1,1,0,1,0,1,1,0,1,1,0,1,0,1,1,1,1],
[1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1],
[1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,1],
[1,1,1,1,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1],
[1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,1],
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1],
[1,0,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,0,1],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1],
[1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1],
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1],
[1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]
#create pacman, walls, ghosts
pacman = Pacman()
for y in xrange(len(map)):
for x in xrange(len(map[y])):
if (map[y][x]==1):
map[y][x] = Wall(Vector2(x*32+16,y*32+16))
for i in xrange(4):
Ghost()
while exit==False:
clock.tick(45)
screen.fill([255,255,255])
keyPressed = pygame.key.get_pressed()
# events
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
exit = True
# more ghosts
if random()<0.001: Ghost()
# updates e draws
for thing in things:
thing.update()
thing.draw(screen)
# collisions
for A in dynamic_things:
#dynamic vs dynamic
for B in dynamic_things:
if A!=B and abs(A.pos-B.pos)<(A.r+B.r):
A.collide(B)
B.collide(A)
#dynamic vs walls
for circle_point in points_in_unit_circle_border:
thing_in_a_border = thingAtPos(A.pos+circle_point*12)
if isinstance(thing_in_a_border,Wall):
A.collide(thing_in_a_border)
pygame.display.flip()
pygame.quit ()
发布于 2012-05-04 16:14:16
在每个循环中,您都在重新绘制和翻转整个屏幕。我没有测试你的程序,但在吃豆人上我知道,屏幕上只有5个移动的精灵,你应该试着每一帧只对这些精灵进行blit (当然,如果其他事情发生了变化,也是这样)。不要使用display.flip(),只需更新您更改过的屏幕区域(这通常会大大提高速度)。
当然,你需要停止每一帧屏幕的空白,并且会有很多关于更新内容的管理。在pygame http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.DirtySprite中有一些额外的对脏精灵的支持,可以帮助你做到这一点。或者你可以更新所有的“活动”精灵,将它们所在的位置清空,然后在新的位置重新绘制它们(很明显,这两个区域中的所有内容也是如此)。将受影响的矩形收集到列表中,并将其传递给update_rects(),而不是翻转屏幕。没有必要在吃豆人游戏的每一帧中都画墙……
发布于 2012-04-30 18:50:51
可能不是很慢的原因,但是"while exit==False:“比"while not exit:”需要更多的字节码来执行。
https://stackoverflow.com/questions/10379102
复制