简体   繁体   中英

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 . 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. 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:

IndexError: pixel index out of range

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). The 3 lines (in magenta) are the collision "detectors":

在此处输入图片说明

And here is the background that will scroll (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.

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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