2013-10-08 4 views
-6

В моей игре есть генератор местности, впоследствии в результате чего во многих случаях .. но я реализовал код:Почему моя игра в 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. Структура ваш код так, что медленные вещи, как чтение из файлов произойдет РАЗ.
  2. Аналогично чтение ключей, событий и т. Д. не один раз для каждого блока.
  3. Помните следующее: если, если, если, если много операций, если Элиф Элиф Элиф заканчивается первым успехом но dict.get(), как правило, гораздо быстрее, так что ваш код может поиск действие для выполнения на нажмите клавишу и сделайте это - если действия были выполнены в функциях.
  4. Читайте о государственных двигателях и о том, как их использовать!
Смежные вопросы