当前位置: 首页 > 知识库问答 >
问题:

重载pyplay。为了动态地扩大表面的尺寸

张晔
2023-03-14

我正在尝试构建一个应用程序,它需要用户绘制一些东西。

为此,我创建了一个画布(一个pyplay。表面对象),画在上面注册,然后我把它粘在窗户上。我希望画布是无限的,这样当用户滚动时,他就可以继续绘图(当然,画布的一小部分被点击到窗口上)。但是,实际上,pyplay中的Surface需要有限的宽度和高度,最重要的是,它没那么大!(我想那是因为它实际上锁定了内存中的空间)。

所以,我尝试创建块:每个块都有固定的大小(比如,屏幕大小的两倍),每个块都分配了一个特定的表面。区块是按需以友好方式创建的,总体上运行良好。

我的问题是,当我试图画交叉到多个块上的线时,需要花费很大的努力来计算这条线实际上应该画在哪些块上,以及应该在哪些块上被打破。我甚至没有尝试画矩形,因为让“画线”函数工作真的很痛苦。

就在那时,我认为我所做的从根本上是错误的:与其试图重写所有的pygame.draw和pygame.gfxdraw函数,让它们基本上每块工作,我真的应该重载pyplay。Surface(例如,创建一个MySurface类Surface的子级),所以每当一个像素被修改时,我在内部选择它属于哪个块,并在该块上实际更改它,并将新的Surface对象传递给pyplay函数。

我在pygamedoc上搜索了很多,但没有解释如何做到这一点。我甚至不知道当我在表面对象上画画时,它的内部调用是什么方法!我也谷歌了一下,我没有发现有人试图做那种事情(也许我走错路了?)。

因此,我的问题是:这是正确的方法吗?如果是的话,我该如何认识到这一点?

我不发布代码,因为我需要的更多的是关于在哪里可以找到我试图做的文档的解释,而不是代码审查。

共有1个答案

鲍鸿波
2023-03-14

你不能只是子类Surface,因为它不是用python写的,而是用C写的;你自己找吧。

您可以采取另一种方法,而不是计算在哪里绘制东西,首先将其blight到一个临时的Surface上,并将其与块的位置相对应。

下面是我拼凑的一个简单例子:

 import pygame

class Chunk(pygame.sprite.Sprite):
    def __init__(self, grid_pos, size, color):
        super().__init__()
        self.image = pygame.Surface(size)
        self.rect = self.image.get_rect(
            x = grid_pos[0] * size[0],
            y = grid_pos[1] * size[1]
        )
        self.image.fill(pygame.Color(color))

    def patch(self, surface):
        self.image.blit(surface, (-self.rect.x, -self.rect.y))

def main():
    pygame.init()
    size = 800, 600
    screen = pygame.display.set_mode(size)
    chunks = pygame.sprite.Group(
        Chunk((0,0), size, 'green'),
        Chunk((1,0), size, 'red'),
        Chunk((0,1), size, 'blue'),
        Chunk((1,1), size, 'yellow')
    )
    dragging = None
    drawing = None
    tmp_s = pygame.Surface(size, pygame.SRCALPHA)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 3:
                    dragging = event.pos
                if event.button == 1:
                    drawing = event.pos

            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 3:
                    dragging = None
                if event.button == 1:
                    drawing = None
                    for chunk in chunks:
                        chunk.patch(tmp_s)

            if event.type == pygame.MOUSEMOTION:
                if dragging:
                    for chunk in chunks:
                        chunk.rect.move_ip(event.rel)

        screen.fill((0, 0, 0))
        chunks.draw(screen)

        tmp_s.fill((0,0,0,0))
        if drawing:
            size = pygame.Vector2(pygame.mouse.get_pos()) - drawing
            pygame.draw.rect(tmp_s, pygame.Color('white'), (*drawing, *size), 10)

        screen.blit(tmp_s, (0, 0))
        chunks.update()
        pygame.display.flip()

main()

如您所见,画布由4个块组成。使用鼠标右键移动画布,使用鼠标左键开始绘制矩形。

 类似资料:
  • 我有一个名为的python文件。我有一个特定的功能,我将把一部分,由于知道功能工作正常: 但是当我尝试函数的图像结果时,我得到一个声明必须是第一个参数,而不是。我做了一些测试,发现中的函数工作得很好,并且它正确地设置了。但是程序没有将其映射到对象。 这里是声明播放器对象和设置的地方: 在这里,我尝试将其显示在我的显示屏上(错误弹出的那行):

  • 问题内容: 在Python(2.7)中发现了从未有过的有趣的东西。 这个: 确实有效,结果是: 但 给 有人可以解释为什么吗?感谢您的回答。 问题答案: Python区分和运算符,并为它们提供了单独的挂钩。和。该类型只是为后者提供了不同的实现。 列表分别实现这些功能更为有效;必须返回一个全新的列表,而可以扩展然后返回。 在C代码中,是由所实现的,该只需调用,或者在python代码中,由。后者根据设

  • 通过作曲家安装Moltin Cart,然后添加服务提供商:并添加别名

  • 问题内容: 我正在为测试做练习,并且遇到了有关重载以及静态和动态绑定的练习。询问以下代码的输出: 我 认为 我获得了第一个,但在其他方面我完全迷失了。这是我解决第一个问题的方法: 在运行时,类型为,因此我们调用Curly的print方法。由于我们传递了要打印的类型的对象,因此在中运行了具有参数类型的相应打印方法。该方法的输出为,正确答案。 但是,当我将这种技术应用于以下几行时,我得到的答案是错误的

  • 我想我得到了第一个,但在其他方面我完全迷失了。我是这样解决第一个问题的: 在运行时,的类型是,所以我们调用curly的print方法。因为我们将类型的对象传递给print,所以相应的参数类型为的print方法在中运行。此方法的输出是,正确答案。 然而,当我将此技术应用到以下行时,我最终得到了错误的答案。有人能解释一下这个概念在Java中到底是如何工作的吗? 代码的正确输出是:

  • 我正在使用Ansible来设置EC2实例并部署一个应用程序。有一个hosts脚本,它收集标签、相关服务器和分组信息。我想把这些动作作为一个剧本来运行,所以 如果需要,将创建新实例 主机脚本加载清单(包括服务器的事实) 部署剧本有效 但我还没找到一个命令让它翻倍。