Почему я получаю ошибку при переключении окон? - PullRequest
0 голосов
/ 20 февраля 2019

Я пытался построить простую игру на python, используя pygame.Сначала моей задачей было сделать движение более плавным, потому что примерно каждую секунду движение прямоугольников зависало на несколько миллисекунд.Затем я нашел решение, добавив "os.environ ['SDL_VIDEODRIVER'] = 'directx'" в мой код и изменив режим отображения на "FULLSCREEN" и "DOUBLEBUFF".Движение теперь более плавное, но всякий раз, когда я нажимаю Alt + Tab из полноэкранной игры, я получаю эту ошибку:

  Traceback (most recent call last):
  File "C:\Users\L-Tramp-GAMING\Documents\Python\Game\Main_Game.py", line 64, in <module>
    screen.fill(BG_COLOR)
pygame.error: IDirectDrawSurface3::Blt: Surface was lost

Я не знаю, как обойти эту проблему.Мне также интересно, могу ли я как-нибудь запустить игру в оконном режиме с добавленной линией DirectX с нормальной скоростью.В данный момент игра работает намного быстрее, когда находится в оконном режиме.Я надеюсь, что некоторые из вас, ребята, смогут мне помочь.Спасибо, Пол

import pygame
import random
import os

#Variables

WIDTH = 1280
HEIGHT = 720

GAME_OVER = False

BG_COLOR = (0, 0, 20)

playerWidth = 50
playerHeight = 50
playerPosX = WIDTH / 2 - playerWidth / 2
playerPosY = HEIGHT - (playerHeight + 75)
playerSpeed = 10

enemieWidth = 75
enemieHeight = 75
enemiePosX = random.randint(0, WIDTH - enemieWidth)
enemiePosY = 0
enemieSpeed = 5

enemieCounter = 1


####################################################################################################

os.environ['SDL_VIDEODRIVER'] = 'directx'

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.FULLSCREEN | pygame.DOUBLEBUF)
pygame.display.set_caption("Game")
pygame.key.set_repeat(1, 10)
clock = pygame.time.Clock()

#GameLoop

while not GAME_OVER:

    for e in pygame.event.get():

        if e.type == pygame.QUIT:

            GAME_OVER = True

        if e.type == pygame.KEYDOWN:

            if e.key == pygame.K_a:

                playerPosX -= playerSpeed
                print(hex(screen.get_flags() & 0xFFFFFFFF))

            if e.key == pygame.K_d:

                playerPosX += playerSpeed

    #Graphics

    screen.fill(BG_COLOR)

    player = pygame.draw.rect(screen, (0, 255, 0), (playerPosX, playerPosY, playerWidth, playerHeight))

    if enemiePosY < HEIGHT:

        enemie = pygame.draw.rect(screen, (255, 0, 0), (enemiePosX, enemiePosY, enemieWidth, enemieHeight))
        enemiePosY += enemieSpeed

    else:

        enemieCounter += 1
        enemiePosY = 0
        enemiePosX = random.randint(0, WIDTH - enemieWidth)

        if (enemieCounter + 1) % 2 == 0:

            pass

    #End Graphics

    pygame.display.flip()

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Ваша задержка движения была вызвана pygame.key.set_repeat.Чтобы позволить игроку удерживать a и d для перемещения, вы можете обновить положение игроков в игровом цикле вместо использования set_repeat, отслеживая переменную скорости.Если вы хотите использовать os.environ по другой причине, помимо устранения задержки, это не сработает, но в противном случае все должно быть в порядке.

import pygame
import random
import os

#Variables

WIDTH = 1280
HEIGHT = 720

GAME_OVER = False

BG_COLOR = (0, 0, 20)

playerWidth = 50
playerHeight = 50
playerPosX = WIDTH / 2 - playerWidth / 2
playerPosY = HEIGHT - (playerHeight + 75)
playerSpeed = 10

enemieWidth = 75
enemieHeight = 75
enemiePosX = random.randint(0, WIDTH - enemieWidth)
enemiePosY = 0
enemieSpeed = 5

enemieCounter = 1


####################################################################################################

#os.environ['SDL_VIDEODRIVER'] = 'directx'

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Game")
#pygame.key.set_repeat(1, 10) <----- This line is the problem
clock = pygame.time.Clock()

#GameLoop

speed = 0

while not GAME_OVER:

    for e in pygame.event.get():

        if e.type == pygame.QUIT:

            GAME_OVER = True

        if e.type == pygame.KEYDOWN:

            if e.key == pygame.K_a:

                speed = -playerSpeed

            if e.key == pygame.K_d:

                speed = +playerSpeed

    playerPosX += speed

    #Graphics

    screen.fill(BG_COLOR)

    player = pygame.draw.rect(screen, (0, 255, 0), (playerPosX, playerPosY, playerWidth, playerHeight))

    if enemiePosY < HEIGHT:

        enemie = pygame.draw.rect(screen, (255, 0, 0), (enemiePosX, enemiePosY, enemieWidth, enemieHeight))
        enemiePosY += enemieSpeed

    else:

        enemieCounter += 1
        enemiePosY = 0
        enemiePosX = random.randint(0, WIDTH - enemieWidth)

        if (enemieCounter + 1) % 2 == 0:

            pass

    #End Graphics

    pygame.display.flip()
0 голосов
/ 21 февраля 2019

Может ли код обработать ошибку, а затем попытаться воссоздать экранный объект?
Это тот же процесс, что и при переключении из полноэкранного в оконное.

РЕДАКТИРОВАТЬ: добавлены некоторыекод из PyGame Wiki: https://www.pygame.org/wiki/toggle_fullscreen, чтобы надеяться обойти дальнейшие проблемы из комментария OP.

try:
    screen.fill(BG_COLOR)
except pygame.error as e:
    # Get the size of the screen
    screen_info= pygame.display.Info()
    cursor     = pygame.mouse.get_cursor()  # Duoas 16-04-2007
    new_width  = screen_info.current_w
    new_height = screen_info.current_h
    # re-initialise the display, creating a re-sizable window
    pygame.display.quit()
    pygame.display.init()
    screen = pygame.display.set_mode( ( new_width, new_height ), pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE )
    pygame.key.set_mods( 0 )            # HACK: work-a-round for a SDL bug??
    pygame.mouse.set_cursor( *cursor )  # Duoas 16-04-2007

    # did it work?
    screen.fill(BG_COLOR)
...