我使用吡游构建一个简单的游戏,并有以下主循环,其中mouse()是一个捕获和处理鼠标事件的函数,keyboard()用于键盘事件:
def mainLoop():
pygame.event.pump()
keyboard(pygame.key.get_pressed())
events = pygame.event.get()
mouse(events)
for event in events:
if event.type == pygame.QUIT:
pygame.quit()
return False
return True当玩家单击瓷砖时,mouse()调用了以下函数
def objReach(obj, pos):
try:
path = obj.reach(pos, move=False) # A* (path-finding algorithm)
for step in path:
sleep(1.0/obj.speed)
objMove(obj, step)
except Exception as e:
sendMsg(str(e))问题是,当对象正在遍历路径(当for循环运行时),鼠标事件不会被捕获,所以如果玩家在中间单击另一个瓷砖,什么都不会发生。我希望玩家能够改变路径。
我尝试在mainLoop循环中使用for,但它只是部分有效--它只捕获MOUSEBUTTONUP事件,而不是上下事件,这是判断播放机是否只是单击或拖放事件所必需的。下面是澄清的mouse()函数:
def mouse(events):
global clickPos
global releasePos
for event in events:
if event.type == MOUSEBUTTONDOWN:
clickPos = getPos(pygame.mouse.get_pos())
# getPos() transforms screen coordinates in game coordinates
elif event.type == MOUSEBUTTONUP:
releasePos = getPos(pygame.mouse.get_pos())
if event.button == MAIN_BUTTON:
# Simple click
if clickPos == releasePos:
if player.privilege > 1:
objMove(player, getPos(pygame.mouse.get_pos()))
else:
objReach(player, getPos(pygame.mouse.get_pos()))
# Drag and drop
else:
obj = player.place.matrix[clickPos[0]][clickPos[1]][-1]
objThrow(obj, clickPos, releasePos)
elif event.button == SECONDARY_BUTTON:
pass # TODO: ...我对多线程不太熟悉,我也不认为它应该与游戏一起使用,但这是我唯一能想到的。有什么想法吗?
发布于 2013-08-28 23:25:01
您可以尝试修改对象,使其具有类似于objReach列表的内容,而不是在多线程中乱动,直接导致对象在obj函数中移动并阻塞主循环。它基本上是一个队列,其中包含要移动到的每个位置的坐标。
然后,您要做的是,当鼠标被单击时,使用您的路径查找算法来查找对象应该沿着的路径,并用它替换队列:
import time
def objReach(obj, pos):
try:
obj.path = obj.reach(pos, move=False) # A* (path-finding algorithm)
obj.last_move = time.time()
obj.move_after = 1 # move every 1 second.
except Exception as e:
sendMsg(str(e))然后,在主循环中,每秒钟一次(使用某种计时器来跟踪1秒过去的时间),使对象弹出列表中的下一个坐标并移动到它。
看起来会是这样的:
def mainLoop():
pygame.event.pump()
keyboard(pygame.key.get_pressed())
events = pygame.event.get()
mouse(events)
for event in events:
if event.type == pygame.QUIT:
pygame.quit()
return False
if time.time() - obj.last_move > obj.move_after:
obj.last_move = time.time()
objMove(obj, obj.path.pop())
return True这样,使对象移动的代码被重新定位到This循环中,以便您仍然可以响应所有事件。
如果用户单击一个新的瓷砖,则路径将被自动覆盖,而main循环将正确地执行正确的操作。
如果您的代码结构正确,您甚至可以扩展游戏,以便它可以同时处理多个对象在瓷砖上移动,以不同的速度移动。
https://stackoverflow.com/questions/18498778
复制相似问题