简体   繁体   English

pygame中如何在屏幕外获得像素颜色?

[英]How to get a pixel color outside of screen in pygame?

I know that to get a pixel color in Pygame I use get_at . 我知道要在Pygame中获得像素颜色,请使用get_at But I need to get a pixel that is outside my screen, ie, I have an image already blitted with just a portion visible. 但是我需要获得一个位于屏幕的像素,即,我的图像已经发白,只有一部分可见。

For example, a 1000x1000 image inside a 500,500 screen will only have 50% visible, the rest will be "off" the screen. 例如,在500,500屏幕内的1000x1000图像将仅具有50%的可见度,其余图像将“关闭”屏幕。 So I need to access the portion off the screen. 因此,我需要访问屏幕之外的部分。

But if I reference get_at with a coordinate greater or less then the screen dimensions, Pygame stops with an error: 但是,如果我使用大于或小于屏幕尺寸的坐标来引用get_at ,则Pygame会因错误而停止:

IndexError: pixel index out of range 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"

How can I get the background image pixel color outside the screen dimensions? 如何获得屏幕尺寸之外的背景图像像素颜色?


Here is the currently visible pygame screen (1600 x 600). 这是当前可见的pygame屏幕(1600 x 600)。 The 3 lines (in magenta) are the collision "detectors": 3行(洋红色)是碰撞“检测器”:

在此处输入图片说明

And here is the background that will scroll (8000 x 8000): 这是将滚动(8000 x 8000)的背景:

在此处输入图片说明

So here is an idea of the scenario: 因此,这是该方案的概念: 在此处输入图片说明

So, the collision detector lines might exceed the pygame screen limits but need to "read" the outside pixels to detect the collision. 因此,碰撞检测器行可能会超出pygame屏幕的限制,但需要“读取”外部像素以检测碰撞。

Here's a stand-alone example that tracks the position of the view/camera on a larger background. 这是一个独立的示例,可在较大背景上跟踪视图/相机的位置。

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

Ignore the hacky-bit at the start to generate a rainbow background image so horizontal movement is obvious. 一开始就忽略hacky位,生成彩虹背景图像,因此水平运动是显而易见的。

The program moves the position based on arrow key presses. 程序基于箭头键移动位置。 Using pygame.key.set_repeat() it allows for the arrow keys to be held down. 使用pygame.key.set_repeat()可以按住箭头键。

There's a little bit of house-keeping in the event loop to ensure the view can't move outside the boundary of the background. 事件循环中有一些整理工作,以确保视图不会移出背景边界。 Then it prints the colour of a pixel in the distance. 然后,它打印远处像素的颜色。

After the events are processed, a section of the background is drawn to the screen, based on the current position. 处理事件后,根据当前位置将背景的一部分绘制到屏幕上。

Let me know if you'd like any clarification. 让我知道您是否需要任何澄清。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM