Search code examples
pythonpygamewindow

Pygame.event.get() stopped working. It says the video system hasn't been initialized


I was dealing with another section of my code not working (which can be found in the code's comments) when I noticed that my filename wasn't what I wanted it to be. I closed VS Code, changed the filename, and it started giving this error. I'm not sure what's up, and all I could find on the internet was 'initialize pygame' or 'put pygame.quit() outside the loop', in which I've done both. I even tried updating pygame.

import pygame
import random

# starts up all the upper levels stuff like the window and framerate
pygame.init()
win = pygame.display.set_mode((1028, 548))
quitt = False
clock = pygame.time.Clock()

class character(): # makes a character that moves. all other functionality will be done elsewhere
  def __init__(self):
    self.rect = pygame.rect.Rect(100, 205, 40, 40)
  def move(self): #movement
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]:
      self.rect = self.rect.move(0, -4)
    if keys[pygame.K_DOWN]:
      self.rect = self.rect.move(0, 4)
    if keys[pygame.K_LEFT]:
      self.rect = self.rect.move(-4, 0)
    if keys[pygame.K_RIGHT]:
      self.rect = self.rect.move(4, 0)

class block(): #blocks that can be pushed
  def __init__(self, startpos):
    self.rect = pygame.rect.Rect(startpos[0], startpos[1], 40, 40)
  def move(self):
    global player, blocklist
    if player.rect.colliderect(self.rect): # oh boy, here's the problem code
      if player.rect.right > self.rect.left: # if approaching from the left. this works.
        if self.rect.bottom - player.rect.top <= 5:
          self.rect.move_ip(0, -4)
        elif self.rect.top - player.rect.bottom >= -5:
          self.rect.move_ip(0, 4)
        elif player.rect.right - self.rect.left <= 5:
          self.rect.move_ip(4, 0)
      elif player.rect.left < self.rect.right: # if approaching from the right. This mostly works.
        if self.rect.bottom - player.rect.top <= 5:
          self.rect.move_ip(0, -4)
        elif self.rect.top - player.rect.bottom >= -5:
          self.rect.move_ip(0, 4)
        elif player.rect.left - self.rect.right >= -5: # here's the problem line. idk what's up.
          self.rect.move_ip(-4, 0)
      else: #here to catch when the two have equal x coords. this works.
        if self.rect.bottom - player.rect.top <= 5:
          self.rect.move_ip(0, -4)
        elif self.rect.top - player.rect.bottom >= -5:
          self.rect.move_ip(0, 4)
    
    self.shunt() # here to stop two objects from being within one another. Also allows you to push more than one block.
  def shunt(self): #mostly copied from the wall. this works.
    global player, blocklist
    if self.rect.colliderect(player.rect):
      if player.rect.right - self.rect.left <= 5:
        player.rect.move_ip(self.rect.left-player.rect.right, 0)
      elif player.rect.left - self.rect.right >= -5:
        player.rect.move_ip(self.rect.right-player.rect.left, 0)
      elif player.rect.top - self.rect.bottom >= -5:
        player.rect.move_ip(0, self.rect.bottom - player.rect.top)
      elif player.rect.bottom - self.rect.top <= 5:
        player.rect.move_ip(0, self.rect.top-player.rect.bottom)
    for block in blocklist:
      if self.rect.colliderect(block.rect) and blocklist.index(block) != blocklist.index(self):
        if block.rect.right - self.rect.left <= 5:
          block.rect.move_ip(self.rect.left-block.rect.right, 0)
        elif block.rect.left - self.rect.right >= -5:
          block.rect.move_ip(self.rect.right-block.rect.left, 0)
        elif block.rect.top - self.rect.bottom >= -5:
          block.rect.move_ip(0, self.rect.bottom - block.rect.top)
        elif block.rect.bottom - self.rect.top <= 5:
          block.rect.move_ip(0, self.rect.top-block.rect.bottom)
        if block.rect.colliderect(player.rect):
          block.shunt()

class button(): # gets pressed if a block goes on it.
  def __init__(self, startpos):
    self.rect = pygame.rect.Rect(startpos[0], startpos[1], 40, 40)
    self.pressed = False
  def checkpressed(self): #checks if it's been pressed.
    global blocklist
    for block in blocklist:
      if self.rect.colliderect(block.rect):
        self.pressed = True

class wall(): # walls. They do wall things.
  def __init__(self, startpos, size):
    self.rect = pygame.rect.Rect(startpos[0], startpos[1], size[0], size[1])
  def shunt(self): # top of the shunt chain.
    global player, blocklist
    if self.rect.colliderect(player.rect): # shunt the player
      if player.rect.right - self.rect.left <= 5:
        player.rect.move_ip(self.rect.left-player.rect.right, 0)
      elif player.rect.left - self.rect.right >= -5:
        player.rect.move_ip(self.rect.right-player.rect.left, 0)
      elif player.rect.top - self.rect.bottom >= -5:
        player.rect.move_ip(0, self.rect.bottom - player.rect.top)
      elif player.rect.bottom - self.rect.top <= 5:
        player.rect.move_ip(0, self.rect.top-player.rect.bottom)
    for block in blocklist: # shunt the blocks
      if self.rect.colliderect(block.rect):
        if block.rect.right - self.rect.left <= 5:
          block.rect.move_ip(self.rect.left-block.rect.right, 0)
        elif block.rect.left - self.rect.right >= -5:
          block.rect.move_ip(self.rect.right-block.rect.left, 0)
        elif block.rect.top - self.rect.bottom >= -5:
          block.rect.move_ip(0, self.rect.bottom - block.rect.top)
        elif block.rect.bottom - self.rect.top <= 5:
          block.rect.move_ip(0, self.rect.top-block.rect.bottom)
        if block.rect.colliderect(player.rect):
          block.shunt()
        for blocky in blocklist:
          if block.rect.colliderect(blocky):
            block.shunt()

player = character() # makes the player
bg = pygame.rect.Rect(0, 0, 1028, 548) # don't want it to look like when you go out of bounds in a source game.
blocklist = [block((200, 205)), block((300, 205))] # list of blocks
buttonlist = [button((700, 100))] # list of buttons (or at least button)
wallist = [wall((0, 0), (1028, 40)), wall((0, 0), (40, 548)), wall((988, 0), (40, 548)), wall((0, 508), (1028, 40)), wall((494, 0), (40, 300))] # list of walls

while not quitt: #main loop
  clock.tick(60) #60 fps
  for event in pygame.event.get(): # this is breaking
    if event.type == pygame.QUIT:
      quitt = True
  pygame.draw.rect(win, (0, 0, 0), bg)# makes sure we aren't seeing the previous frames

  for button in buttonlist:#update buttons
    button.checkpressed()
    if button.pressed:
      pygame.draw.rect(win, (0, 255, 0), button.rect) #draw buttons
    else:
      pygame.draw.rect(win, (255, 0, 255), button.rect)
  player.move() # update the player
  for block in blocklist: # update the blocks
    block.move()
    for wall in wallist: # walls shunt
      wall.shunt()
    pygame.draw.rect(win, (0, 0, 255), block.rect) # draw blocks
  for wall in wallist:
    pygame.draw.rect(win, (255, 255, 255), wall.rect) # draw walls
  pygame.draw.rect(win, (255, 0, 0), player.rect) # draw player
  pygame.display.update() # update the screen
  
  pygame.quit() #bye bye

Solution

  • It is a matter of indentation, pygame.quit() must be called after the application loop, but not in the application loop:

    while not quitt: #main loop
      clock.tick(60) #60 fps
      for event in pygame.event.get(): # this is breaking
        if event.type == pygame.QUIT:
          quitt = True
      pygame.draw.rect(win, (0, 0, 0), bg)
      # [...]
    
      # INDANTATION
    #<-|
    pygame.quit() #bye bye