I have two turtles in my program. An animation happened where they collide together, but I would like one turtle to be on top of the other like this:
So, my question is - how can I make this happen - is there a simple line of code such as: turtle.front(), if not what is it?
I discuss this briefly in my response to Make one turtle object always above another where the rule of thumb for this simple situation is:
last to arrive is on top
Since Python turtle doesn't optimize away zero motion, a simple approach is to move the turtle you want on top by a zero amount:
import turtle
def tofront(t):
t.forward(0)
gold = turtle.Turtle("square")
gold.turtlesize(5)
gold.color("gold")
gold.setx(-10)
blue = turtle.Turtle("square")
blue.turtlesize(5)
blue.color("blue")
blue.setx(10)
turtle.onscreenclick(lambda x, y: tofront(gold))
turtle.done()
The blue turtle overlaps the gold one. Click anywhere and the situation will be reversed.
Although #Bally's solution works, my issue with it is that it creates a new turtle everytime you adjust the layering. And these turtles don't go away. Watch turtle.turtles() grow. Even my solution leaves footprints in the turtle undo buffer but I have to believe it consumes less resources.
Just add this to turtle.py file
def tofront(self, tobring):
newfront = tobring.clone()
tobring.ht()
return newfront
works correct,
so method - sould return you new clone of turtle, on the top of all other turtles.
parameter tobring - it's your current turtle (the one you want to bring to front)
you can use this def in your program or put it into turtle.py file
if so, don't forget to add it to list of commands, - _tg_turtle_functions
_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'tofront', 'color',
I did it after clone command
Hope this will help you
Related
This is the programme I wrote but I'm not sure what's wrong:-
import turtle
import random
bob = turtle.Turtle()
screen = turtle.Screen()
def coord(x,y):
print(x,y)
turtle.onscreenclick(None)
turtle.onscreenclick(coord)
turtle.listen()
print('hello')
turtle.done()
The programme works fine except that the print('hello') part happens first, followed by the on screen event. How do I make the onscreen event occur first before the rest of my programme?
You can simply make the rest of your code part of the coord function:
def coord():
print(x,y)
turtle.onscreenclick(None)
print("Hello")
# The rest of your program goes here.
However, a few things to note:
This isn't an amazing elegant solution, especially if you intend to set up other events further into your code. It can become quite hard to keep track of.
It's imperative that you remove the event binding (in this case the binding of coord to onscreenclick) as soon as it's been used, otherwise you could end up with multiple instances of the same code running at once if someone double-clicked the screen, for example. In your case you've already done this (with turtle.onscreenclick(None)), but it is something to keep in mind.
If you choose to go this route, don't forget to rename the coord function something more representative of what that section of your code will do.
just reviewing for my upcoming midterm. We were given Past midterm problems but no solutions. I am trying to grasp the knowledge best i can.
For this problem, it asks to define a function named equalSigns, pass it values t and length. So, i just need to make my program in turtle graphics, create two parellel line, simple enough i suppose. this is my code that i wrote just for it to correctly output an equal sign of x length. (then of course i would convert it to a function) My question, is there any better way to create this?
import turtle
t=turtle.Turtle()
s=turtle.Screen()
t.forward(200)
t.penup()
t.home()
t.right(90)
t.forward(50)
t.pendown()
t.left(90)
t.forward(200)
'''i suppose i dont have to go home and then down.
instead just continue and go down and forward left.
but either way, is this the best approach to take?
'''
Yes, I think there's a better way. Most of all, I think you turned the wrong way: you need to make a second right turn to come back along the lower line.
You could make a routine that does a half-equals, and then all it twice to get the two lines. Think of this as drawing a rectangle, except that the short sides are invisible.
# Draw long side
t.pendown()
t.forward(x)
t.penup()
t.right(90)
# Move along short side without drawing
t.forward(x/4)
t.right(90)
That gets you to the opposite corner of the rectangle. Call this twice, and you're done ... and back at the starting point.
Perhaps you could have your turtle think outside the shell:
import turtle
import tkinter as _
_.ROUND = _.BUTT
turtle.width(50)
turtle.forward(200)
turtle.color("white")
turtle.width(48)
turtle.backward(200)
turtle.done()
(The vertical gray bars at the two ends are artifacts of GIF conversion and not present when the program is run.)
I am a newbie using python 3.2.3
When I ran the module in the python IDLE, the turtle drew a square without any update on the screen, so the window appeared blank, and after I input any key, the turtle and the square appeared due to the call of turtle.update().
However, when I double-clicked the .py file storing the below code in my document and executed it directly, the square always showed up before I input any key.
The interesting part is that the turtle was not shown but only the square was shown.
It seems that there was a turtle update only for the square after drawing even if I had already set turtle tracer to (0,0).
Is this considered a bug and how can I solve it? Thanks for the help.
import turtle
def drawSquare():
turtle.down();
turtle.begin_fill();
turtle.goto(10, 0);
turtle.goto(10, 10);
turtle.goto(0, 10);
turtle.goto(0, 0);
turtle.end_fill();
turtle.up();
def tUpdate():
turtle.update();
turtle.tracer(0,0);
drawSquare();
input("Not updated. Press any key.");
tUpdate();
print("Updated");
turtle.mainloop();
You've got a couple of things working against you: the poor documenation provided for tracer() and the fact that end_fill() and up() cause updates to occur. tracer() is not really meant to hide things from the user until you're ready to display them -- it's a speed optimization so that the user doesn't have to see every drawing step in a complicated image. You don't have full control over when updates will occur.
Here's a rework of your example that displays the behaviour you want at the cost of it no longer being a filled square. I've swapped your input() trigger for a mouse click on the window instead but your approach will work just as well here too:
from turtle import Turtle, Screen
def drawSquare(turtle):
turtle.goto(100, 0)
turtle.goto(100, 100)
turtle.goto(0, 100)
turtle.goto(0, 0)
screen = Screen()
screen.tracer(0, 0)
screen.onclick(lambda x, y: screen.update())
turtle = Turtle()
drawSquare(turtle)
screen.mainloop()
I also made which are turtle methods, and which are screen methods, more explicit. The beginning programmer friendly design of the turtle library tends to blur these in the interest of ease of use.
I would like to create a program where one turtle object moves to where a user clicks their mouse, and a different turtle object moves at the same time. I have the first part, but I can't seem to get the rest to work.
Any help would be appreciated.
This is my code. (Credit for the first part of this goes to #Cygwinnian)
from turtle import *
turtle = Turtle()
screen = Screen()
screen.onscreenclick(turtle.goto)
turtle.getscreen()._root.mainloop()
turtle2 = Turtle()
while True:
turtle2.back(100)
turtle2.forward(200)
turtle2.back(100)
I am by no means an expert at Python's turtle module, but here's some code that I think does what you want. The second turtle will be moving back and forth any time the first turtle is not:
from turtle import *
screen = Screen() # create the screen
turtle = Turtle() # create the first turtle
screen.onscreenclick(turtle.goto) # set up the callback for moving the first turtle
turtle2 = Turtle() # create the second turtle
def move_second(): # the function to move the second turtle
turtle2.back(100)
turtle2.forward(200)
turtle2.back(100)
screen.ontimer(move_second) # which sets itself up to be called again
screen.ontimer(move_second) # set up the initial call to the callback
screen.mainloop() # start everything running
This code creates a function that moves the second turtle repeatedly back and forth from its starting position. It uses the ontimer method of the screen to schedule itself over and over. A slightly more clever version might check a variable to see if it is supposed to quit, but I didn't bother.
This does make both turtles move, but they don't actually move at the same time. Only one can be moving at any given moment. I'm not sure if there is any way of fixing that, other than perhaps splitting up the moves into smaller pieces (e.g. have the turtles alternate moving one pixel at a time). If you want fancier graphics you probably need to move on from the turtle module!
My program for creating a Mandelbrot set has a bug: whenever the pen changes colors, and every 42nd pixel after that, is lighter. This is, rather coincidentally, a mandelbug (yes, I just learned that term), as it is inconsistent for many pixels near an "edge" (it might actually be blurred between the color it's supposed to be and the color the last, or next, pixel is supposed to be), but it's always the 42nd pixel after that one until the next color change. I am using OSX 10.6.8, PYTHON 2.7. When I wrote this program at school, it worked perfectly (Windows), and then I sent it to myself, and worked on it a little more (mostly just making the sample size and therefore image larger), and ran it, I got this bug. EDIT: My bad, I forgot to mention that this only happens with my Mandelbrot program, the few other turtle programs I have at home are fine.
Parts of screenshots (so that you don't have to wait forever while the program runs to see what I'm talking about):
From my first version from home:
From the current version (sideways):
Heres the code:
import turtle
import math
turtle.speed(0)
def benoit(onelen):
turtle.left(90)
for x in range(-2*onelen, onelen):
turtle.up()
turtle.goto(x, int(-1.5*onelen)-1)
turtle.down()
for y in range(int(-1.5*onelen)-1, int(1.5*onelen)-1):
z = complex(0,0)
c = complex(x*1.0/onelen,y*1.0/onelen)
for k in range(20):
z = z*z+c
if abs(z) > 2:
g = .2 + .8*(20-k)/20
break
if k == 19:
g = 0
turtle.pencolor(0,g,0)
turtle.forward(1)
benoit(250)
x = raw_input("Press Enter to Exityadayadayada")
EDIT: A fix has been suggested by DSM, who likes this bug. However, I have no experience editing Python source code, and all the underscores are making me nervous. Can someone tell me specifically what to edit and/or how?
Wow. I think this is one of my favourite bugs ever, and believe it or not, the fact that the number happens to be 42 is actually relevant! Well, peripherally, anyhow..
In turtle.py:
def _goto(self, end):
"""Move the pen to the point end, thereby drawing a line
if pen is down. All other methodes for turtle movement depend
on this one.
[...]
###### vererbung!!!!!!!!!!!!!!!!!!!!!!
self._position = end
if self._creatingPoly:
self._poly.append(end)
if len(self.currentLine) > 42: # 42! answer to the ultimate question
# of life, the universe and everything
self._newLine()
self._update() #count=True)
So the problem comes about when it decides to break a line, apparently for performance reasons:
def _newLine(self, usePos=True):
"""Closes current line item and starts a new one.
Remark: if current line became too long, animation
performance (via _drawline) slowed down considerably.
"""
I was able to "fix" the bug by bumping up the linenumber limit and/or scattering self._pencolor references in places that didn't have any. But you're not crazy, anyway, and it's not really anything that you're doing. :-)
Can i offer a suggestion?
i tried your code and it was taking forever to run which you are aware of but what you may not be aware of is the tracer function... i simply put at the beginning of your code:
wn=turtle.Screen()
wn.tracer(10000)
that also eliminates the need for the speed(0) function :)
Try that and run it again, i did and it rendered the whole image in 62 seconds, i timed it by importing the time module by putting this code at the beginning:
import time
st=time.time()
and this code at the end:
print time.time()-st
Well done by the way, Ive just made my own thats a lot slower and lower quality then yours but was using an array of the square shape and stamping to each location i wanted in the array lol, but will be trying to improve it in the future as i only found out turtle existed less then a week ago.
One last thing, if you type:
from turtle import *
instead of "import turtle" you dont need to put turtle at the beginning of every function call :) same thing goes for every other module.
Ive included the pic of your fractal that took 62 seconds to render on my machine thats not even that powerfulYour code run on my weak machine.
I hope all this helps you greatly. also youll notice i dont have that light line problem, not sure if you fixed that issue in the original code up top?