如何使对象跟随tkinter中的鼠标

时间:2016-09-15 17:18:06

标签: python tkinter mouse tkinter-canvas

我正在尝试制作agar.io克隆并且我有鼠标的坐标,但我不知道如何让玩家向鼠标移动而不是直接转向鼠标。到目前为止,我有这个来获取鼠标的坐标:

def mouseCoords(self):
    rawMouseX, rawMouseY =   tk.winfo_pointerx(), tk.winfo_pointery()
    self.mousecoords = rawMouseX  - tk.winfo_rootx(), rawMouseY - tk.winfo_rooty()
    return self.mousecoords

我想要一种方法来使用两个对象的tag将点和文本移向鼠标。

编辑:

我尝试使用此代码使点朝向鼠标移动,但它只在8个不同的方向上移动,而不是直接朝向鼠标移动。

这是完整的(未完成的)代码:

from tkinter import *
import time, random, numpy



class PlayerSprite:
    def __init__(self, canvas):
        self.canvas = canvas
        self.endgame = False
        self.id = self.canvas.create_oval(350, 350, 400, 400, tag='User', fill=random.choice(colors))
        self.id2 = self.canvas.create_text(375, 375, text=nick, font=('Helvetica', 15), tag='User')
    def coords(self):
        print(self.canvas.coords('User'))
        return self.canvas.coords('User')
    def mouseCoords(self):
        rawMouseX, rawMouseY =   tk.winfo_pointerx(), tk.winfo_pointery()
       self.mousecoords = rawMouseX  - tk.winfo_rootx(), rawMouseY - tk.winfo_rooty()
        return self.mousecoords
    def moveTowardMouse(self):   #This is the function that I don't know how to complete
        selfx, selfy = self.coords()
       mousex, mousey = self.mousecoords
        movex = (mousex-selfx)
        movey = (mousey-selfy)
        if movex > 0 and movey > 0:
            self.canvas.move('User', 2, 2)
        elif movex > 0 and movey < 0:
            self.canvas.move('User', 2, -2)
        elif movex < 0 and movey > 0:
            self.canvas.move('User', -2, 2)
        elif movex < 0 and movey < 0:
            self.canvas.move('User', -2, -2)
        elif movex == 0 and movey > 0:
            self.canvas.move('User', 0, 2)
        elif movex == 0 and movey < 0:
            self.canvas.move('User', 0, -2)
        elif movex > 0 and movey == 0:
            self.canvas.move('User', 2, 0)
        elif movex < 0 and movey == 0:
            self.canvas.move('User', -2, 0)
        elif movex == 0 and movey == 0:
            pass
        else:
            pass

tk = Tk()
nick = simpledialog.askstring('nickname', 'Nickname')
tk.title("My Agar.io Clone")
tk.wm_attributes('-topmost', 1)
tk.resizable(0, 0)
canvas = Canvas(tk, width=750, height=750)
center =  (canvas.winfo_reqwidth()/2), (canvas.winfo_reqheight()/2)
colors = ['red', 'blue', 'green', 'yellow']

canvas.pack()

player = PlayerSprite(canvas)
player.mouseCoords()

while player.endgame == False:
    try:
        player.moveTowardMouse()
        player.mouseCoords()
        tk.update_idletasks()
        tk.update()
        time.sleep(.01)
    except KeyboardInterrupt:
        print('CRL-C recieved, quitting')
        tk.quit()
        break

2 个答案:

答案 0 :(得分:1)

要让玩家向各个方向移动,您需要使用玩家和鼠标坐标与参考轴的角度。然后使用该角度找到移动玩家的x和y距离。

我使用atan2模块中的math方法来计算角度。

修改后的代码

## imports for Python 2.7, change as appropriate
from Tkinter import *
import tkSimpleDialog as simpledialog
import time, random, numpy, math


class PlayerSprite:
    def __init__(self, canvas):
        self.canvas = canvas
        self.endgame = False
        self.id = self.canvas.create_oval(350, 350, 400, 400, tag='User', fill=random.choice(colors))
        self.id2 = self.canvas.create_text(375, 375, text=nick, font=('Helvetica', 15), tag='User')
    def coords(self):
        print(self.canvas.coords('User'))
        return self.canvas.coords('User')
    def mouseCoords(self):
        rawMouseX, rawMouseY =   tk.winfo_pointerx(), tk.winfo_pointery()
        self.mousecoords = rawMouseX  - tk.winfo_rootx(), rawMouseY - tk.winfo_rooty()
        return self.mousecoords
    def moveTowardMouse(self):   # Problem function?
        ## Use center of the of the oval/player as selfx, selfy
        selfx, selfy = (self.coords()[0]+self.coords()[2])/2, (self.coords()[1]+self.coords()[3])/2
        mousex, mousey = self.mousecoords
        movex = (mousex-selfx)
        movey = (mousey-selfy)

        speed = 2 ## Player speed
        theta = math.atan2(movey, movex) ## angle between player and mouse position, relative to positive x

        ## Player speed in terms of x and y coordinates
        x = speed*math.cos(theta)
        y = speed*math.sin(theta)

        self.canvas.move('User', x, y)


tk = Tk()
nick = simpledialog.askstring('nickname', 'Nickname')
tk.title("My Agar.io Clone")
tk.wm_attributes('-topmost', 1)
tk.resizable(0, 0)
canvas = Canvas(tk, width=750, height=750)
center =  (canvas.winfo_reqwidth()/2), (canvas.winfo_reqheight()/2)
colors = ['red', 'blue', 'green', 'yellow']

canvas.pack()

player = PlayerSprite(canvas)
player.mouseCoords()

while player.endgame == False:
    try:
        player.moveTowardMouse()
        player.mouseCoords()
        tk.update_idletasks()
        tk.update()
        time.sleep(.005)
    except:# KeyboardInterrupt:
        print('CRL-C recieved, quitting')
        tk.quit()
        break

答案 1 :(得分:0)

我明白了:

def moveTowardMouse(self):
    selfx, selfy = self.coords()
    mousex, mousey = self.mousecoords
    directDist = math.sqrt(((mousex-selfx) ** 2) + ((mousey-selfy) ** 2))
    self.speed = 4
    movex = (mousex-selfx) / directDist
    movey = (mousey-selfy) / directDist
    self.canvas.move('User', movex*self.speed, movey*self.speed)