2013-10-08 132 views
-6

在我的比赛有一个地形生成,随后导致在许多情况下..但我实现了一个代码:STILL为什么我的pygame游戏如此缓慢?

for b in blocklist: 
    if b.rect.left>=0: 
     if b.rect.right<=640: 
      screen.blit(b.sprite, b.rect) 

,使其只呈现卵石(400-500)块内的事情,它像2000年左右渲染一样运行。那么我做错了什么?它与

pygame.display.update() #or 
pygame.display.flip() 

他们甚至有区别吗?

下面是代码:

#Init stuff 
    import pygame,random 
    from pygame.locals import * 
    from collections import namedtuple 
    import time, string 
    pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=500) 
    f=open('texdir.txt','r') 
    texdir=f.read() 
    f.close() 
    f=open(texdir+"\\splash.txt",'r') 
    splash=f.read() 
    splash=splash.replace('(','') 
    splash=splash.replace(')','') 
    splash=splash.split(',') 
    f.close() 
    splashlen=len(splash) 
    chc=random.randint(0,int(splashlen)) 
    splash=splash[chc-1] 
    f=open(texdir+"//backcolor.txt") 
    pygame.init() 
    clock=pygame.time.Clock() 
    screen=pygame.display.set_mode((640,480)) 
    pygame.display.set_caption("PiBlocks | By Sam Tubb") 
    max_gravity = 100 
    blocksel=texdir+"\\dirt.png" 
    btype='block' 
    backimg = pygame.image.load(texdir+"\\menu.png").convert() 
    backimg = pygame.transform.scale(backimg, (640,480)) 
    clsimg = pygame.image.load("clear.bmp").convert() 
    clsimg = pygame.transform.scale(clsimg, (640,480)) 
    ingame=0 
    sbtn=pygame.image.load("startbtn.png").convert() 
    qbtn=pygame.image.load("quitbtn.png").convert() 
    tbtn=pygame.image.load("texbtn.png").convert() 
    sbtnrect=sbtn.get_rect() 
    sbtnrect.x=220 
    sbtnrect.y=190 
    qbtnrect=qbtn.get_rect() 
    qbtnrect.x=220 
    qbtnrect.y=225 
    tbtnrect=tbtn.get_rect() 
    tbtnrect.x=220 
    tbtnrect.y=260 
    go=0 
    gotime=35 
    select=1 
    colliding = False 
    Move = namedtuple('Move', ['up', 'left', 'right']) 
    player=[] 
    blocklist=[] 
    font=pygame.font.Font(None,18) 

    #set cursor 
    curs = pygame.image.load(texdir+"\\cursor.png").convert() 
    curs.set_colorkey((0,255,0)) 

    #set backcolor 
    COLOR=f.read() 
    f.close() 
    COLOR=COLOR.replace('(','') 
    COLOR=COLOR.replace(')','') 
    COLOR=COLOR.split(',') 
    c1=COLOR[0] 
    c2=COLOR[1] 
    c3=COLOR[2] 

    #load sounds 
    place=pygame.mixer.Sound('sound\\place.wav') 
    place2=pygame.mixer.Sound('sound\\place2.wav') 
    place3=pygame.mixer.Sound('sound\\place3.wav') 

    #set sprites and animation frames 
    psprite = pygame.image.load(texdir+"\\player\\playr.png").convert() 
    psprite.set_colorkey((0,255,0)) 
    psprite2 = pygame.image.load(texdir+"\\player\\playr2.png").convert() 
    psprite2.set_colorkey((0,255,0)) 
    psprite3 = pygame.image.load(texdir+"\\player\\playr3.png").convert() 
    psprite3.set_colorkey((0,255,0)) 
    anim=1 
    class Block(object): 
      def __init__(self,x,y,sprite,btype): 
        if blocksel==texdir+"\\woodslab.png": 
          self.btype='slab' 
          self.sprite = pygame.image.load(sprite).convert() 
          self.rect = self.sprite.get_rect(top=y+16, left=x) 
        else: 
          self.btype='block' 
          self.sprite = pygame.image.load(sprite).convert_alpha() 
          self.rect = self.sprite.get_rect(top=y, left=x) 


    class Player(object): 
     sprite=psprite 
     def __init__(self, x, y): 
      self.rect = self.sprite.get_rect(centery=y, centerx=x) 
      # indicates that we are standing on the ground 
      # and thus are "allowed" to jump 
      self.on_ground = True 
      self.xvel = 0 
      self.yvel = 0 
      self.jump_speed = 7 
      self.move_speed = 3 

     def update(self, move, blocks): 

      # check if we can jump 
      if move.up and self.on_ground: 
       self.yvel -= self.jump_speed 

      # simple left/right movement 
      if move.left: 
        self.xvel = -self.move_speed 
      if move.right: 
        self.xvel = self.move_speed 

      # if in the air, fall down 
      if not self.on_ground: 
       self.yvel += 0.3 
       # but not too fast 
       if self.yvel > max_gravity: self.yvel = max_gravity 

      # if no left/right movement, x speed is 0, of course 
      if not (move.left or move.right): 
       self.xvel = 0 

      # move horizontal, and check for horizontal collisions 
      self.rect.left += self.xvel 
      self.collide(self.xvel, 0, blocks) 

      # move vertically, and check for vertical collisions 
      self.rect.top += self.yvel 
      self.on_ground = False; 
      self.collide(0, self.yvel, blocks) 

     def collide(self, xvel, yvel, blocks): 
      # all blocks that we collide with 
      for block in [blocks[i] for i in self.rect.collidelistall(blocks)]: 

       # if xvel is > 0, we know our right side bumped 
       # into the left side of a block etc. 
       if xvel > 0: 
         self.rect.right = block.rect.left 
       if xvel < 0: 
         self.rect.left = block.rect.right 

       # if yvel > 0, we are falling, so if a collision happpens 
       # we know we hit the ground (remember, we seperated checking for 
       # horizontal and vertical collision, so if yvel != 0, xvel is 0) 
       if yvel > 0: 
        self.rect.bottom = block.rect.top 
        self.on_ground = True 
        self.yvel = 0 
       # if yvel < 0 and a collision occurs, we bumped our head 
       # on a block above us 
       if yvel < 0: self.rect.top = block.rect.bottom 

    def get_key(): 
    while 1: 
     event = pygame.event.poll() 
     if event.type == KEYDOWN: 
     return event.key 
     else: 
     pass 

    def display_box(screen, message): 
    "Print a message in a box in the middle of the screen" 
    fontobject = pygame.font.Font(None,18) 
    pygame.draw.rect(screen, (0,0,0), 
         ((screen.get_width()/2) - 100, 
         (screen.get_height()/2) - 10, 
         200,20), 0) 
    pygame.draw.rect(screen, (255,255,255), 
         ((screen.get_width()/2) - 102, 
         (screen.get_height()/2) - 12, 
         204,24), 1) 
    if len(message) != 0: 
     screen.blit(fontobject.render(message, 1, (255,255,255)), 
        ((screen.get_width()/2) - 100, (screen.get_height()/2) - 10)) 
    pygame.display.flip() 

    def ask(screen, question): 
    "ask(screen, question) -> answer" 
    pygame.font.init() 
    current_string = [] 
    display_box(screen, question + ": " + string.join(current_string,"")) 
    while 1: 
     inkey = get_key() 
     if inkey == K_BACKSPACE: 
     current_string = current_string[0:-1] 
     elif inkey == K_RETURN: 
     break 
     elif inkey == K_MINUS: 
     current_string.append("_") 
     elif inkey <= 127: 
     current_string.append(chr(inkey)) 
     display_box(screen, question + ": " + string.join(current_string,"")) 
    return string.join(current_string,"") 
    while True: 
      for block in blocklist: 
        if any(block.rect.colliderect(b.rect) for b in blocklist if b is not block): 
          if b.btype=='slab': 
            blocklist.remove(block) 
          else: 
            blocklist.remove(b) 
      if ingame==1: 
       screen.fill((int(c1),int(c2),int(c3))) 
       mse = pygame.mouse.get_pos() 
       key = pygame.key.get_pressed() 
       if key[K_a]: 
         anim+=1 
         if anim==9: 
           anim=1 
       if key[K_d]: 
         anim+=1 
         if anim==9: 
           anim=1 
       if key[K_1]: 
        blocksel=texdir+"\\dirt.png" 
        btype='block' 
        select=1 
       if key[K_2]: 
        blocksel=texdir+"\\stonetile.png" 
        btype='block' 
        select=2 
       if key[K_3]: 
        blocksel=texdir+"\\stone.png" 
        btype='block' 
        select=3 
       if key[K_4]: 
        blocksel=texdir+"\\sand.png" 
        btype='block' 
        select=4 
       if key[K_5]: 
        blocksel=texdir+"\\woodplank.png" 
        btype='block' 
        select=5 
       if key[K_6]: 
        blocksel=texdir+"\\woodslab.png" 
        btype='slab' 
        select=6 
       if key[K_LEFT]: 
        try: 
          for b in blocklist: 
           b.rect.left+=32 
        except: 
          pass 
        try: 
          player.rect.left+=32 
        except: 
          pass 
       if key[K_RIGHT]: 
         try: 
          for b in blocklist: 
           b.rect.left-=32 
         except: 
           pass 
         try: 
          player.rect.left-=32 
         except: 
           pass 
       if key[K_UP]: 
         try: 
          for b in blocklist: 
           b.rect.top+=32 
         except: 
           pass 
         try: 
          player.rect.top+=32 
         except: 
           pass 
       if key[K_DOWN]: 
         try: 
          for b in blocklist: 
           b.rect.top-=32 
         except: 
           pass 
         try: 
          player.rect.top-=32 
         except: 
           pass 
       if key[K_ESCAPE]: 
        execfile('PiBlocks.pyw') 
       for event in pygame.event.get(): 
        if event.type == QUIT: 
         exit() 
        if event.type == MOUSEBUTTONDOWN: 
          if event.button==4: 
            if select<9: 
              select=select+1 
            else: 
              select=1 
          elif event.button==5: 
            if select>1: 
              select=select-1 
            else: 
              select=9 
          if select==1: 
            blocksel=texdir+"\\dirt.png" 
            btype='block' 
          if select==2: 
            blocksel=texdir+"\\stonetile.png" 
            btype='block' 
          if select==3: 
            blocksel=texdir+"\\stone.png" 
            btype='block' 
          if select==4: 
            blocksel=texdir+"\\sand.png" 
            btype='block' 
          if select==5: 
            blocksel=texdir+"\\woodplank.png" 
            btype='block' 
          if select==6: 
            blocksel=texdir+"\\woodslab.png" 
            btype='slab' 


        if key[K_LSHIFT]: 
         if event.type==MOUSEMOTION: 
          if not any(block.rect.collidepoint(mse) for block in blocklist): 
           snd=random.randint(1,3) 
           x=(int(mse[0])/32)*32 
           y=(int(mse[1])/32)*32 
           if go==1: 
              if snd==1: 
               place.play() 
              elif snd==2: 
               place2.play() 
              elif snd==3: 
               place3.play() 
              blocklist.append(Block(x,y,blocksel,btype)) 
        if key[K_RSHIFT]: 
         if event.type==MOUSEMOTION: 
          to_remove = [b for b in blocklist if b.rect.collidepoint(mse)] 
          for b in to_remove: 
            if go==1: 
              blocklist.remove(b) 
        else: 
         if event.type == pygame.MOUSEBUTTONUP: 
          if event.button == 1: 
           to_remove = [b for b in blocklist if b.rect.collidepoint(mse)] 
           for b in to_remove: 
            if go==1: 
              blocklist.remove(b) 

           if not to_remove: 
            snd=random.randint(1,3) 
            x=(int(mse[0])/32)*32 
            y=(int(mse[1])/32)*32 
            if go==1: 
              if snd==1: 
               place.play() 
              elif snd==2: 
               place2.play() 
              elif snd==3: 
               place3.play() 
              blocklist.append(Block(x,y,blocksel,btype)) 

          elif event.button == 3: 
           x=(int(mse[0])/32)*32 
           y=(int(mse[1])/32)*32 
           player=Player(x+16,y+16) 

       move = Move(key[K_w], key[K_a], key[K_d]) 

       for b in blocklist: 
         if b.rect.left>=0: 
           if b.rect.right<=640: 
             screen.blit(b.sprite, b.rect) 

       if player: 
        player.update(move, blocklist) 
        if anim==1 or anim==2 or anim==3: 
          screen.blit(psprite, player.rect) 
        elif anim==4 or anim==5 or anim==6: 
          screen.blit(psprite2, player.rect) 
        elif anim==7 or anim==8 or anim==9: 
          screen.blit(psprite3, player.rect) 
       x=(int(mse[0])/32)*32 
       y=(int(mse[1])/32)*32 
       screen.blit(curs,(x,y)) 
       clock.tick(60) 
       x=blocksel.replace(texdir,'') 
       x=x.replace('.png','') 
       vers=font.render('PiBlocks Alpha 0.6',True,(255,255,255)) 
       tex=font.render('Selected Texture Pack: '+texdir,True,(255,255,255)) 
       words=font.render('Selected Block: '+str(x), True, (255,255,255)) 
       screen.blit(vers,(1,1)) 
       screen.blit(tex,(1,12)) 
       screen.blit(words,(1,25)) 
       if gotime==0: 
         go=1 
       else: 
         gotime-=1 
       pygame.display.update() 
      elif ingame==0: 
        blocklist=[] 
        mse = pygame.mouse.get_pos() 
        player=[] 
        key = pygame.key.get_pressed() 
        text=font.render(splash, True, (255,255,255)) 
        if key[K_RETURN]: 
          ingame=1 
        for event in pygame.event.get(): 
          if event.type == QUIT: 
           exit() 
          if event.type == KEYDOWN: 
            print event.key 
        if sbtnrect.collidepoint(mse): 
          if pygame.mouse.get_pressed()==(1,0,0): 
            ingame='gen' 
            top=(random.randint(5,8)*32) 
            cen=(top+random.randint(4,6)*32) 
            down=15 
            across=0 
            blklvl=0 
            while across<1920: 
              while down>0: 
                screen.fill((0,0,0)) 
                if blklvl==top: 
                  blocklist.append(Block(across,blklvl,texdir+"\\grass.png",'block')) 
                if blklvl>top: 
                  if blklvl<cen: 
                    blocklist.append(Block(across,blklvl,texdir+"\\dirt.png",'block')) 
                if blklvl>cen-1: 
                  blocklist.append(Block(across,blklvl,texdir+"\\stone.png",'block')) 
                down=down-1 
                blklvl=blklvl+32 

              if down==0: 
                if across<1920: 
                  per=(across/(32/5)) 
                  if per>100: 
                    per=100 
                  top=(random.randint(5,8)*32) 
                  cen=(top+random.randint(4,6)*32) 
                  down=15 
                  blklvl=0 
                  across=across+32 
                  down=15 
                  drawgen=font.render('GENERATION:'+str(per)+'%%', True, (255,255,255)) 
                  screen.blit(drawgen,(1,1)) 
                  pygame.display.flip() 
              go=0 
              ingame=1 

        if qbtnrect.collidepoint(mse): 
          if pygame.mouse.get_pressed()==(1,0,0): 
            exit() 
        if tbtnrect.collidepoint(mse): 
          if pygame.mouse.get_pressed()==(1,0,0): 
            ingame='texsel' 
        screen.blit(backimg,(0,0)) 
        screen.blit(text,(364,76)) 
        screen.blit(sbtn,sbtnrect) 
        screen.blit(qbtn,qbtnrect) 
        screen.blit(tbtn,tbtnrect) 
        pygame.display.flip() 
      elif ingame=='texsel': 
        screen.blit(clsimg,(0,0)) 
        inp = ask(screen, 'Texture Directory') 
        f=open('texdir.txt','w') 
        f.write(str(inp)) 
        f.close() 
        pygame.display.flip() 
        execfile('PiBlocks.pyw') 

任何帮助,将不胜感激

+1

你的配置文件告诉你什么时候运行它? – geoffspear

+2

请问您可以投资一些*您的*时间来详细说明这个问题,最多可以将其降至10-20行代码?这个问题意味着“请为我调试这个庞大的代码体”。投票关闭 – J0HN

+1

这个问题似乎是脱离主题,因为它属于http://codereview.stackexchange.com/ – FallenAngel

回答

8

的代码运行缓慢,因为它是非结构化的码堆(这的清理版本)是不断加载外部资源,阅读事件和鼠标数据。

  1. 结构代码,以便就像从文件中读取慢的事情发生ONCE
  2. 同样的阅读键,事件等不是每块一次。
  3. 记住以下几点:如果,如果,如果,如果是很多操作,如果elif的elif的elif的第一个成功 dict.get(结束)通常快得多让你的代码可以查找要执行的操作上一个关键的新闻和做它 - 如果行动是在功能上执行。
  4. 阅读关于状态引擎以及如何使用它们!
相关问题