类和tkinter球运动
问题描述:
我有以下代码,它设法使球在屏幕的顶端和底端反弹。类和tkinter球运动
工作代码为反弹顶部和底部的
from tkinter import *
import random
import time
class Ball:
def __init__(self,canvas,color):
self.canvas=canvas
self.id=canvas.create_oval(30,30,50,50,fill=color)
self.canvas.move(self.id,100,200)
#ADD THESE LINES TO OUR __INIT__ METHOD
self.x=0
self.y=-1
self.canvas_height=self.canvas.winfo_height()
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[1] <=0:
self.y=1
if pos[3] >=self.canvas_height:
self.y=-1
def main():
tk=Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0,0)
tk.wm_attributes("-topmost",1)
canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
ball1=Ball(canvas,'green')
while 1:
tk.update()
ball1.draw() #call the ball draw method here
time.sleep(0.01)
main()
当试图做到这一点的左到右(左,右墙反弹),我不能完全弄清楚逻辑或解决我的错误如下所示。
我已经试过了弹跳左右
self.x=1 #set the object variable x to 0 (don't move the ball horizontally)
self.y=-0 #set the object variable y to -1 (this means keep moving the ball UP on initilisation)
self.canvas_height=self.canvas.winfo_height() #set the canvas height by calling the canvas function winfo_height (it gives us the current canvas height)
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos=self.canvas.coords(self.id)
if pos[2] <=0: #if you hit the top of the screen then stop subtracting 1 as defined in the __init__ method and therefore stop moving up -reverse directions
self.x=-1
if pos[3] >=self.canvas_height: #if the bottom coordinates are greater or equal to canvas height, then reverse again, and set y back to -1 (go up)
self.x=1
一个答案,
可能有人提供简单的解释为所需要的逻辑解决问题,坐标来自哪里以及pos [0],pos [1]等指的是什么。我有一个想法,但它不是很清楚,并且会从某种清晰度中受益(就像我想象的那样)。
所以,我在解释+编码解决方案修复(使用我的原始代码)来解决问题。
答
代码几乎是正确的。事实上,一时的进一步思考可能会给你答案是非常正确的。您的'移动x'代码已经从'移动y'代码复制粘贴,但没有足够改变。谨防这样做。
回应'pos pos [0]等于什么意思',我邀请您阅读Get coords of an oval in Tkinter。 通常,矩形的坐标为(左,上,右,下)。
你会发现,我已经改变了以下一些事情,除了纠正你的错误:
- 我已经改变了
x
&y
变量vx
和vy
。数值是球的速度,而不是位置。 - 函数名现在是
move
,而不是draw
,因为该函数移动并且不绘制。 -
alive
变量与tk.protocol
行为程序提供了一种在用户关闭窗口后清理的整洁方式。
。
from tkinter import *
import random
import time
class Ball:
def __init__(self,canvas,color):
self.alive = True
self.canvas = canvas
self.id = canvas.create_oval(30, 30, 50, 50, fill=color)
self.canvas.move(self.id, 100, 200)
#ADD THESE LINES TO OUR __INIT__ METHOD
self.vx = 1
self.vy = -1
self.canvas_width = self.canvas.winfo_width()
self.canvas_height = self.canvas.winfo_height()
def move(self):
self.canvas.move(self.id, self.vx, self.vy)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.vx = 1
if pos[2] >= self.canvas_width:
self.vx = -1
if pos[1] <= 0:
self.vy = 1
if pos[3] >= self.canvas_height:
self.vy = -1
def kill(self):
self.alive = False
def main():
tk = Tk()
tk.title("My 21st Century Pong Game")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, bg="white", width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()
tk.protocol("WM_DELETE_WINDOW", lambda: ball1.kill())
ball1 = Ball(canvas, 'green')
while ball1.alive:
tk.update()
ball1.move() #call the ball move method here
time.sleep(0.01)
tk.destroy()
if __name__ == "__main__":
main()