【问题标题】:Getting Turtle in Python to recognize click events让 Python 中的 Turtle 识别点击事件
【发布时间】:2016-07-29 15:38:16
【问题描述】:

我正在尝试在 python 中制作 Connect 4,但我不知道如何获取屏幕点击的坐标,以便我可以使用它们。现在,我想画板,然后有人点击,画一个点,然后回到 while 循环的顶部,擦屏幕,然后再试一次。我尝试了几个不同的选项,但似乎没有一个适合我。

def play_game():
"""
When this function runs, allows the user to play a game of Connect 4
against another person
"""
turn = 1
is_winner = False
while is_winner == False:
    # Clears screen
    clear()
    # Draws empty board
    centers = draw_board()
    # Decides whose turn it is, change color appropriately
    if turn % 2 == 0:
        color = RED
    else:
        color = BLACK
    # Gets coordinates of click
    penup()
    onscreenclick(goto)
    dot(HOLE_SIZE, color)
    turn += 1

【问题讨论】:

  • 您尝试过哪些选项?另外,您使用的是什么 GUI 库?不知道这一点,很难回答。
  • @wirefox 大概是乌龟——至少标题是这么说的
  • @WayneWerner 是的,对我来说,乌龟并没有明确地解析为 GUI 库;他可能一直在谈论通用海龟代理并使用其他东西来绘制

标签: python turtle-graphics


【解决方案1】:

与其他答案一样,我认为它们都不能解决实际问题。您已通过在代码中引入无限循环来锁定事件:

is_winner = False
while is_winner == False:

你不能用海龟图形来做到这一点——你设置了事件处理程序和初始化代码,但将控制权交给了主循环事件处理程序。我的以下返工展示了您可以如何做到这一点:

import turtle

colors = ["red", "black"]
HOLE_SIZE = 2

turn = 0
is_winner = False

def draw_board():
    pass
    return (0, 0)

def dot(color):
    turtle.color(color, color)
    turtle.stamp()

def goto(x, y):
    global turn, is_winner

    # add code to determine if we have a winner

    if not is_winner:
        # Clears screen
        turtle.clear()
        turtle.penup()

        # Draws empty board
        centers = draw_board()

        turtle.goto(x, y)

        # Decides whose turn it is, change color appropriately
        color = colors[turn % 2 == 0]
        dot(color)

        turn += 1
    else:
        pass

def start_game():
    """
    When this function runs, sets up a new
    game of Connect 4 against another person
    """

    global turn, is_winner

    turn = 1
    is_winner = False

    turtle.shape("circle")
    turtle.shapesize(HOLE_SIZE)

    # Gets coordinates of click
    turtle.onscreenclick(goto)

start_game()

turtle.mainloop()

运行它,您将看到您描述的所需行为。

【讨论】:

  • 制作 turn 和 is_winner 全局变量而不是在 start_game 中创建它们并将它们作为参数传递给 goto 有什么好处?
  • 另外,如果我想创建其他函数来测试用户单击的位置是否已被占用或为空,我猜我会在绘制点的正上方调用这些函数。但是,如果条件为 False,我怎样才能让游戏跳过并让该人重新点击?休息在这里有用吗?
  • @HelpPlz,我们不能将turnis_winner 传递给goto(),因为该函数是由turtle.onscreenclick() 调用的,我们无法控制传递的参数。至于您的其他问题,我建议您关闭当前的问题,并使用您添加的任何其他代码提出一个新问题。
  • 嗨,我是 python 新手,这里有几个问题。您的方法没有屏幕实例化,但无论如何它都会创建一个屏幕,这是怎么回事?另外,在第 55 行,当您将“goto”声明为方法时,您将其作为参数传递,您是如何做到的?
  • @Wizard,通过执行import turtle,屏幕对象的方法也被定义为顶级函数(在 隐式 单一屏幕实例参数上)。调用turtle.onscreenclick() 是在此屏幕实例上调用onscreenclick() 的函数。正是由于这种混淆,我通常使用from turtle import Screen, Turtle 来使对象显式。就goto 而言,函数也是数据,onscreenclick() 将函数作为参数,而不是对其的调用,因此 it 可以稍后调用该函数。阅读海龟文档中的事件。
【解决方案2】:

我假设您在 python 中使用 Turtle(因此得名。) 如果是这种情况,这里有一个有用帖子的链接:Turtle in python- Trying to get the turtle to move to the mouse click position and print its coordinates 我知道我知道。我和下一个人一样讨厌只链接答案。但是我提供链接的帖子可能比我能更好地回答您的问题。

~Python先生

【讨论】:

    【解决方案3】:

    假设您使用的是标题中提到的turtle

    >>> import turtle
    >>> help(turtle.onscreenclick)
    
    Help on function onscreenclick in module turtle:
    
    onscreenclick(fun, btn=1, add=None)
        Bind fun to mouse-click event on canvas.
    
        Arguments:
        fun -- a function with two arguments, the coordinates of the
               clicked point on the canvas.
        num -- the number of the mouse-button, defaults to 1
    
        Example (for a TurtleScreen instance named screen)
    
        >>> onclick(goto)
        >>> # Subsequently clicking into the TurtleScreen will
        >>> # make the turtle move to the clicked point.
        >>> onclick(None)
    

    这意味着您的回调函数(您显然命名为 goto)将采用两个参数,一个 X 和 Y 位置。

    import turtle
    
    def goto(x, y):
        print('Moving to {}, {}'.format(x,y))
        turtle.goto(x, y)
    
    turtle.onscreenclick(goto)
    turtle.goto(0,0)
    

    您所做的每一次点击都会将海龟移动到不同的位置。请注意,turtle 已经有一个事件循环 - 您不需要自己的一个。只需响应点击即可。

    【讨论】:

      【解决方案4】:

      基本上,您需要为 onclick 和 onscreenclick 函数添加一个“x”和“y”参数。您不需要使用它们,它们只是虚拟参数。填写完这些点击就没有问题了:

      window = turtle.Screen()
      

      这个函数使用 x, y 参数,因为我保存点击是为了指定一个用海龟填充的区域

      def on_left_click_save_coordinates(x, y):
          global counter, Fill_COORS1, Fill_COORS2
          counter += 1
          print(x, y)
      
          if counter == 1:
              Fill_COORS1 = (x, y)
          elif counter == 2:
              Fill_COORS2 = (x, y)
              counter = 0
      

      这个不使用x,y参数,因为它们是假人,这个用于允许多个选项,其中一个退出,另一个告诉乌龟填写上面点击保存的指定区域。

      def on_right_click_open_options(x, y):
          global going
          last_color = options(window, filler, Fill_COORS1, Fill_COORS2, LAST_BLOCK_USED)
          if type(Last_COLOR) == type(bool):
              going = True
      
      
      
      window.onscreenclick(on_click, btn=1)
      window.onscreenclick(open_options, btn=3)
      

      这是我的代码的 sn-p 示例。希望这可以帮助。 btn 3 指右键 btn 1 是默认值,不需要指定,指的是左键

      btn 2 是滚轮点击,不是滚动。

      很抱歉,如果这不是最好的格式,这是我第一次在 stackoverflow 上发帖。希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        • 2014-01-26
        • 2020-12-10
        • 2023-02-22
        • 1970-01-01
        相关资源
        最近更新 更多