title: Why is my pygame game so slow?
body: <p>In my game there is a terrain generator, subsequently resulting in many instances.. but I implemented a code:</p>
  
  <pre><code>for b in blocklist:
      if b.rect.left&gt;=0:
         if b.rect.right&lt;=640:
            screen.blit(b.sprite, b.rect)
  </code></pre>
  
  <p>So that it only renders things within the scree (400-500) blocks, and it STILL runs as if it were rendering all 2000 or so. So what am I doing wrong? Does it have anything to do with</p>
  
  <pre><code>pygame.display.update() #or
  pygame.display.flip()
  </code></pre>
  
  <p>Is their even a difference?</p>
  
  <p>Here is the code:</p>
  
  <pre><code>   #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 &gt; 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 &gt; 0, we know our right side bumped 
                 # into the left side of a block etc.
                 if xvel &gt; 0:
                         self.rect.right = block.rect.left
                 if xvel &lt; 0:
                         self.rect.left = block.rect.right
  
                 # if yvel &gt; 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 &gt; 0:
                     self.rect.bottom = block.rect.top
                     self.on_ground = True
                     self.yvel = 0
                 # if yvel &lt; 0 and a collision occurs, we bumped our head
                 # on a block above us
                 if yvel &lt; 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) -&gt; 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 &lt;= 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&lt;9:
                                             select=select+1
                                     else:
                                             select=1
                             elif event.button==5:
                                     if select&gt;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&gt;=0:
                                 if b.rect.right&lt;=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&lt;1920:
                                             while down&gt;0:
                                                     screen.fill((0,0,0))
                                                     if blklvl==top:
                                                             blocklist.append(Block(across,blklvl,texdir+"\\grass.png",'block'))
                                                     if blklvl&gt;top:
                                                             if blklvl&lt;cen:
                                                                     blocklist.append(Block(across,blklvl,texdir+"\\dirt.png",'block'))
                                                     if blklvl&gt;cen-1:
                                                             blocklist.append(Block(across,blklvl,texdir+"\\stone.png",'block'))
                                                     down=down-1
                                                     blklvl=blklvl+32
  
                                             if down==0:
                                                     if across&lt;1920:
                                                             per=(across/(32/5))
                                                             if per&gt;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')
  </code></pre>
  
  <p>Any help will be greatly appreciated</p>