Я знаю, что для получения пикселя в Pygame я использую get_at
. Но мне нужно получить пиксель, который находится за пределами моего экрана, т.е. У меня есть изображение, уже имеющее видимую часть.
Например, изображение 1000x1000 внутри экрана 500 500 будет отображаться только на 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, но им необходимо "прочитать" внешние пиксели для обнаружения столкновения.
Вот отдельный пример, который отслеживает положение вида/камеры на большем фоне.
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 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()
Игнорируйте взломанный бит в начале, чтобы создать фоновое изображение радуги, поэтому горизонтальное движение очевидно.
Программа перемещает позицию на основе клавиш со стрелками. Используя pygame.key.set_repeat()
он позволяет удерживать клавиши со стрелками.
Там немного домашнего хозяйства в цикле событий, чтобы представление не могло перемещаться за пределы фона. Затем он печатает цвет пикселя на расстоянии.
После обработки событий на экран выводится раздел фона, основанный на текущей позиции.
Дайте мне знать, если вы хотите получить какие-либо разъяснения.
screen
, потому что их нет. Экран - это просто поверхность с размером окна. Вы можете получить доступ к пикселям поверхностиimage
которую вы бликаете за пределами экрана. Не могли бы вы объяснить, почему вы хотите это сделать? Какова ваша настоящая цель?