1

I have a game with a background made of tiles, some are static (grass, mud), but i want water to be flowing. i have created a surface called water, then i have a loop that iterates through a series of 10 pngs for the frames of the water flowing. i want to then update this surface 10x as often as the rest of the game, and blit it to the main surface at 30fps with the other objects.

However all i can achieve is no movement or the water flowing at insane speed(by updating the whole display in the water update loop.)

is there a way i can update just this surface?

here's my code:

#mud, grass and surface are defined earlier.
water = pygame.Surface((100,100))

            #create mud tiles
            for x in range(0,800,100):
                for y in range(0, 500, 100):
                    screen.blit(mud,(x,y))

            #create grass tiles
            for x in range(400, 800, 100):
                for y in range(0, 300, 100):
                    screen.blit(grass,(x,y))

            #create filenames
            for x in range(1,11):
                if x < 10:
                    filename = "images\water\water1000" + str(x) + ".png "
                else:
                    filename = "images\water\water100" + str(x) + ".png "
                waterimg = pygame.image.load(filename)

                #add to a surface, then tile the surface onto the game.
                water.blit(waterimg,(0,0))
                for x in range(100, 200, 100):
                    for y in range(0, 500, 100):
                        screen.blit(water, (x,y))
                        pygame.display.flip() #makes it update crazily. removing this line makes it not update at all.

            allsprites.draw(screen)
            pygame.display.flip()
lavelle
  • 1,446
  • 1
  • 17
  • 30

2 Answers2

2

It looks like you want to use pygame.display.update. Just pass it a list of all the water tiles' rects, and it will only update those parts of the screen. The only thing is that you can't use it with pygame.OPENGL displays, apparently.

However, are you sure you want to animate your water at 300fps? It seems like you should just tell your draw method what tick you're up to, and use that to figure out which frame to display. e.g.

def draw(tick, (whatever other arguments you have...):
    ... #draw mud and grass
    #the modulo operator % gets the remainder of the two numbers, so 12 % 10 = 2
    filename = "images\water\water1000" + str(tick % 10) + ".png"
    waterimg = pygame.image.load(filename)
    ... #blit the waterimg, but don't flip

Even better would be to load all your water tiles into a list before hand and use

waterimg = watertiles[tick % 10]

and number your images from 0-9 instead of 1-10.

Anyway, I hope this helps (and works).

Krendil
  • 113
  • 1
  • 3
  • seems pretty good, cheers accepted because even if i don't get it to work i now understand the concept a lot better. one question: how do i get the tick variable? I don't have a draw method, just an infinite loop: while 1: clock.tick(30) #handle inputs and draw everything – lavelle Dec 11 '10 at 15:19
  • To keep track of the tick, put tick = 0 before you enter the loop, and put tick+=1 after you call flip(). – Krendil Dec 11 '10 at 15:23
1

Your code is not right. The general schema is (simplified: 1 update loop - 1 draw loop):

load_all_images_needed()
itime = time.time()
while 1:  
   now = time.time()
   update(now, now - itime) # send absolute time and delta time
   itime = now
   draw()
   flip()

You can use the absolute time to decide which frame water to use (i.e: water_images[int(now*10.0) % len(water_images)] for 10fps in water sprite)

tokland
  • 66,169
  • 13
  • 144
  • 170