[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: USEREVENT clash fix, was Re: [pygame] Re: Starting the pygame 2 series



On 28.07.2018 12:16, Sam Bull wrote:
On Sat, 2018-07-28 at 09:59 +0200, René Dudfield wrote:
def custom_type():
    """ Return an event type we can use for our own events.
    """
Don't forget to mention in the documentation that StopIteration will be raised
if there are no more event types available.


Hi there

Sorry for the late response.

You can prevent the USEREVENT clash if you use a custom event construct like this (or at least almost):


pygame.event.post(pygame.event.Event(pygame.USEREVENT, {"id": 1223434234, "num": 34, "value": "bla"}))

Using this allows you do define any value for the id field you need. Also you can add custom properties (in this example like 'num' and 'value').  But then you will have a if elif else dispatching construct within the elif block handling the USEREVENT.

This extra values can be read like normal event attributes like this:

print(event)
print(event.id)
print(event.num)
print(event.value)

This is a bit cumbersome to use (since I don't know why pygame.NUMEVENTS is limited to 32) but will work.

But there is a strange thing: using mixer.music, mixer.Channel or pygame.time.set_timer() objects. They provide an set_endevent() method, but only can take an integer (which is almost useless with the NUMEVENTS limit). I would have expected to be able to set a custom event there too because that would solve it the same way as with normal events.

Especially when using a timer you normally want many timers bound to different ids. If pygame would provide that built-in this would really be good (hmm, maybe there should be an additional module for this like for sprites).


I see only two ways: Either raise the NUMEVENTS limit to a high number e.g. >1000 or bigger.

Or

Allow custom events everywhere.


For libraries or classes using an USEREVENT maybe the actual event number should be passed somehow so each application/game can use the event numbers as they fit best.

~DR0ID


Below my test script:


# -*- coding: utf-8 -*-
from __future__ import print_function, division

import logging

logging.basicConfig()
import pygame

logger = logging.getLogger(__name__)

SCREENSIZE = 800, 600

def main():

    pygame.init()
    # screen = pygame.display.set_mode(SCREENSIZE, pygame.RESIZABLE | pygame.SRCALPHA, 32)
    screen = pygame.display.set_mode(SCREENSIZE)

    running = True
    while running:
        # events
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    running = False
                elif event.key == pygame.K_SPACE:
                    pygame.event.post(pygame.event.Event(pygame.USEREVENT, {"id": 1223434234, "num": 34, "value": "bla"}))
                elif event.key == pygame.K_m:
                    pygame.mixer.music.set_endevent(pygame.event.Event(pygame.USEREVENT, {id: 999}))
            elif event.type == pygame.USEREVENT:
                print(event)
                print(event.id)
                print(event.num)
                print(event.value)
                # dispatch here according to id
                if event.id == 0:
                    pass
                elif event.id == 3:
                    pass
                else:
                    pass
                    # and so on

        # draw

        pygame.display.flip()
        screen.fill((255, 0, 255))

    pygame.quit()


if __name__ == '__main__':
    main()