I'm doing a homework and I want to know how can I move turtle to a random location a small step each time. Like can I use turtle.goto() in a slow motion?
Someone said I should use turtle.setheading() and turtle.forward() but I'm confused on how to use setheading() when the destination is random.
I'm hoping the turtle could move half radius (which is 3.5) each time I update the program to that random spot.
You use the term half radius twice in your question's title and text, but never really explain it. For purposes of your question, we're just talking about some arbitrary small distance -- correct?
I would avoid import time and time.sleep() as they work against an event-driven world like turtle. Instead, I would use turtle's own ontimer() method to keep things in synch:
from turtle import Screen, Turtle
from random import randrange
HALF_RADIUS = 3.5 # unexplained constant
DELAY = 1000 # milliseconds
WIDTH, HEIGHT = 640, 480
CURSOR_SIZE = 20
def forward_slowly(distance):
if distance > 0:
turtle.forward(min(distance, HALF_RADIUS))
remaining = max(distance - HALF_RADIUS, 0)
screen.ontimer(lambda d=remaining: forward_slowly(d), DELAY)
else:
screen.ontimer(move_target, DELAY)
def move_target():
x = randrange(CURSOR_SIZE - WIDTH//2, WIDTH//2 - CURSOR_SIZE)
y = randrange(CURSOR_SIZE - HEIGHT//2, HEIGHT//2 - CURSOR_SIZE)
target.goto(x, y)
target.pendown()
turtle.setheading(turtle.towards(target))
forward_slowly(turtle.distance(target))
screen = Screen()
screen.setup(WIDTH, HEIGHT)
turtle = Turtle('turtle')
turtle.speed('slowest')
turtle.width(3)
target = Turtle('turtle')
target.speed('fastest')
target.color('red')
target.penup()
move_target()
screen.exitonclick()
(Any resemblence to a Pepé Le Pew cartoon is purely coincidental.)
Do you mean that you want to move a small step, stop, and repeat? If so, you can ‘import time’ and add ‘time.sleep(0.1)’ after each ‘forward’
Related
I am trying to make this game where once you hit the borders of the box the turtle will return to the position it was at directly before it hit the border of the box. I am pretty new so any help would be appreciated. So far I have if y cord is greater than the box it goes back to right before it hit but it doesn't seem to be working.
import turtle
wn = turtle.Screen()
wn.bgcolor('black')
line = turtle.Turtle()
line.goto(-450,-15)
line.speed(9999)
line.pendown
line.color('white')
line.forward(850)
line.left(90)
line.forward(400)
line.left(90)
line.forward(850)
line.left(90)
line.forward(410)
line.color('black')
fred = turtle.Turtle()
fred.penup()
fred.goto(-430, 0)
fred.shape('square')
fred.color('white')
fred.penup()
fred.delay = 0.1
fred.direction = "Stop"
#Set Up (Controls)
wn.listen()
def ahead():
fred.forward(10)
def behind():
fred.backward(10)
if fred.ycor() < -500:
fred.goto(0, -500)
if fred.ycor() > 500:
fred.goto(0, 500)
wn.onkey(behind,"a")
wn.onkey(ahead,"d")
wn.mainloop()
You should use if inside functions - and values in if you may have to calculate manually.
def ahead():
fred.forward(10)
#print(fred.xcor())
if fred.xcor() > 430 - 50: # minus turtle width
fred.backward(10)
def behind():
fred.backward(10)
#print(fred.xcor())
if fred.xcor() < -430 :
fred.forward(10)
But problem will be if you will have more elements which should stop turtle.
turtle doesn't have function to detect collisions and you may have to access tkinter functions for this or you would have to create own function which checks xcor, ycor with coordinates from some list. And list should have coordinates for all objects. And this may need to calculate coordinates manually.
turtle is nice for drawing figures but not for games. There are better modules - like PyGame, Arcade, PGzero (PyGame Zero)
With python, I'm trying to make a function that gets the colour that the turtle is currently on top of. I've found that turtle.pos() gives me coordinates of its location, how can I use those coordinates to get colours?
I think the best way to do this would be using the steps shown here: https://www.kite.com/python/answers/how-to-find-the-rgb-value-of-a-pixel-in-python
One way to go about this is to append every turtle you create into a list, then in your main game loop, loop through the list of turtle to see if the turtle.distance() is smaller than a certain value:
import turtle
wn = turtle.Screen()
turtles = []
yertle = turtle.Turtle('turtle')
while True:
wn.tracer(0)
for t in turtles:
if yertle.distance(t) < 20 and yertle != t:
print(f'Touched {t.color()}')
wn.update()
In the above code I used if yertle.distance(t) < 20 which is for when all the turtles are the default size: 20.
I am trying to generate a list of random Y coordinates for a turtle graphics program that needs to draw flowers, but to prevent the flowers from drawing over each other I need to draw them from back to front. What I need to do is sort the random list from largest to smallest, then have it draw the flowers in that order.
I have already set up the program to generate 9 random numbers and sort them from largest to smallest, but I don't know how to draw the numbers from that list in order and assign them the Y value of the flower
This is my code for generating the random list:
def draw_stem(t,StemX,StemY):
StemYcoordinates=random.sample(range(-200,0),9)
sorted(StemYcoordinates, key=int)
But I am having trouble connecting it to this part of the code where it goes to the xy position where I want the flower to be drawn
for i in range(9):
t.setheading(90)
t.pensize(7-(StemYcoordinate//40))
t.color("#39ff14")
t.penup()
t.goto(StemX,StemYcoordinates)
t.down()
any help would be greatly appreciated
I think for your code, you will need to use the setpos() method.
This method treats the screen in turtle like a coordinate plane with four quadrants.
Using this, set the x and y coordinates accordingly, or randomly if you want to.
For example, this puts the turtle in a random spot every time you run it:
from turtle import *
t = Turtle()
t.penup()
from random import randint
x = randint(-200, 200)
y = randint(-200, 200)
t.setpos(x, y)
Hope this Helps!!!
Based on the description of your problem, you seem to want something like:
from turtle import Screen, Turtle
from random import sample, random
RADIUS = 100
PETALS = 10
def draw_petal(t, radius):
heading = t.heading()
t.circle(radius, 60)
t.left(120)
t.circle(radius, 60)
t.setheading(heading)
def draw_flower(t):
for _ in range(PETALS):
draw_petal(t, RADIUS)
t.left(360 / PETALS)
def draw_flowers(t, stemX):
stemYcoordinates = sorted(sample(range(-200, 0), 9))
for stemYcoordinate in stemYcoordinates:
t.setheading(90)
t.pensize(7 + stemYcoordinate // 40)
t.color(random(), random(), random())
t.penup()
t.goto(stemX, stemYcoordinate)
t.pendown()
draw_flower(t)
screen = Screen()
turtle = Turtle(visible=False)
turtle.speed('fastest') # because I have no patience
draw_flowers(turtle, 0)
screen.exitonclick()
But if this isn't what you're looking for, take the time to reread and edit your question to clarify what you want to do. Add more (if not all) of the code you've written so far, to make it clear what you need help with.
I am trying to double the size of the turtle in the window every time I press x on my keyboard. I tried using .turtlesize(2,2,2), but that's not right. I need to double every time the key is pressed so if the turtle size is (1,1,1), it will become (2,2,2) then (4,4,4) and so on each time I press x.
This is what I have so far:
import turtle
turtle.setup(500,500)
wn = turtle.Screen()
wn.title("Commands")
wn.bgcolor("black")
tess = turtle.Turtle()
tess.shape("triangle")
tess.color("red")
tess.left(90)
def increaseSize():
size = tess.turtlesize()
increase = tuple([2 * num for num in size])
tess.turtlesize(increase) #this is where the error occurs
wn.onkey(increaseSize, "x")
wn.listen()
Change this line:
tess.turtlesize(increase)
to instead be:
tess.turtlesize(*increase)
turtlesize() wants three separate values but you were passing one tuple of three values so we need to spread that tuple across the argument list.
The default size of a Turtle object is 20 pixels, which is the equivalent of the ratio 1 when resizing the Turtle.
For example:
import turtle
tess = turtle.Turtle()
print(tess.shapesize())
Output:
(1.0, 1.0, 1)
The first two 1.0s in the tuple represents how many units 20 pixels the Turtle's width and height are, and the last 1 represents the width of the Turtle's outline.
You won't be able to see the outline if you only pass one argument into the tess.color() brackets, because by default, there is no outline.
To increase the Turtle's size, simply pass in the number of 20 pixels you want each of the Turtle's dimensions to be into tess.shapesize() or tess.turtesize():
import turtle
tess = turtle.Turtle()
tess.shapesize(2, 3, 1) # Sets the turtle's width to 60px and height to 90px
The other answer points out that the turtlesize function does not take in an
array; it takes in ints or floats, so you'll need to unpack the tuple with a *
when you pass the tuple into the function.
In your increaseSize function, the tuple and [] wrappers aren't necessary,
and only wastes efficiency. Simply use ():
def increaseSize():
size = tess.turtlesize()
increase = (2 * num for num in size)
tess.turtlesize(*increase)
On top of your code there is
turtle.setup(500,500)
wn = turtle.Screen()
Since you defined a Screen object, wn, it's cleaner to use wn.setup() instead of turtle.setup():
wn = turtle.Screen()
wn.setup(500,500)
All together:
import turtle
wn = turtle.Screen()
wn.setup(500,500)
tess = turtle.Turtle("triangle")
tess.color("red")
tess.left(90)
def increaseSize():
size = tess.turtlesize()
increase = (2 * num for num in size)
tess.turtlesize(*increase)
wn.onkey(increaseSize, "x")
wn.listen()
Output:
I am trying to learn python and so far it has gone well. However i keep getting an infinite loop error after a while of my code running. The code given below is that of a star with 7 angles.
import turtle
n = 7
def drawStar(t, sz, s):
"""Get turtle t to draw a star of sz sides, s size"""
for i in range(sz):
t.right(180)
t.forward(s)
t.right(180/n)
wn = turtle.Screen()
wn.bgcolor("lightgreen")
alex = turtle.Turtle()
alex.color("hotpink")
#
n = 7
for i in range(15):
alex.up()
alex.forward(30)
alex.right(144)
alex.down()
print(n)
drawStar(alex,n,30)
wn.exitonclick()
Folks have pointed out that your use of range(15) instead of range(5) redraws the stars three times making your program take longer. (Sufficiently that you mistook it for an infinite loop.)
There are additional ways to improve the performance of the program. The easy bandaid is to add alex.speed("fastest") which will cause the turtle to race through the drawing and end sooner.
However, if we instead do alex.speed("slowest") we'll see the other problem with the program: the turtle spends too much time turning one way and turning back the other. At times it turns the long way around a circle instead of the short way. So let's rework the code to address this issue:
from turtle import Turtle, Screen
N = 7
def drawStar(turtle, sides, size):
""" Get turtle turtle to draw a star of sides sides of size size """
turtle.right(18)
for _ in range(sides - 1):
turtle.forward(size)
turtle.right(6 * 180 / sides)
turtle.forward(size)
screen = Screen()
screen.bgcolor("lightgreen")
alex = Turtle()
# alex.speed("fastest")
alex.color("hotpink")
for i in range(5):
alex.up()
alex.forward(30)
alex.down()
drawStar(alex, N, 30)
alex.left(8)
alex.hideturtle()
screen.exitonclick()
Under normal speed, and only 5 iterations instead of 15, this optimization of turns knocks 1/3 off the time it takes to draw the stars! Yet produces the same result: