【问题标题】:How to get a pixel color outside of screen in pygame?如何在pygame中获得屏幕外的像素颜色?
【发布时间】:2023-03-31 04:06:01
【问题描述】:

我知道要在 Pygame 中获得像素颜色,我使用 get_at。 但是我需要在我的屏幕外部获得一个像素,即,我有一个图像已经被blitted,只有一部分可见。

例如,500,500 屏幕内的 1000x1000 图像将只有 50% 可见,其余部分将“关闭”屏幕。所以我需要访问屏幕外的部分。

但是,如果我引用get_at 的坐标大于或小于屏幕尺寸,Pygame 会因错误而停止:

IndexError: 像素索引超出范围

import pygame
W = 1600
H = 600
pygame.init()
screen = pygame.display.set_mode([W, H])
image = pygame.image.load('huge_background.png').convert_alpha()
screen.blit(image, [-5000, -420])
pygame.display.update()
screen.get_at([100, -5]) # generates "IndexError: pixel index out of range"

如何获取屏幕尺寸之外的背景图像像素颜色?


这是当前可见的 pygame 屏幕 (1600 x 600)。 3 行(洋红色)是碰撞“检测器”:

这是会滚动的背景 (8000 x 8000):

所以这里有一个场景的想法:

因此,碰撞检测器行可能会超出 pygame 屏幕限制,但需要“读取”外部像素以检测碰撞。

【问题讨论】:

  • 您无法访问screen 之外的像素,因为没有像素。屏幕只是一个具有窗口大小的表面。您可以访问在屏幕外闪烁的image 表面的像素。你能解释一下你为什么要这样做吗?你的实际目标是什么?
  • 我正在创建一个比赛程序,我的汽车需要检测前方是否有障碍物(例如,前方 500 像素)。汽车始终聚焦在屏幕上,并且背景图像(赛道)正在滚动。但根据汽车的位置,前方 500 像素将超出可见屏幕。但我知道背景图像有障碍或曲线。因此,即使当前没有显示这些像素,我也需要“读取”这些像素。
  • 好的,那么您可以访问背景图像/表面的像素并将当前偏移量添加到像素坐标。您仍然必须确保坐标在表面区域内以防止错误。是否只有一个大背景表面作为轨道?你使用像素颜色来检查它是障碍物还是道路?
  • 我在原帖中插入了一些图片和描述。
  • @skrx 知道如何解决这个问题吗?

标签: python python-3.x colors pygame pixel


【解决方案1】:

这是一个独立的示例,它在较大的背景上跟踪视图/相机的位置。

import pygame
W = 600
H = 400
pygame.init()
# generate repeated KEYDOWN events when a key is held
pygame.key.set_repeat(500, 50)  
screen = pygame.display.set_mode([W, H])

# image = pygame.image.load('huge_bkgnd.png').convert_alpha()

#create a large bkgnd image
bkgnd = pygame.Surface((W*10, H*10))
# draw a rainbow on the bkgnd surface
colours = ["red", "orange", "yellow", "green", "lightblue1", "blue", "purple"]
bar_width = bkgnd.get_width() // (10 * len(colours))
for x in range(0, bkgnd.get_width() // bar_width):
    rect = [x*bar_width, 0, bar_width, bkgnd.get_height()]
    bkgnd.fill(pygame.Color(colours[x % len(colours)]), rect)

position = [0, 0]
clock = pygame.time.Clock() #for limiting FPS
finished = False
while not finished:
    for event in pygame.event.get():
            if event.type == pygame.QUIT:
                finished = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    position[0] -= 100
                if event.key == pygame.K_RIGHT:
                    position[0] += 100
                if event.key == pygame.K_UP:
                    position[1] -= 100
                if event.key == pygame.K_DOWN:
                    position[1] += 100
                # for all key movement clamp position to size of background
                position[0] = max(0, min(position[0], bkgnd.get_width() - W))
                position[1] = max(0, min(position[1], bkgnd.get_height() - H))
                try:
                    x = position[0] + W*2  # just look at what's to the right
                    y = position[1]
                    print(f"At {position}: Heading for ({x},{y}) {bkgnd.get_at((x, y))}")
                except IndexError:
                    print(f"Heading for the edge! {bkgnd.get_width() - position[0]} to go!")
    # copy bkgnd to screen
    view_rect = (*position, W, H)
    screen.blit(bkgnd.subsurface(view_rect), (0,0))
    # update the screen
    pygame.display.update()
    clock.tick(60)  # limit FPS
pygame.quit()

忽略开头的 hacky 位以生成彩虹背景图像,因此水平移动很明显。

程序根据箭头键的按下移动位置。使用pygame.key.set_repeat() 允许按住箭头键。

在事件循环中有一些内部维护,以确保视图不能移动到背景边界之外。然后它打印远处一个像素的颜色。

处理完事件后,会根据当前位置将一部分背景绘制到屏幕上。

如果您需要任何说明,请告诉我。

【讨论】:

    猜你喜欢
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多