简体   繁体   中英

Can't draw parabolic curve correctly with turtle graphics

I'm making a game like 'angry bird'.

There are two input:power and angle. I apply those inputs to parabolic curve.

My turtle flies, making a parabolic curve. and my turtle have to hit the target, but my turtle draws strange curve when angle is greater than 46, angle is 30, 40 etc...

I don't know where is problem....here is my code:

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()

I think create_target() and create_turtle() , and setting() don't have problem...

Below, I reduce your code to a MVCE (minimal, complete, and verifiable example) to examine the parabolic curve drawing code. The problem I found with it is the usual one of the difference between degrees and radians . The Python math library thinks in radians but provides a conversion function for degrees. The Python turtle library thinks in degress, by default, but can switch to radians using turtle.radians() . Either way is fine but the usage has to be consistent:

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()

EXAMPLE

> 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
> 

在此处输入图片说明

Now, what more do you want it to do parabolic curve-wise?

Oh Thanks thanks really thanks.......!!!! but, i have one more problem. that is, the 'if' sentence in throw_turtle function. my intention for using that 'if' sentence is for check and end the game. but in fact, the user can not exactly correct coordinate of target. so it is impossible that end the game. so the game is endless....

to avoid that, i re-write like this.

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...")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM