重载 pygame.Surface,以动态增加曲面的大小。

我正试图建立一个需要用户绘制一些东西的应用程序。

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

所以,我试着创建了 块状每一个chunk都有固定的大小(比如,屏幕大小的两倍),并且给每个chunk分配一个特定的Surface。分块是按需创建的,总的来说效果很好。

我的问题是,当我试图绘制交叉到多个块上的线条时,需要花很大的力气来计算该线条到底应该绘制到哪个块上,以及应该在哪个块上被破坏。我甚至没有尝试绘制矩形,因为它 真的 的 “draw-a-line “函数的工作很麻烦。

这时我觉得我所做的事情从根本上来说是错误的:与其试图重写所有的pygame.draw和pygame.gfxdraw函数,让它们基本上做一个每块的工作,不如真正重载pygame.Surface(比如说,创建一个MySurface类的Surface子类),这样每当一个像素被修改时,我就在内部选择它属于哪个块,并实际在该块上进行修改,然后把这个新的Surface对象传递给pygame函数。

我搜索了很多在 pygame文档但那里没有解释如何做到这一点。我甚至不知道当我在Surface对象上blitdraw时,内部调用了哪些方法!我也在google上搜索了一下,没有发现有人在尝试做这种事情(也许我走错了路?我也在谷歌上搜索了一下,并没有发现有人在尝试做这种事情(也许我走错了路?)。

所以,我的问题是:这是正确的方法吗?如果是,我应该如何实现?

我不发代码,因为我需要的更多的是解释在哪里可以找到我试图做什么的doc,而不是代码审查。

解决方案:

你不能只是子类 Surface因为它不是用python写的,而是用C语言写的。下面是源代码;你自己看吧。

你可以采取另一种方法,而不是计算在哪里画的东西,blit到一个临时的。Surface 首先,将其blit到相对于chunk的位置的chunks上。

下面是我黑进的简单例子。

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

enter image description here

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

给TA打赏
共{{data.count}}人
人已打赏
未分类

Primefaces <p:outputPanel>或<div>.我应该用什么来做响应式?

2022-9-9 1:50:19

未分类

谷歌应用脚本。类型错误:未定义不是一个函数

2022-9-9 1:50:21

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索