【问题标题】:Can't draw parabolic curve correctly with turtle graphics无法使用海龟图形正确绘制抛物线
【发布时间】:2017-03-16 03:12:42
【问题描述】:

我正在制作一款类似“愤怒的小鸟”的游戏。

有两个输入:功率和角度。 我将这些输入应用于抛物线。

我的乌龟飞起来,形成一条抛物线。我的乌龟必须命中目标, 但是当角度大于 46、角度为 30、40 等时,我的乌龟会画出奇怪的曲线...

我不知道问题出在哪里......这是我的代码:

import turtle
import random
import math

g=9.80665
origin_x=-480
origin_y=-180
flag=False


def create_target():

    x=random.randint(0,500)
    y=random.randint(-200,0)
    target=turtle.Turtle()
    target.hideturtle()
    target.penup()
    target.goto(x,y)
    target.shape('square')
    target.color('red')
    target.showturtle()
    return target

def create_turtle():

    homework=turtle.Turtle()
    homework.hideturtle()
    homework.penup()
    homework.speed(0)
    homework.goto(origin_x,origin_y)
    homework.pendown()
    homework.shape('turtle')
    homework.color('blue')
    homework.left(45)
    homework.showturtle()
    return homework

def setting():
    '''drawing back ground lines'''
    setting=turtle.Turtle()
    setting.hideturtle()
    setting.speed(0)
    turtle.colormode(255)
    setting.pencolor(214,214,214)

    for y in range(100,-101,-100):
        setting.penup()
        setting.goto(-500,y)
        setting.pendown()
        setting.goto(500,y)

    for x in range(-375,500,125):
        setting.penup()
        setting.goto(x,200)
        setting.pendown()
        setting.goto(x,-200)


def throw_turtle(turtle,target):
    angle=int(input("Enter Angle:"))
    power=int(input("Enter Power:"))
    '''
    parabola fomula:
        x coordinate: speed(in here, that is power) * cos(anlge)*time
        y coordinate: speed*sin(angle)*time - (gravity speed*time**2)/2
    '''
    for time in range(1,20):
        # the origin fomula is for the situation that starts from (0,0). so I think
        # I should  compensate it, but is it right?
        x=power*math.cos(angle)*time + origin_x
        y=power*math.sin(angle)*time - (((time**2)*g)/2) + origin_y
        if x<origin_x:  # I think it has problem...
            x-=origin_x

        turtle.goto(x,y)
        turtle.stamp()    #this is for testing
        if (x==target.xcor()) and (y==target.ycor()):
            print("******Target is HIT!!! ******")
            print("End of Game")
            flag=True
            break
    else:
        print("You missed...")


turtle.setup(1000,400)
windo=turtle.Screen()
windo.title('Angry Turtle')
setting()

#__main

my_turtle=create_turtle()
while flag==False:
    target=create_target()
    my_turtle=create_turtle()
    my_turtle.speed(6)

    throw_turtle(my_turtle,target)
    my_turtle.hideturtle()
    target.hideturtle()

我认为create_target()create_turtle()setting() 没有问题...

【问题讨论】:

    标签: python drawing turtle-graphics


    【解决方案1】:

    下面,我将您的代码简化为 MVCE(最小、完整且可验证的示例)来检查抛物线绘制代码。我发现它的问题是 degreesradians 之间的常见差异之一。 Python 数学库以弧度为单位,但提供了度数的转换函数。默认情况下,Python 海龟库以递减方式思考,但可以使用turtle.radians() 切换到弧度。无论哪种方式都可以,但用法必须一致:

    from turtle import Turtle, Screen
    import math
    import random
    
    G = 9.80665
    origin_x = -480
    origin_y = -180
    
    def create_turtle():
    
        homework = Turtle(shape='turtle')
        homework.hideturtle()
        homework.penup()
        homework.goto(origin_x, origin_y)
        homework.pendown()
        homework.speed(0)
        homework.left(45)
        homework.showturtle()
    
        return homework
    
    def throw_turtle(turtle):
    
        angle = int(input("Enter Angle (in degrees): "))
        power = int(input("Enter Power: "))
    
        # parabola formula:
        #   x coordinate: speed(in here, that is power) * cos(angle)*time
        #   y coordinate: speed*sin(angle)*time - (gravity speed * time**2)/2
    
        for time in range(1, 20):
    
            x = power * math.cos(math.radians(angle)) * time + origin_x
            y = power * math.sin(math.radians(angle)) * time - (((time ** 2) * G) / 2) + origin_y
    
            turtle.goto(x, y)
            turtle.stamp()  # this is for testing
    
    
    window = Screen()
    window.setup(1000, 400)
    
    for _ in range(3):
        my_turtle = create_turtle()
    
        my_turtle.color(random.choice(['red', 'green', 'blue', 'purple', 'black']))
    
        throw_turtle(my_turtle)
    
    window.exitonclick()
    

    示例

    > python3 test.py
    Enter Angle (in degrees): 30   
    Enter Power: 120
    Enter Angle (in degrees): 45
    Enter Power: 90
    Enter Angle (in degrees): 60
    Enter Power: 90
    > 
    

    现在,您还希望它在抛物线方面做些什么?

    【讨论】:

    • 哦谢谢谢谢真的谢谢.......!!!!但是,我还有一个问题。也就是说,
    【解决方案2】:

    哦谢谢谢谢真的谢谢.......!!!! 但是,我还有一个问题。即 throw_turtle 函数中的“if”语句。 我使用“if”语句的目的是检查并结束游戏。但实际上,用户并不能准确地正确定位目标坐标。所以结束游戏是不可能的。所以游戏是无止境的......

    为了避免这种情况,我这样重写。

    def throw_turtle(turtle,target):
        angle=int(input("Enter Angle:"))
        power=int(input("Enter Power:"))
    
        '''
        parabola fomula: x coordinate: speed(in here, that is power) * cos(anlge)*time
                                  y coordinate: speed*sin(angle)*time - (gravity speed*time**2)/2'''
        for time in range(1,20):
            x=power*math.cos(math.radians(angle))*time + origin_x         #the origin fomula is for the situation that starts from (0,0). so i think i should  compensate it. but.. is it right?
            y=power*math.sin(math.radians(angle))*time - (((time**2)*g)/2) + origin_y     
    
            turtle.goto(x,y)
            turtle.stamp()    #this is for testing        min_target_x=target.xcor()-1
    
            max_target_x=target.xcor()+1     #the '1' means target's size
            min_target_y=target.ycor()-1 
            max_target_y=target.ycor()+1
            min_target_y=target.ycor()-1
    
            if ((turtle.xcor()>=min_target_x) or (turtle.xcor()<=max_target_x)) and ((turtle.ycor()>=min_target_y) or (turtle.ycor()<=max_target_y)):
    
                print("******Target is HIT!!! ******")
                print("End of Game")
                flag=True
                break
        else:     
            print("You missed...")
    

    【讨论】:

    • 您的 max_* 和 min_* 逻辑搞砸了。首先,您的作业中有一个复制粘贴错误。其次,您使用的目标太紧-不要仅将最大值基于位置,而是基于位置加上宽度和高度。如果需要,然后添加一些以使目标更大。最后,您的 if((()or())and(()or())) 逻辑似乎是错误的,可能希望是 if((()and())and()and()))。
    • 哦,谢谢!我想我可以解决它...!我祝福你...♥^_^
    猜你喜欢
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2022-11-21
    相关资源
    最近更新 更多