首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用游戏连续捕获鼠标事件

用游戏连续捕获鼠标事件
EN

Stack Overflow用户
提问于 2013-08-28 21:47:00
回答 1查看 1.5K关注 0票数 0

我使用吡游构建一个简单的游戏,并有以下主循环,其中mouse()是一个捕获和处理鼠标事件的函数,keyboard()用于键盘事件:

代码语言:javascript
复制
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()调用了以下函数

代码语言:javascript
复制
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()函数:

代码语言:javascript
复制
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: ...

我对多线程不太熟悉,我也不认为它应该与游戏一起使用,但这是我唯一能想到的。有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-28 23:25:01

您可以尝试修改对象,使其具有类似于objReach列表的内容,而不是在多线程中乱动,直接导致对象在obj函数中移动并阻塞主循环。它基本上是一个队列,其中包含要移动到的每个位置的坐标。

然后,您要做的是,当鼠标被单击时,使用您的路径查找算法来查找对象应该沿着的路径,并用它替换队列:

代码语言:javascript
复制
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秒过去的时间),使对象弹出列表中的下一个坐标并移动到它。

看起来会是这样的:

代码语言:javascript
复制
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循环将正确地执行正确的操作。

如果您的代码结构正确,您甚至可以扩展游戏,以便它可以同时处理多个对象在瓷砖上移动,以不同的速度移动。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18498778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档