renpy / pygame_sdl2

Reimplementation of portions of the pygame API using SDL2.
GNU Lesser General Public License v2.1
326 stars 64 forks source link

App crashing on mobile not desktop when pygame.mouse.get_pressed() is triggered #84

Closed umbe1987 closed 3 years ago

umbe1987 commented 6 years ago

I opened the same issue at rapt-pygame-example but I am copying it here as I think it's more related to this repo. Sorry for double posting...

I made a game which uses pygame.mouse.get_pressed() to check whether the mouse left button is pressed. The complete code is in my repo. If this happens, it checks whether the position of the click is LEFT RIGH UP or DOWN of a joypad draw. This moves a character towards the correct direction. The game works when I test it on my Ubuntu machine, but it crashes as soon as I touch whatever area of the screen on mobile (no matter if it's within the joypad's buttons or outside). I check for mouse left with the code below inside a Joypad class:

    def btn_pressed(self, mouse_event):

        # check if left mouse is being pressed
        if pygame.mouse.get_pressed()[0]:
            x, y  = mouse_event.pos
            if self.btn_up.rect.collidepoint(x, y):
                return 'UP'
            elif self.btn_down.rect.collidepoint(x, y):
                return 'DOWN'
            elif self.btn_left.rect.collidepoint(x, y):
                return 'LEFT'
            elif self.btn_right.rect.collidepoint(x, y):
                return 'RIGHT'

Then, in the Character class I do:

    def move(self, joypad_direction):
        """
        move the character
        to be used along with Joypad.btn_pressed returns
        ('UP', 'DOWN' 'LEFT', 'RIGHT')
        """

        self.dx = 0
        self.dy = 0

        # check for horizontal move
        if joypad_direction == 'LEFT':
            self.dx = -self.speed
            self.rect.move_ip(-self.speed, 0)
        if joypad_direction == 'RIGHT':
            self.dx = +self.speed
            self.rect.move_ip(self.speed, 0)

        self.dx = 0

        # check for vertical move
        if joypad_direction == 'UP':
            self.dy = -self.speed
            self.rect.move_ip(0, -self.speed)
        if joypad_direction == 'DOWN':
            self.dy = +self.speed
            self.rect.move_ip(0, self.speed)
        self.dy = 0

Finally, in my main function I do:

    while True:

        ev = pygame.event.wait()

        # If not sleeping, draw the screen.
        if not sleeping:
            hero.move(joypad.btn_pressed(ev))
            screen.fill((0, 0, 0, 255))

            joypad.buttons.draw(screen)

            if x is not None:
                screen.blit(hero.image, (x, y))

            pygame.display.flip()
renpytom commented 6 years ago

What's the crash?

umbe1987 commented 6 years ago

I solved. It was an issue in my code. I was waiting for events and storing x y position with ev.pos afterwards, but I did not check which type of event. So basically with the mouse from desktop everything worked while some different unkown event from mobile which did not have pos attribute caused the app to "crash" (going to background) as soon as I touched the screen. I'm on mobile so I can't provide the code but I'll come back when I'll be in front of my laptop. I committed a working code to my repo (see link above).

umbe1987 commented 6 years ago

Ok, so the problem was related to these lines in the main loop:

# If not sleeping, draw the screen.
        if not sleeping:
            hero.move(joypad.btn_pressed(ev))

which I changed to:

if not sleeping:
    if ev.type == pygame.MOUSEMOTION or ev.type == pygame.MOUSEBUTTONUP:
        hero.move(joypad.btn_pressed(ev))

Now, x, y = ev.pos in Joypad.btn_pressed() method does not goes in error if the event is something without the "pos" attribute (e.g a QUIT event). My updated code is in my repo if you wanna see it.

You can close the issue if you want, thanks!