如何让我的代码等待点击?
Posted
技术标签:
【中文标题】如何让我的代码等待点击?【英文标题】:How do I make my code wait for a click? 【发布时间】:2017-11-20 18:19:39 【问题描述】:我正在尝试为 pvp 战舰游戏编写代码,但我有点卡住了。
我会先给你看代码,然后解释它们是如何工作的。
这是第一个代码。此函数用于在网格上定位每艘船:
def ship_builder(name):
# client ship value = 6, server ship value = 7
v_or_h = randrange(2)
if v_or_h == 0:
vertical = True
else:
vertical = False
if name == 'destroyer':
print('Click a cell to build a destroyer.')
if vertical == True:
print('Vertical')
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
col = (pos[0] // (cell_side + margin)) + 1
row = (pos[1] // (cell_side + margin)) + 1
grid[row][col] = 7
for i in range(3):
row += 1
grid[row][col] = 7
elif vertical == False:
print('Horizontal')
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
col = (pos[0] // (cell_side + margin)) + 1
row = (pos[1] // (cell_side + margin)) + 1
grid[row][col] = 7
for i in range(3):
col += 1
grid[row][col] = 7
elif name == 'frigate':
print('Click a cell to build a frigate')
if vertical == True:
print('Vertical')
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
col = (pos[0] // (cell_side + margin)) + 1
row = (pos[1] // (cell_side + margin)) + 1
grid[row][col] = 7
for i in range(2):
row += 1
grid[row][col] = 7
elif vertical == False:
print('Horizontal')
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
col = (pos[0] // (cell_side + margin)) + 1
row = (pos[1] // (cell_side + margin)) + 1
grid[row][col] = 7
for i in range(2):
col += 1
grid[row][col] = 7
第二个是上面函数的for循环:
for ship in ['destroyer','frigate']:
ship_builder(ship)
color_change()
#color_change() is a function that colors the responding cells for the ships.
这是他们应该如何工作的。首先,ship_builder
被称为船名(例如,“战舰”)。代码做的第一件事是检查船是垂直放置还是水平放置。根据它的值,用户可以点击一个单元格来确定位置。这是我遇到问题的地方;代码只是跳过该部分并继续进行而不做任何事情。
我的问题是:为什么会跳过鼠标点击部分? pygame.event.get() 不应该让 Python “等待”一个动作吗?
我不确定我是否解释得很详细。如果我需要提供更多信息,请给我留言。我真的需要帮助!
谢谢!
【问题讨论】:
【参考方案1】:简短的回答:
不,pygame.event.get() -> EventList
不应该“等待”一个动作。请改用pygame.event.wait() -> EventType
。
更长的答案:
Pygame 正在使用一个事件队列,它存储已发生的事件。让我们看看pygame.event.get()
文档。
pygame.event.get() get events from the queue get() -> Eventlist get(type) -> Eventlist get(typelist) -> Eventlist
这将获取所有消息并将它们从队列中删除。如果给定一个类型或类型序列,则只会从队列中删除那些消息。如果您只是从队列中获取特定事件,请注意队列最终可能会填满您不感兴趣的事件。
所以基本上,pygame.event.get()
返回自我们上次调用它以来发生的所有事件。如果我们的事件还没有发生,它就不会在返回的EventList
中。
但是还有另一个名为 pygame.event.wait()
的函数按照要求的方式运行(尽管它只返回一个事件)。
pygame.event.wait() wait for a single event from the queue wait() -> EventType instance
从队列中返回单个事件。如果队列为空,此函数将等待直到创建队列。一旦事件被返回,它就会从队列中删除。
因此可以等待类似的鼠标按下事件
event_happened = False
while not event_happened:
event = pygame.event.wait()
if event.type == pygame.MOUSEBUTTONDOWN:
do_something()
event_happened = True
但是,我们需要在这里小心,因为如文档中所述,事件已从队列中删除,这意味着所有不属于 pygame.MOUSEBUTTONDOWN
类型的事件都将丢失.如果需要,我们将不得不手动处理它们或将它们传递/保护它们。
这是更长的答案,但我有一个补充/警告。像这样在代码中的不同点获取事件会很快导致混乱(例如,由于如上所述的丢失事件等)。这种情况下的决定可能与程序中缺少主游戏循环有关(我无法确定,因为我不知道周围的代码,但当前的实现似乎暗示了类似的东西)。
通常,事件是在一个连续的主游戏循环中访问的,看起来像这样
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
build_ship_on_event(event)
elif event.type == pygame.QUIT:
pygame.quit()
sys.exit()
build_ship_on_event(event)
函数可以尝试做类似的事情
def build_ship_on_event(event):
if event_is_mouse_click(event):
ship_builder(selected_ship_type, event.pos)
并在给定位置为先前选择的类型建造船(当然检查之前是否建造过船等等)。
【讨论】:
没想到回答这么详细!非常感谢!以上是关于如何让我的代码等待点击?的主要内容,如果未能解决你的问题,请参考以下文章