在Pygame中更新一个表面

1 投票
2 回答
4802 浏览
提问于 2025-04-16 08:23

我有一个游戏,背景是由一些瓷砖组成的,有些是静态的(比如草地和泥土),但我想让水流动起来。我创建了一个叫做水的表面,然后我有一个循环,循环播放10个png图片,来显示水流动的帧。我想让这个水的表面更新的频率是游戏其他部分的10倍,并且以30帧每秒的速度把它和其他物体一起显示到主画面上。

但是我现在只能做到水要么不动,要么流动得非常快(因为我在水的更新循环中更新了整个显示)。

有没有办法只更新这个水的表面呢?

这是我的代码:

#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()

2 个回答

1

你的代码有点问题。一般的结构是这样的(简单来说就是:1个更新循环 - 1个绘制循环):

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()

你可以用绝对时间来决定使用哪个水的画面(比如说:water_images[int(now*10.0) % len(water_images)] 这样可以在水的动画中实现10帧每秒)。

2

看起来你想用 pygame.display.update 这个功能。你只需要把所有水块的矩形区域放到一个列表里,它就只会更新屏幕上这些部分。唯一需要注意的是,似乎这个功能不能和pygame.OPENGL显示一起使用。

不过,你真的确定要把水动画做成300帧每秒吗?感觉你可以直接告诉你的绘制方法当前的时间点,然后用这个来决定显示哪一帧。例如:

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

更好的做法是提前把所有的水块加载到一个列表里,然后使用

waterimg = watertiles[tick % 10]

并把你的图片编号从0到9,而不是1到10。

总之,希望这些对你有帮助(并且能正常工作)。

撰写回答