How do I create a "rpg door" effect in pygame, and what's wrong with my method?

Viewed 233

I'm creating a game where going near a door(defined using Rect function) calls a function which loads a new game screen which gives the effect of going through to that door inside the house. I tried to do the same thing with the coming out mechanism where I tried to define an area with a Rect object and made it so that when the player comes near it the main game loop is called and it would give the effect of coming out the door but doing so makes it so that the player is stuck in an infinite loop of the screen fading away. the part of the code is attached below and the full code is here

this is the door collision detection

    out = pygame.Rect(360, 580, 80, 10)
    player_rect = playerImgXL.get_rect(topleft=(playerXxl, playerYxl))

    if player_rect.colliderect(out):
        game()  # coming out of the house

this is the game loop function

def game():
  global present_dialogue
  global current_dialogue
  global playerX
  global playerY
  clock.tick(12)
  mixer.music.pause()
  mixer.music.load('pallet_music.mp3')
  # mixer.music.play(100)
  playerX_change = 0
  playerY_change = 0
  running = True
  while running:
      present_dialogue = None
      current_dialogue = None
      for event in pygame.event.get():
          if event.type == pygame.QUIT:
              pygame.quit()
              sys.exit()
      redrawgamewindow()
      pygame.display.update()

this isn't the entire game loop there's just the event detection and collision detection between the sys.exit statement and the display update statement

this is the redrawgamewindow function that I call at the end of the game loop

def redrawgamewindow():
  global walkcount
  scr.fill((0, 0, 0))
  scr.blit(pallet, (60, 0))
  if current_dialogue:
      scr.blit(*current_dialogue)
      npc_one_dialogue()
  if walkcount + 1 >= 29:
      walkcount = 0
  if up:
      scr.blit(WalkFront[walkcount // 7], (playerX, playerY))
      walkcount += 1
  elif down:
      scr.blit(WalkBack[walkcount // 7], (playerX, playerY))
      walkcount += 1
  elif left:
      scr.blit(WalkLeft[walkcount // 7], (playerX, playerY))
      walkcount += 1
  elif right:
      scr.blit(WalkRight[walkcount // 7], (playerX, playerY))
      walkcount += 1
  else:
      player(playerX, playerY)
  if present_dialogue:
      scr.blit(*present_dialogue)
      npc_two_dialogue()
1 Answers

A few changes are needed to prevent the fade loop:

  • In the inhouse_oak function, reset the starting position when the player enters the room

  • When the player exits the room, just return to the main game loop

    def inhouse_oak():
        global playerXxl
        global playerYxl
        playerXxl = 365  # reset starting position
        playerYxl = 480
        ...........
        while running:
            .................
            if player_rect.colliderect(out):
                return  # return to main loop
                # game()  # coming out of the house
    
  • In the main loop, when the player exits the room, move the player away from the door

      door3 = pygame.Rect(462, 348, 25, 5)
      if player_rect.colliderect(door3):
          fade(800, 600)
          inhouse_oak()  # Oak's Lab door
          playerY_change = playerX_change = 0  # stop player movement
          playerY += 10  # move away from door
    

To add a fade when exiting the room, make these changes:

  • Generalize the fade function.

    def fade(x, y, rgw):  # last parameter is screen function to call
        fade = pygame.Surface((x, y))
        fade.fill((0, 0, 0))
        for alpha in range(0, 300):
            fade.set_alpha(alpha)
            rgw(True)  # fading = True
            scr.blit(fade, (0, 0))
            pygame.display.update()
    
  • Add the fading parameter to the main game function.

    def redrawgamewindow(fading=False):
    
  • Add the fading parameter to the room function and check the parameter before updating the screen to prevent screen flash.

    def redrawgamewindow_oak(fading=False):
        .........
        if not fading: pygame.display.update()  # prevent flash if fading
    
  • Update the fade call in the redrawgamewindow function.

      door3 = pygame.Rect(462, 348, 25, 5)
      if player_rect.colliderect(door3):
          fade(800, 600, redrawgamewindow)  # fade main game
          inhouse_oak()  # Oak's Lab door
          playerY_change = playerX_change = 0
          playerY += 10  #playerX_change
    
  • In redrawgamewindow_oak, when leaving the room, call the fade function.

      if player_rect.colliderect(out):
          fade(800, 600, redrawgamewindow_oak)  # fade room
          return  # return to main loop
          #game()  # coming out of the house
    
Related