所以对于这个项目,我必须让子弹击中目标。 使用度数射击子弹击中目标。 我使子弹能够射击以及随机创建的目标。 然而,每当我射击子弹时,它只是要求进入另一个学位 射击子弹。我不知道为了让子弹识别我失踪了什么 代码结尾附近的for循环和if语句。它似乎只是忽略了它。该 子弹也刚射过目标。我需要做到这一点 基本上与子弹,度数和目标创造一个直角。我想 我做到了,但显然缺少了一些东西。 另外,choice = simple.dialog也没有效果,而idk为什么。 谢谢你的帮助!
from tkinter import*
import time
import math
import random
master = Tk()
cw= 1000
ch=650
w = Canvas(master, width=cw, height=ch, bg="skyblue")
w.pack()
w.create_line(10, 635, 80, 610, fill="black", width= 15)
w.create_oval(30, 630, 60, 650, fill="brown")
target_x= 900
target_y= random.randrange(40, 610)
choice = simpledialog.askstring
w.create_oval(900, target_y, 900 -40, target_y -40, fill="pink")
while(True):
if choice == "n":
break;
w.create_oval(900, target_y, 900 -40, target_y -40, fill="pink")
dMove= w.create_oval(81, 600, 80+10, 600+10, fill= "red")
degree = simpledialog.askstring("Enter degree", "What is your guess",
initialvalue="Enter a degree")
degree= 90 - int(degree)
for i in range(90):
w.move(dMove, math.sin(math.radians(degree))*10, \
-math.cos(math.radians(degree))*10)
time.sleep(0.06)
w.update()
b = 820
a = target_y
c = b / math.cos(math.radians(degree))
c1 = math.sqrt(math.pow(b, 2) + math.pow(target_y+10, 2))
c2 = math.sqrt(math.pow(b, 2) + math.pow(target_y-10, 2))
w.update()
if c < c2 and c > c1:
print("You got it")
break
else:
print("enter degree")
答案 0 :(得分:0)
代码不断要求新的degrees
因为它总是认为你错过了目标。我不知道你当前计算你是否打击是如何工作的,所以我真的不知道如何直接修复它。但我已经提出了两种新的方法来使事物按预期发挥作用。
有两种不同的碰撞检测方法可以在这里工作。第一种是计算你是否直接从角度命中,因为在你选择拍摄角度后没有任何动态变化。根据目标的位置,您可以计算到达目标死点的角度,并计算至少部分子弹仍会击中目标的角度的最大偏移量。如果用户输入perfect_angle - max_offset
和perfect_angle + max_offset
之间的角度,则会受到影响。
from tkinter import*
import time
import math
import random
master = Tk()
cw= 1000
ch=650
w = Canvas(master, width=cw, height=ch, bg="skyblue")
w.pack()
w.create_line(10, 635, 80, 610, fill="black", width= 15)
w.create_oval(30, 630, 60, 650, fill="brown")
target_x= 900
target_y= random.randrange(40, 605)
target_radius = 20
bullet_x = 91
bullet_y = 605
bullet_radius = 10
rel_x = target_x - bullet_x
rel_y = target_y - bullet_y
perfect_angle = math.atan2(rel_y, rel_x)
distance = math.sqrt(rel_x**2 + rel_y**2)
max_angle_offset = math.asin((bullet_radius + target_radius)/ distance)
target = w.create_oval(target_x-target_radius, target_y-target_radius,
target_x+target_radius, target_y+target_radius,
fill="pink")
#print(math.degrees(perfect_angle), math.degrees(max_angle_offset))
while True:
bullet = w.create_oval(bullet_x-bullet_radius, bullet_y-bullet_radius,
bullet_x+bullet_radius, bullet_y+bullet_radius,
fill= "red")
degree = simpledialog.askstring("Enter degree", "What is your guess",
initialvalue="Enter a degree")
rad = math.radians(-float(degree))
for i in range(int(distance / 10) + 1):
w.move(bullet, math.cos(rad)*10, math.sin(rad)*10)
time.sleep(0.06)
w.update()
#print(math.degrees(rad), math.degrees(perfect_angle - rad))
if perfect_angle - max_angle_offset <= rad <= perfect_angle + max_angle_offset:
print("You got it")
break
else:
print("enter degree")
问题的另一个方法是在你移动子弹时进行碰撞检测,而不是预先进行。如果您以后想要将游戏更改为具有移动目标,或者如果您将子弹的动态更改为不易提前计算(例如添加拖动),则这对您来说会更好。我只是从Canvas
中提取子弹的坐标(平均边界以获得中心),并对目标进行距离检查。如果在任何给定的帧上我们比半径的总和更接近,我们就会命中! (我实际上是在检查距离的平方以避免昂贵的平方根,但它的工作原理相同。)
from tkinter import*
import time
import math
import random
master = Tk()
cw= 1000
ch=650
w = Canvas(master, width=cw, height=ch, bg="skyblue")
w.pack()
w.create_line(10, 635, 80, 610, fill="black", width= 15)
w.create_oval(30, 630, 60, 650, fill="brown")
target_x= 900
target_y= random.randrange(40, 605)
target_radius = 20
bullet_x = 91
bullet_y = 605
bullet_radius = 10
rel_x = target_x - bullet_x
rel_y = target_y - bullet_y
distance = math.sqrt(rel_x**2 + rel_y**2)
hit_distance = bullet_radius + target_radius
target = w.create_oval(target_x-target_radius, target_y-target_radius,
target_x+target_radius, target_y+target_radius,
fill="pink")
hit = False
while True:
bullet = w.create_oval(bullet_x-bullet_radius, bullet_y-bullet_radius,
bullet_x+bullet_radius, bullet_y+bullet_radius,
fill= "red")
degree = simpledialog.askstring("Enter degree", "What is your guess",
initialvalue="Enter a degree")
rad = math.radians(-float(degree))
for i in range(int(distance / 10) + 1):
w.move(bullet, math.cos(rad)*10, math.sin(rad)*10)
x0, y0, x1, y1 = w.coords(bullet)
x = (x1 + x0) // 2
y = (y1 + y0) // 2
if (target_x-x)**2 + (target_y-y)**2 < hit_distance**2:
hit = True
time.sleep(0.06)
w.update()
if hit:
print("You got it")
break
else:
#print(x, y, target_x, target_y,
# (target_x-x)**2 + (target_y-y)**2, hit_distance**2)
print("enter degree")
请注意,我还清理了代码中的许多其他内容,因为无法分辨出您使用的某些常量来自哪些(以及哪些常量可能不正确)。
一个特别重要的变化是,target_x
/ _y
变量和新的bullet_x
/ _y
变量始终引用 center 有问题的对象,这使数学更容易。您的旧代码通过不同方向的半径来抵消这两个形状!
您也以非常奇怪的方式使用degrees
角度。我现在只将它转换为弧度一次并让它保持正常的数学意义(角度沿着正x轴从零开始,并且当朝向正y轴旋转时增加)。这意味着子弹所采取的角度通常是负面的,但这并不会给我们带来麻烦,因为我们不打算显示它们(除了我已经注释掉的调试print
调用)。