我有两个问题需要帮助修复。一个是当Pong球击中左侧或右侧的中间时 - 它猛烈地抽搐直到桨在它上面移动。它应该做的是,它应该向外反弹并远离墙壁,而不是猛烈地抽搐。
第二个问题与桨的击中框有关。现在,如果Pong球击中桨的中间,它的行为与预期的一样,但如果它击中顶部边缘或底部边缘,它会使球相位通过。
我想知道是否有人可以帮助我确定这些问题发生的原因,以及如何纠正这些问题。
from tkinter import *
import random
from math import *
##MAIN GAME PART##
window = Tk()
canvas = Canvas(window,width=400,height=400)
canvas.pack()
sideX = -1
sideY = 0
##FUNCTIONS##
def movePaddles(event):
key=event.keysym
if key == 'Up':
canvas.move(PaddleTwo,0,-10)
elif key == 'Down':
canvas.move(PaddleTwo,0,10)
if key == 'w':
canvas.move(PaddleOne,0,-10)
elif key == 's':
canvas.move(PaddleOne,0,10)
def distance(target1,target2):
target1coords = canvas.coords(target1)
target2coords = canvas.coords(target2)
x1 = (target1coords[0] + target1coords[2] ) / 2
y1 = (target1coords[1] + target1coords[3] ) / 2
x2 = (target2coords[0] + target2coords[2]) / 2
y2 = (target2coords[1] + target2coords[3]) / 2
d = sqrt( (x2-x1)** 2 + (y2-y1)** 2)
return d
def checkCollisions():
global sideX
global sideY
for e in PaddleList:
if distance(PingPongBall,e) < 20:
if e == 1:
sideX = 1
sideY = random.randint(0,1)
elif e == 2:
sideX = -1
sideY = random.randint(0,1)
canvas.move(PingPongBall,sideX,sideY)
def moveBall():
##Found no other way of changing these variables without global##
global sideY
global sideX
for e in BallList:
xcor = canvas.coords(e)[0]
ycor = canvas.coords(e)[1]
if xcor >= 400: ##Right side of screen
if sideY == -1:
sideY = 1
sideX = 1
elif sideY == 1:
sideY = -1
sideX = -1
elif sideX == 1:
sideX = -1
if xcor <= 0: ##Left side of screen
if sideY == -1:
sideY = 1
sideX = 1
elif sideY == 1:
sideY = -1
sideX = -1
elif sideX == -1:
sideX = 1
if ycor >= 400: ##Top of screen
if sideY == -1:
sideY = 1
elif sideY == 1:
sideY = -1
if ycor <= 0: ##Bottom of screen
if sideY == -1:
sideY = 1
elif sideY == 1:
sideY = -1
##SET UP TIMER AKA INFINITE LOOP WITHOUT LAG##
timeLeft = 1
##PADDLES AND OTHER STUFF##
PaddleOne = canvas.create_rectangle(10 ,150 ,25 ,250 ,fill='blue')
PaddleTwo = canvas.create_rectangle(400,150 ,385 ,250 ,fill='blue')
PingPongBall = canvas.create_rectangle(200, 200, 210 ,210 ,fill='red')
PaddleList = [PaddleOne,PaddleTwo]
BallList = [PingPongBall]
Target = PaddleList[0]
##KEY BINDINGS##
canvas.bind_all('<Key>',movePaddles)
##INFINITE LOOP##
while timeLeft > 0:
checkCollisions()
moveBall()
window.update()
答案 0 :(得分:0)
考虑这种控制结构:
if xcor >= 400: ##Right side of screen
if sideY == -1:
sideY = 1
sideX = 1
elif sideY == 1:
sideY = -1
sideX = -1
elif sideX == 1:
sideX = -1
让我们来看看可能的场景:
球在上升时击中右墙(sideY == -1)
xcor>=400
仍为True。这将解释你的毛刺行为,当球接触球时它会被覆盖(我会在片刻解释一下),但实际上你的条件应该是这样的:
if xcor >= 400: ##Right side of screen
#make it go left
sideX = -1
if xcor <= 0: ##Left side of screen
#make it go right
sideX = 1
if ycor >= 400: ##Bottom of screen
#make it go up
sideY = -1
if ycor <= 0: ##Top of screen
#make it go down
sideY = 1
至于你的hitbox,你只是检查从球的中心到球拍中心的距离是否小于20:
if distance(PingPongBall,e) < 20:
这只占桨的中间40%左右,这不是你想要的,你想知道它们是否重叠可以通过使用in
来完成运算符,.find_overlapping
方法和.bbox
方法(这两种方法都是described here)
def is_overlapping(tag1,tag2):
return tag1 in canvas.find_overlapping(*canvas.bbox(tag2))
然后您可以通过以下方式检查球拍是否接触球:
if is_overlapping(PingPongBall,e):