Проблема отображения изображения в игре на Python
Пишу игру на Python. Писать на данном языке программирования начал относительно недавно, поэтому не особо разбираюсь во всех мелочах. Просьба особо не критиковать. Проверил код пару раз. Ошибок в коде не выявил. При запуске кода открывает окно с черным экраном.
import pygame
import random
import sys
# Задаем цвета
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 30
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, img='player.png'):
super().__init__()
self.image = pygame.image.load(img).convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.change_x = 0
self.change_y = 0
self.walls = None
self.couns = None
self.collected_coins = 0
self.enemies = pygame.sprite.Group()
self.alive = True
def update(self):
self.rect.x += self.change_x
block_hit_list = pygame.sprite.Spritecollide(self, self.walls, False)
for block in block_hit_list:
if self.change_x > 0:
self.rect.right = block.rect.left
else:
self.rect.left = block.rect.right
self.rect.y += self.change_y
block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
if self.change_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.botttom
coins_hit_list = pygame.sprite.spritecollide(self, self.coins, False)
for coin in coins_hit_list:
self.collected_coins += 1
coin.kill()
if pygame.sprite.spritecollideany(self, self.enemies, False):
self.alive = False
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
class Coin(pygame.sprite.Sprite):
def __init__(self, x, y, img='coin.png'):
super().__init__()
self.image = pygame.image.load(img).convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, img='crocodile1.png'):
super().__init__()
self.image = pygame.image.load(img).convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.start = x
self.stop = x + random.randint(180, 240)
self.direction = 1
def update(self):
if self.rect.x >= self.stop:
self.rect.x = self.stop
self.direction = -1
if self.rect.x <= self.start:
self.rect.x = self.startself.direction = 1
self.rect.x += self.direction * 2
pygame.init()
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption('Ainel')
all_sprite_list = pygame.sprite.Group()
wall_list = pygame.sprite.Group()
wall_coords = [
[0, 0, 10, 600],
[790, 0, 10, 600],
[10, 0, 790, 10],
[0, 200, 100, 10],
[0, 590, 600, 10],
[450, 400, 10, 200],
[550, 450, 250, 10]
]
for coord in wall_coords:
wall = Wall(coord[0], coord[1], coord[2], coord[3])
wall_list.add(wall)
all_sprite_list.add(wall)
coins_list = pygame.sprite.Group()
coins_coord = [[100, 140], [236, 50], [400, 234]]
for coord in coins_coord:
coin = Coin(coord[0], coord[1])
coins_list.add(coin)
all_sprite_list.add(coin)
enemies_list = pygame.sprite.Group()
enemies_coord = [[10, 500], [400, 50]]
for coord in enemies_coord:
enemy = Enemy(coord[0], coord[1])
enemies_list.add(enemy)
all_sprite_list.add(enemy)
player = Player(50, 50)
player.walls = wall_list
all_sprite_list.add(player)
player.coins = coins_list
player.enemies = enemies_list
font = pygame.font.SysFont('Arial', 24, True)
text = font.render('GAME OVER', True, WHITE)
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.change_x = -3
elif event.key == pygame.K_RIGHT:
player.change_x = 3
elif event.key == pygame.K_UP:
player.change_y = -3
elif event.key == pygame.K_DOWN:
player.change_y = 3
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
player.change_x = 0
elif event.key == pygame.K_RIGHT:
player.change_x
elif event.key == pygame.K_UP:
player.change_y = 0
elif event.key == pygame.K_DOWN:
player.change_y = 0
screen.fill(RED)
Ответы (2 шт):
Автор решения: Никита Крылов
→ Ссылка
Метод screen.fill должен вызываться каждый кадр перед обновлением экрана.
Измените конец главного цикла while:
while not done:
...
screen.fill(RED)
pygame.display.update()
clock.tick(60) # количество кадров
Автор решения: Sertefer
→ Ссылка
В итоге я смог разобраться с проблемой и сделать небольшую игру поэтому уже рабочий код вместе с игрой оставляю ниже
import pygame
from pygame.locals import (
RLEACCEL,
)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WIDTH = 1000
HEIGHT = 800
class Vstaf(pygame.sprite.Sprite):
def __init__(self):
self.rect = pygame.Rect(0, 0, 200, 50)
super(Vstaf, self).__init__()
self.surf = pygame.image.load("iy.jpg").convert()
self.rect = self.surf.get_rect()
self.rect.center = (WIDTH / 1.1, HEIGHT / 6.2)
class Vstao(pygame.sprite.Sprite):
def __init__(self):
self.rect = pygame.Rect(0, 0, 200, 50)
super(Vstao, self).__init__()
self.surf = pygame.image.load("hy.jpg").convert()
self.rect = self.surf.get_rect()
self.rect.center = (WIDTH / 1.15, HEIGHT / 1.4)
class Vstat(pygame.sprite.Sprite):
def __init__(self):
self.rect = pygame.Rect(0, 0, 200, 50)
super(Vstat, self).__init__()
self.surf = pygame.image.load("by.jpg").convert()
self.rect = self.surf.get_rect()
self.rect.center = (WIDTH / 10, HEIGHT / 10.9)
class Vstae(pygame.sprite.Sprite):
def __init__(self):
self.rect = pygame.Rect(0, 0, 200, 50)
super(Vstae, self).__init__()
self.surf = pygame.image.load("ly.jpg").convert()
self.rect = self.surf.get_rect()
self.rect.center = (WIDTH / 10, HEIGHT / 2.3)
class Vstav(pygame.sprite.Sprite):
def __init__(self):
self.rect = pygame.Rect(0, 0, 200, 50)
super(Vstav, self).__init__()
self.surf = pygame.image.load("ky.jpg").convert()
self.rect = self.surf.get_rect()
self.rect.center = (WIDTH / 10, HEIGHT / 1.4)
class Player(pygame.sprite.Sprite):
def __init__(self):
self.rect = pygame.Rect(0, 0, 200, 50)
super(Player, self).__init__()
self.surf = pygame.image.load("player.png").convert()
self.surf.set_colorkey((255, 255, 255), RLEACCEL)
self.rect = self.surf.get_rect()
self.rect.center = (WIDTH / 40, HEIGHT / 33)
def move(self, dx, dy):
# Move each axis separately. Note that this checks for collisions both times.
if dx != 0:
self.move_single_axis(dx, 0)
if dy != 0:
self.move_single_axis(0, dy)
def move_single_axis(self, dx, dy):
# Move the rect
self.rect.x += dx
self.rect.y += dy
# If you collide with a wall, move out based on velocity
for wall in walls:
if self.rect.colliderect(wall.rect):
if dx > 0: # Moving right; Hit the left side of the wall
self.rect.right = wall.rect.left
if dx < 0: # Moving left; Hit the right side of the wall
self.rect.left = wall.rect.right
if dy > 0: # Moving down; Hit the top side of the wall
self.rect.bottom = wall.rect.top
if dy < 0: # Moving up; Hit the bottom side of the wall
self.rect.top = wall.rect.bottom
# Nice class to hold a wall rect
class Wall(object):
def __init__(self, pos):
walls.append(self)
self.rect = pygame.Rect(pos[0], pos[1], 16, 16)
# Initialise pygame
pygame.init()
# Set up the display
screen = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Ainel")
vstaf = Vstaf()
vstao = Vstao()
vstat = Vstat()
vstae = Vstae()
vstav = Vstav()
player = Player() # Create the player
walls = [] # List to hold the walls
# Holds the level layout in a list of strings.
level = [
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W W W WWWW W W",
"WWWWWWWWWWWW W WWWW WWWW WWWWWWW W W",
"WWWWWWWWWWWW W W WWWWWWWWWWWW W W W",
"WWWWWWWWWWWW WWWWW W W W W W",
"WWWWWWWWWWWW WWWWWWWWWW W W WWWWW W",
"WWWWWWWWWWWW W WWWW W W WW W W WWWWWWWWWWWWW",
"WWWWWWWWWWW WWWWW W W W W WW W WWWWWWWWWWWWW",
"W W WWWWWW W W WWWWWWWWWWWWWW W WWWWWWWWWWWWW",
"W WWWWWW WWWWW W W WW WW W WWWWWWWWWWWWW",
"W W WWWWWW W W WWWWWWWWW WW W W",
"W WWWWW WW WW WW",
"W W WWWWWWWWWWW WWWWWW WWWWWWWWWWWWWWWW WW W",
"W W W WW W W WW W WW W",
"WWWWWWW WWWWW W WWWWWWWWW W W WWWW W",
"W W WWWWW W WW W W W",
"W WWWWWWWW W WW W W W W WWWWWWWWWWWWWW W",
"W WWWW W W W W W W",
"WWWWWWWWWWWW W WWW WWWWWWWWWWWW W W W",
"WWWWWWWWWWWW WW W WW W W W W",
"WWWWWWWWWWWW W WWW WW W W WW W W W W",
"WWWWWWWWWWWW WWWWWW WWWWWWW WWW WW WW W",
"WWWWWWWWWWWW W WWW W W WWWWWWWWWWWW WWW W W W",
"WWWWWWWWWWWW WWW WWWW W WW WWWWWWWWWW W",
"WWWWWWWWWWWW WWW WWWWWWWWWWWWWWWWWW W W",
"W WWWWWWWW W W WW WWW WWWW WW W",
"W WWWWWWWWWWWWW W WW WWW WWW WWWW W",
"WWWW WW W WWWWWW WW WW W",
"W WWWWWWW W WWWWWWWWWW W W W WWWWW",
"WWW WW WWW W W W WWW WWWWW W W",
"W W W W W W W W",
"WWWWWWW WWWWWW W W W W W W",
"W W WWWW WWWW WW W WWW W",
"WWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWW W",
"WWWWWWWWWWWWWWWW WWWW E WWWW WWWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW W WW W WWWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW W WWWWWW WWWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
]
# Parse the level string above. W = wall, E = exit
x = y = 0
for row in level:
for col in row:
if col == "W":
Wall((x, y))
if col == "E":
end_rect = pygame.Rect(x, y, 16, 16)
x += 16
y += 16
x = 0
running = True
while running:
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
running = False
# Move the player if an arrow key is pressed
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
player.move(-1, 0)
if key[pygame.K_RIGHT]:
player.move(1, 0)
if key[pygame.K_UP]:
player.move(0, -1)
if key[pygame.K_DOWN]:
player.move(0, 1)
# Just added this to make it slightly fun ;)
if player.rect.colliderect(end_rect):
raise SystemExit
# Draw the scene
screen.fill((0, 0, 0))
for wall in walls:
pygame.draw.rect(screen, (255, 255, 255), wall.rect)
pygame.draw.rect(screen, (255, 0, 0), end_rect)
screen.blit(player.surf, player.rect)
screen.blit(vstav.surf, vstav.rect)
screen.blit(vstae.surf, vstae.rect)
screen.blit(vstat.surf, vstat.rect)
screen.blit(vstao.surf, vstao.rect)
screen.blit(vstaf.surf, vstaf.rect)
pygame.display.flip()
pygame.quit()

