我正在尝试为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'等待'动作吗?
我不确定我是否大幅解释过。如果我需要提供更多信息,请给我发表评论。我真的需要一些帮助!
谢谢!
答案 0 :(得分:3)
答案简短:
不,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
从队列中返回单个事件。如果队列为空,则此函数将等待,直到创建一个。返回后,事件将从队列中删除。
因此可以等待像
这样的mousedown事件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)
并在给定位置为之前选择的类型构建船舶(当然,检查船舶是否已经建造过,依此类推)。