Ошибка в pygame TypeError: argument 1 must be pygame.Surface, not pygame.Rect
Выдает такую ошибку:
D:\Рабочий стол\Flappy Floppa>python bird.py
pygame 2.1.2 (SDL 2.0.18, Python 3.10.2)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "D:\Рабочий стол\Flappy Floppa\bird.py", line 92, in <module>
window.blit(imgFON, fon)
TypeError: argument 1 must be pygame.Surface, not pygame.Rect
import pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
FPS = 60
window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
imgFON = pygame.image.load('images/fon.png')
imgBIRD = pygame.image.load('images/bird.png')
imgPB = pygame.image.load('images/PB.png')
imgPT = pygame.image.load('images/PT.png')
py, sy, ay = HEIGHT // 2, 0, 0
player = pygame.Rect(HEIGHT // 3, py, 50, 50)
state = 'start'
timer = 10
pipes = []
bges = []
bges.append(pygame.Rect(0, 0, 288, 512))
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
press = pygame.mouse.get_pressed()
keys = pygame.key.get_pressed()
click = press[0] or keys[pygame.K_SPACE]
if timer > 0:
timer -= 1
for i in range(len(bges)-1, -1, -1):
imgFON = bges[i]
imgFON.x -= 1
if imgFON.right < 0:
bges.remove(imgFON)
for i in range(len(pipes)-1, -1, -1):
pipe = pipes[i]
pipe.x -= 3
if pipe.right < 0:
pipes.remove(pipe)
if state == 'start':
if click and timer == 0 and len(pipes) == 0:
state = 'play'
py += (HEIGHT // 2 - py) * 0.1
player.y = py
elif state == 'play':
if click:
ay = -2
else:
ay = 0
py += sy
sy = (sy + ay + 1) * 0.98
player.y = py
if len(pipes) == 0 or pipes[len(pipes)-1].x < WIDTH - 200:
pipes.append(pygame.Rect(WIDTH, 0, 52, 200))
pipes.append(pygame.Rect(WIDTH, 400, 52, 200))
if player.top < 0 or player.bottom > HEIGHT:
state = 'fall'
for pipe in pipes:
if player.colliderect(pipe):
state = 'fall'
elif state == 'fall':
sy, ay = 0, 0
state = 'start'
timer = 60
else:
pass
window.fill(pygame.Color('black'))
for fon in bges:
window.blit(imgFON, fon)
for pipe in pipes:
if pipe.y == 0:
rect = imgPB.get_rect(bottomleft = pipe.bottomleft)
window.blit(imgPB, rect)
else:
rect = imgPT.get_rect(topleft = pipe.topleft)
window.blit(imgPT, rect)
window.blit(imgBIRD, player)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
UPD.
import pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
FPS = 60
window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
imgFON = pygame.image.load('images/fon.png')
imgBIRD = pygame.image.load('images/bird.png')
imgPB = pygame.image.load('images/PB.png')
imgPT = pygame.image.load('images/PT.png')
py, sy, ay = HEIGHT // 2, 0, 0
player = pygame.Rect(HEIGHT // 3, py, 50, 50)
state = 'start'
timer = 10
pipes = []
bges = []
bges.append(pygame.Surface(0, 0, 288, 512))
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
press = pygame.mouse.get_pressed()
keys = pygame.key.get_pressed()
click = press[0] or keys[pygame.K_SPACE]
if timer > 0:
timer -= 1
for fon in reversed(bges):
imgFON.x -= 1
if imgFON.right < 0:
bges.remove(imgFON)
for i in range(len(pipes)-1, -1, -1):
pipe = pipes[i]
pipe.x -= 3
if pipe.right < 0:
pipes.remove(pipe)
if state == 'start':
if click and timer == 0 and len(pipes) == 0:
state = 'play'
py += (HEIGHT // 2 - py) * 0.1
player.y = py
elif state == 'play':
if click:
ay = -2
else:
ay = 0
py += sy
sy = (sy + ay + 1) * 0.98
player.y = py
if len(pipes) == 0 or pipes[len(pipes)-1].x < WIDTH - 200:
pipes.append(pygame.Rect(WIDTH, 0, 52, 200))
pipes.append(pygame.Rect(WIDTH, 400, 52, 200))
if player.top < 0 or player.bottom > HEIGHT:
state = 'fall'
for pipe in pipes:
if player.colliderect(pipe):
state = 'fall'
elif state == 'fall':
sy, ay = 0, 0
state = 'start'
timer = 60
else:
pass
window.fill(pygame.Color('black'))
for fon in bges:
window.blit(imgFON, fon)
for pipe in pipes:
if pipe.y == 0:
rect = imgPB.get_rect(bottomleft = pipe.bottomleft)
window.blit(imgPB, rect)
else:
rect = imgPT.get_rect(topleft = pipe.topleft)
window.blit(imgPT, rect)
window.blit(imgBIRD, player)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
UPD. Еще один вариант исправления Дело было все в том что imgFON хранил в себе картинку, а после я пытался туда же сохранить bges[i], то есть в этой переменной уже хранилась картинка, а я пытался туда добавить еще список bges[], решение было лишь создать новую переменную, например fon. Если что то неправильно объяснил или не так назвал, извините, только учусь
for i in range(len(bges)-1, -1, -1):
imgFON = bges[i]
imgFON.x -= 1
UPD. Ниже прикрепляю рабочий код
import pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
FPS = 60
window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
imgBG = pygame.image.load('images/fon.png')
imgBIRD = pygame.image.load('images/bird.png')
imgPB = pygame.image.load('images/PB.png')
imgPT = pygame.image.load('images/PT.png')
py, sy, ay = HEIGHT // 2, 0, 0
player = pygame.Rect(HEIGHT // 3, py, 50, 50)
state = 'start'
timer = 10
pipes = []
bges = []
bges.append(pygame.Rect(0, 0, 288, 512))
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
press = pygame.mouse.get_pressed()
keys = pygame.key.get_pressed()
click = press[0] or keys[pygame.K_SPACE]
if timer > 0:
timer -= 1
for i in range(len(bges)-1, -1, -1):
fon = bges[i]
fon.x -= 1
if fon.right < 0:
bges.remove(fon)
for i in range(len(pipes)-1, -1, -1):
pipe = pipes[i]
pipe.x -= 3
if pipe.right < 0:
pipes.remove(pipe)
if state == 'start':
if click and timer == 0 and len(pipes) == 0:
state = 'play'
py += (HEIGHT // 2 - py) * 0.1
player.y = py
elif state == 'play':
if click:
ay = -2
else:
ay = 0
py += sy
sy = (sy + ay + 1) * 0.98
player.y = py
if len(pipes) == 0 or pipes[len(pipes)-1].x < WIDTH - 200:
pipes.append(pygame.Rect(WIDTH, 0, 52, 200))
pipes.append(pygame.Rect(WIDTH, 400, 52, 200))
if player.top < 0 or player.bottom > HEIGHT:
state = 'fall'
for pipe in pipes:
if player.colliderect(pipe):
state = 'fall'
elif state == 'fall':
sy, ay = 0, 0
state = 'start'
timer = 60
else:
pass
window.fill(pygame.Color('black'))
for fon in bges:
window.blit(imgBG, fon)
for pipe in pipes:
if pipe.y == 0:
rect = imgPB.get_rect(bottomleft = pipe.bottomleft)
window.blit(imgPB, rect)
else:
rect = imgPT.get_rect(topleft = pipe.topleft)
window.blit(imgPT, rect)
window.blit(imgBIRD, player)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
Ответы (1 шт):
Автор решения: gil9red
→ Ссылка
В window.blit(imgFON, fon) у вас imgFON является Rect, а не Surface
В одном из циклом вы переписываете переменную imgFON, помещая в нее Rect:
imgFON = pygame.image.load('images/fon.png')
...
bges = []
bges.append(pygame.Rect(0, 0, 288, 512))
...
for i in range(len(bges)-1, -1, -1):
imgFON = bges[i] # !!!
imgFON.x -= 1
if imgFON.right < 0:
bges.remove(imgFON)
...
for fon in bges:
window.blit(imgFON, fon)
UPD.
Обновил код в соответствии с рекомендациями выше:
import pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
FPS = 60
window = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
imgFON = pygame.image.load('images/fon.png')
imgBIRD = pygame.image.load('images/bird.png')
imgPB = pygame.image.load('images/PB.png')
imgPT = pygame.image.load('images/PT.png')
py, sy, ay = HEIGHT // 2, 0, 0
player = pygame.Rect(HEIGHT // 3, py, 50, 50)
state = 'start'
timer = 10
pipes = []
bges = []
bges.append(pygame.Rect(0, 0, 288, 512))
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT:
play = False
press = pygame.mouse.get_pressed()
keys = pygame.key.get_pressed()
click = press[0] or keys[pygame.K_SPACE]
if timer > 0:
timer -= 1
# !!!!!!!!!!!!!!!!!!!!!!!!
for fon in reversed(bges):
fon.x -= 1
if fon.right < 0:
bges.remove(fon)
# !!!!!!!!!!!!!!!!!!!!!!!!
for i in range(len(pipes)-1, -1, -1):
pipe = pipes[i]
pipe.x -= 3
if pipe.right < 0:
pipes.remove(pipe)
if state == 'start':
if click and timer == 0 and len(pipes) == 0:
state = 'play'
py += (HEIGHT // 2 - py) * 0.1
player.y = py
elif state == 'play':
if click:
ay = -2
else:
ay = 0
py += sy
sy = (sy + ay + 1) * 0.98
player.y = py
if len(pipes) == 0 or pipes[len(pipes)-1].x < WIDTH - 200:
pipes.append(pygame.Rect(WIDTH, 0, 52, 200))
pipes.append(pygame.Rect(WIDTH, 400, 52, 200))
if player.top < 0 or player.bottom > HEIGHT:
state = 'fall'
for pipe in pipes:
if player.colliderect(pipe):
state = 'fall'
elif state == 'fall':
sy, ay = 0, 0
state = 'start'
timer = 60
window.fill(pygame.Color('black'))
for fon in bges:
window.blit(imgFON, fon)
for pipe in pipes:
if pipe.y == 0:
rect = imgPB.get_rect(bottomleft = pipe.bottomleft)
window.blit(imgPB, rect)
else:
rect = imgPT.get_rect(topleft = pipe.topleft)
window.blit(imgPT, rect)
window.blit(imgBIRD, player)
pygame.display.update()
clock.tick(FPS)
pygame.quit()