0

I tried to build a simple game in python using pygame. At first my problem was to make the movement more smooth, because about every second the movement of the rectangles stuck for a few milliseconds. Then I found an solution by adding "os.environ['SDL_VIDEODRIVER'] = 'directx'" in to my code and changing the display mode to "FULLSCREEN" and "DOUBLEBUFF". The movement is more fluid now, but whenever I Alt + Tab out of the fullscreen game, i get this error:

  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

I don't know how to bypass this problem. I am also wondering if i can somehow run the game in windowed mode with the directx line added in normal speed. At the moment the game runs in much higher speed when it is in windowed mode. I hope some of you guys can help me. Thank you, Paul

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()
deceze
  • 510,633
  • 85
  • 743
  • 889
Luap555
  • 51
  • 1
  • 1
  • 4

2 Answers2

0

Can the code handle the error, and then try re-creating the screen object ?
This is the same sort of process as when switching from full-screen to windowed.

EDIT: Added some code from the PyGame Wiki: https://www.pygame.org/wiki/toggle_fullscreen to hopefully work around further issues from OP's comment.

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)
Kingsley
  • 14,398
  • 5
  • 31
  • 53
  • Thank you for your answer. Most times it works with your solution, but ironically I can't hold down the key to move my rectangle more than only 10px a time after alt- tabing out of the fullscreen window. Any idea ? – Luap555 Feb 21 '19 at 10:02
  • @Luap555 - I added a few calls from some example code on the PyGame Wiki. The `get_cursor()` / `set_cursor()`, and the `pygame.key.set_mods( 0 )`. Maybe these will help, but it's just a guess. – Kingsley Feb 21 '19 at 21:40
  • Thank you, but i found out that i get very smooth movement whithout using DirectX but the fps limit from pyglet – Luap555 Feb 21 '19 at 21:46
0

Your movement lag was caused by pygame.key.set_repeat. To allow the player to hold down a and d to move you can update the players position in your game loop instead of using set_repeat by keeping track of a speed variable. If you wanted to use os.environ for another reason besides fixing the lag then this won't work but otherwise this should be fine.

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()
nj1234
  • 66
  • 4
  • Thanks for your answer, but unfortunately this does not fix the stuttering. The rectangles which come down from the top are also lagging – Luap555 Feb 21 '19 at 09:42