python - pygame surface.blit(bg,pos,pos) 对比。 surface.blit(bg,pos),你明白这个吗?

标签 python pygame blit

阅读 pygame 教程 here ,你会发现这个例子:(箭头是我的)

for o in objects:
    screen.blit(background, o.pos, o.pos) #<---
for o in objects:
    o.move()
    screen.blit(o.image, o.pos) #<---`

阅读 blit 的 pygame 文档 here会这样说:(斜体是我的)

blit(source, dest, area=None, special_flags = 0) -> Rect Draws a source Surface onto this Surface. The draw can be positioned with the dest argument. Dest can either be pair of coordinates representing the upper left corner of the source. A Rect can also be passed as the destination and the topleft corner of the rectangle will be used as the position for the blit. The size of the destination rectangle does not effect the blit.

谁能帮我理解这一点?我已经研究了自己的代码好几天了,最后我终于注意到在示例中他们在一个调用中使用了“pos”两次,在另一个调用中使用了一次。我把它扔给我的,瞧,令人难以置信的不同步、频闪、缓慢动画的问题消失了。但我不明白为什么。


编辑:上述误解只是速度瓶颈的一部分。我不明白(并且仍在努力)必须将其运动增量乘以时钟滴答。突然间,一切都变得生机勃勃。这是一个例子,也许会对其他勤奋的游戏新手有所帮助:

clock = pygame.time.Clock()
FPS=60        
while True:
    timer = clock.tick(FPS)
    if label.x < label.target_x:
        label.x += (2*timer) #<-----

.... Sprite /表面位置的增量是相对于 clock.tick 返回的数字而言的。突然之间,一台现代笔记本电脑可以让二十张图像以极快的速度在屏幕上移动:) 感谢泰德·克莱因·伯格曼的帮助!

最佳答案

文档中还有一行:

An optional area rectangle can be passed as well. This represents a smaller portion of the source Surface to draw.

第一个 for 循环中发生的情况是,他们通过在所有游戏对象之上绘制背景图像来清除以前的图像。背景图像可能比游戏对象大,因此每次我们对其进行 blit 时,我们都会绘制不需要重新绘制的屏幕部分。他们所做的是指定要绘制多少背景图像,这在这种情况下可以节省性能。

编辑: 命名 pos 可能会有点误导;它实际上是一个矩形。如果将矩形传递给第二个参数 (dest),则 blit 函数将使用左上角作为源的位置。不考虑矩形的实际面积。

如果将矩形传递给第三个参数(区域),则位图传输函数在位图传输源时将考虑矩形的面积。

我创建了一个小模型示例来展示 pygame 通常如何使用。您经常创建一个主循环来执行三件事:处理事件、更新对象和绘制对象。在你的例子中我看起来像这样:

import random
import pygame
pygame.init()

SIZE = WIDTH, HEIGHT = 800, 600
FPS = 60


class AnimatedWord:

    def __init__(self, image, position, target, speed=1):
        self.image    = image
        self.target   = image.get_rect().move(*target)
        self.position = image.get_rect().move(*position)
        self.speed    = speed

    def update(self):
        if self.position.y > self.target.y:
            self.position.y -= self.speed
        elif self.position.y < self.target.y:
            self.position.y += self.speed

        if self.position.x > self.target.x:
            self.position.x -= self.speed
        elif self.position.x < self.target.x:
            self.position.x += self.speed

    def draw(self, screen):
        screen.blit(self.image, self.position)


def create_word_surfaces(words, font_size=30, color=(106, 90, 205, 0)):
    font = pygame.font.SysFont("Arial", font_size)

    surfaces = []
    for word in words:
        surface = font.render(word, True, color)
        surfaces.append(surface)

    return surfaces


def main():
    screen = pygame.display.set_mode(SIZE)
    background = screen.copy()
    background.fill((0, 0, 0, 0))
    screen.blit(background, (0, 0))
    clock = pygame.time.Clock()

    words = "loading loading loading loading loading loading loading loading loading loading vectors monkey banana reishi argonaut oneironaut purgatory interstitium marmalade savanna chinchilla gobies loading loading leadbetter ".split(" ")

    targets_x = [i for i in range(0, screen.get_width(), 50)]
    targets_y = [i for i in range(0, screen.get_height(), 20)]

    animated_words = []
    for surface in create_word_surfaces(words):
        target_x = random.choice(targets_x)
        target_y = random.choice(targets_y)
        animated_word = AnimatedWord(surface, position=(400, 300), target=(target_x, target_y), speed=1)
        animated_words.append(animated_word)

    running = True
    while running:   # Main loop

        clock.tick(FPS)  # Limit the framerate to FPS

        # HANDLE EVENTS
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        # UPDATE GAME OBJECTS
        for x in animated_words:
            x.update()

        # DRAW GAME OBJECTS
        screen.blit(background, (0, 0))  # Fill entire screen.
        for x in animated_words:
            x.draw(screen)

        pygame.display.update()

if __name__ == '__main__':
    main()

关于python - pygame surface.blit(bg,pos,pos) 对比。 surface.blit(bg,pos),你明白这个吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49593042/

相关文章:

python - 没有 sudo 的语法错误

python pygame blit。获取要显示的图像

python - Pygame:位 block 传输移动背景会产生太多模糊

python - 反转 DataFrame 中的单个列

python - 从 View 中发出 websocket 消息

python - 在pygame中计算时间

python - Pygame:如何消除行星图像上出现的黑色光晕?

python - 为什么我的 Pygame Sprite 像碰撞盒一样旋转?

python - 在 django 中创建新用户给出的不是散列密码

xml - 我应该如何在 pygame 游戏中存储有关房间的信息?