Python - Black screen afther re-opening pygame application
Asked Answered
W

1

6

I created a simple tile based game with python pygame and the android subset. When I exit the app on my android device and I re-open it I see a black screen, if I close the program form the 'tabs' then the game will work again, does anybody know what's the problem? Do I have to add some code in the program?

from pygame.locals import *
from settings import *
from sprites import *
import pygame
import time
import sys
import os

try:
    import pygame_sdl2
    pygame_sdl2.import_as_pygame()
except ImportError:
    pass

pygame.init()
pygame.display.set_caption(TITLE)

class Game:

    def __init__(self):
        self.clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))

        self.up_button = pygame.Rect(1000, 400, 100, 100)
        self.down_button = pygame.Rect(1000, 600, 100, 100)
        self.right_button = pygame.Rect(1100, 500, 100, 100)
        self.left_button = pygame.Rect(900, 500, 100, 100)

        self.all_sprites = pygame.sprite.Group()
        self.walls = pygame.sprite.Group()
        self.player = Player(self, 2, 2)

        for x in range(5, 10):
            Wall(self, x, 3)
        for x in range(5, 10):
            Wall(self, x, 7)
        for y in range(3, 8):
            Wall(self, 10, y)

        self.buttons = pygame.sprite.Group()
        self.game_over = False

    def update(self):
        self.all_sprites.update()

    def draw(self):
        self.screen.fill(BLACK)
        self.draw_grid()
        self.all_sprites.draw(self.screen)
        pygame.draw.rect(self.screen, GREEN, self.up_button)
        pygame.draw.rect(self.screen, RED, self.down_button)
        pygame.draw.rect(self.screen, BLUE, self.right_button)
        pygame.draw.rect(self.screen, YELLOW, self.left_button)
        pygame.display.update()

    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                if self.up_button.collidepoint(mouse_pos):
                    self.player.move(dy = -1)
                elif self.down_button.collidepoint(mouse_pos):
                    self.player.move(dy = 1)
                elif self.right_button.collidepoint(mouse_pos):
                    self.player.move(dx = 1)
                elif self.left_button.collidepoint(mouse_pos):
                    self.player.move(dx = -1)

    def run(self):
        self.title_menu()
        while not self.game_over:
            self.clock.tick(FPS)
            self.events()
            self.update()
            self.draw()

    def draw_grid(self):
        for x in range(0, WIDTH, TILESIZE):
            pygame.draw.line(self.screen, LIGHTGRAY, (x, 0), (x, HEIGHT))
        for y in range(0, HEIGHT, TILESIZE):
            pygame.draw.line(self.screen, LIGHTGRAY, (0, y), (WIDTH, y))

    def title_menu(self):
        pass

if __name__ == '__main__':
    game = Game()
    game.run()
Wardroom answered 15/11, 2016 at 19:43 Comment(7)
Do you press ESCAPE to exit the application or do you just close it with the home button? Because of how Android hibernates applications and assumes your application to be able to be un-frozen, this is quite important.Truthvalue
I just press the home button, If I try to press the back button it doesn't do anythingWardroom
Your code specifically says to trigger pygame.quit() when the event pygame.QUIT is raised, it's only raised whenever K_ESCAPE (keyboard key Escape) is pressed. The home button is NOT escape. The home button will hibernate the application and nothing else, when you open up the application "again" it's actually just resumed. This is to save processing power and boot times of applications when re-opening them. It's the illusion of being closed and open super quick that people wants, not actually closing them ;)Truthvalue
Also this code has nothing to do with Android what so ever, am I wrong? How are you running this on Android? Kiwy? If so, you should probably add some code here as to how you detect the different Android specific OS calls and events, because I'm assuming you're running in some form of Python emulator since Android doesn't really do Python natively.Truthvalue
Sorry this is the link: github.com/renpytom/rapt-pygame-exampleWardroom
@MircoDeZorzi Can the problem still be reproduced?Captivity
The problem is still there even with PyGame 2, built with buildozerBautzen
B
3

For some reasons that I don't really understand, it looks like the reference to the screen (that you stored in the screen property of your Game object) is lost after the Android main Activity loses the focus. One possible reason might be related to the EGL Context Lost, although I don't have significant elements to confirm this hypothesis.

Despite the reasons causing this issue, I think I've found a solution to it. First, you need to catch the event when the app is coming back to foreground (check this answer for more details about how to do this by means of specific SDL2 events), and then restore the screen reference.

Here is what worked for me, applied to your events method:

def events(self):
    for event in pygame.event.get():
        if event.type == 261:
            # 261 is SDL_APP_WILLENTERFOREGROUND event code
            self.screen = pygame.display.set_mode((WIDTH, HEIGHT))

        # ...
Bautzen answered 2/9, 2021 at 11:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.