Pygame - 如何创建更多USEREVENT类型的事件?
这个问题是因为我需要创建很多USEREVENT类型的事件。由于找不到关于如何创建超过限制的userevent的信息,所以我来这里寻求帮助。
目前我知道USEREVENT类型的事件值是24,允许的最大ID是31。我还发现一些ID是保留的,至少在官方文档的一个评论中提到过(http://www.pygame.org/docs/ref/event.html#comment_pygame_event_Event)。
基于这些信息,我有两个问题:那些SDL_EVENT_RESERVED的事件ID可以安全地用作用户创建事件的额外空间吗(比如一个定时器:pygame.time.set_timer(USEREVENT + 7, 1000))?有没有办法像定时器代码示例那样创建无限数量的用户自定义事件?
如果我的问题因为措辞不当或其他原因而让人难以理解,我很抱歉。
3 个回答
pygame.time.set_timer()
这个函数可以在事件队列中不断创建一个 USEREVENT
。时间需要以毫秒为单位设置。例如:
time_interval = 500 # 500 milliseconds == 0.1 seconds
timer_event = pygame.USEREVENT+1
pygame.time.set_timer(timer_event, time_interval)
需要注意的是,在pygame中可以定义自定义事件。每个事件都需要一个独特的ID。用户事件的ID必须在 pygame.USEREVENT
(24)和 pygame.NUMEVENTS
(32)之间。在这种情况下,pygame.USEREVENT+1
就是定时事件的ID。
自从Pygame 2.0版本开始,可以使用 pygame.event.custom_type()
来代替 pygame.USEREVENT+1
。 pygame.event.custom_type()
的作用是:
为自定义用途保留一个
pygame.USEREVENT
。如果创建的事件太多,会引发一个pygame.errorstandard
的异常。
例如:
timer_event = pygame.event.custom_type()
pygame.time.set_timer(timer_event, 500)
如果我是你,我会只用一种 USEREVENT 类型,来创建我想要的多个自定义事件。实现这个的方式就是给事件的名称或类型加一个特别的属性。下面有个小例子可以让你更清楚...
这个是在 Windows 10 上,使用 pygame 1.9.6 和 Python 3.7.3 测试的。
import pygame as pg
ON_MY_MOUSE_CLICK = 1 # your own codes for your own events...
ON_MY_SCROLL = 2
BLAH_BLAH = 3
# etc ...
pg.init()
video = pg.display.set_mode((100,100))
MouseEvent = pg.event.Event(pg.USEREVENT, MyOwnType=ON_MY_MOUSE_CLICK )
ScrollEvent = pg.event.Event(pg.USEREVENT, MyOwnType=ON_MY_SCROLL)
blahblahEvent = pg.event.Event(pg.USEREVENT, MyOwnType=BLAH_BLAH)
pg.event.post(MouseEvent) # call your own type
pg.event.post(ScrollEvent) # call your own type
for event in pg.event.get():
if (event.type == pg.QUIT):
pass # your built-in event handle goes here
elif (event.type == pg.USEREVENT): # here we go
if (event.MyOwnType == ON_MY_MOUSE_CLICK):
print("My own mouse event!") # handle for your own event
elif (event.MyOwnType == ON_MY_SCROLL):
print("My own scroll event!") # handle for your own event
elif (event.MyOwnType == BLAH_BLAH):
print("My own blah blah event!") # handle for your own event
编辑:
如果你发现自己需要使用 pg.time.set_timer
,我知道我们不能把 MyOwnType
直接赋值给 set_timer
。不过,你可以随意使用我在 GitHub 上的 set_interval.py
。它是 MIT 许可证的,所以你不用担心一般的 GNU 许可证之类的问题...
这里有个例子:
from set_interval import setInterval
import pygame as pg
def set_timer(eventObj, interval):
func = lambda x: pg.event.post(x)
return setInterval(func=func, sec=interval, args=[eventObj])
ON_MY_MOUSE_CLICK = 1 # your own codes for your own events...
ON_MY_SCROLL = 2
BLAH_BLAH = 3
# etc ...
pg.init()
video = pg.display.set_mode((100,100))
MouseEvent = pg.event.Event(pg.USEREVENT, MyOwnType=ON_MY_MOUSE_CLICK )
ScrollEvent = pg.event.Event(pg.USEREVENT, MyOwnType=ON_MY_SCROLL)
blahblahEvent = pg.event.Event(pg.USEREVENT, MyOwnType=BLAH_BLAH)
# replacement for pygame.time.set_timer(MouseEvent, 1000)
myIntervalHandle1 = set_timer(MouseEvent, 1)
# replacement for pygame.time.set_timer(ScrollEvent, 2500)
myIntervalHandle2 = set_timer(ScrollEvent, 2.5)
running = True
while running :
for event in pg.event.get():
if (event.type == pg.QUIT):
pg.display.quit()
myIntervalHandle1.stop() # stop timer
myIntervalHandle2.stop() # stop timer
running = False
elif (event.type == pg.USEREVENT): # here we go
if (event.MyOwnType == ON_MY_MOUSE_CLICK):
print("My own mouse event!") # handle for your own event
elif (event.MyOwnType == ON_MY_SCROLL):
print("My own scroll event!") # handle for your own event
elif (event.MyOwnType == BLAH_BLAH):
print("My own blah blah event!") # handle for your own event
你可以在这里找到 set_interval.py
:
用户事件的范围应该在:
pygame.USEREVENT
: 24pygame.NUMEVENTS
: 32
所以你可以有9种不同的用户事件。
通常的做法是定义一个常量:
SOME_EVENT = pygame.USEREVENT + 0
ANOTHER_EVENT = pygame.USEREVENT + 1
...
如果你用 event(...)
来创建事件,你可以给这个事件添加一些属性,这样你就可以创建很多不同的子事件,并给它们添加额外的数据,比如:键盘事件。
不过,当你使用 pygame.time.set_timer()
时,你只能使用一个ID,没法添加其他信息。