Python turtle.ondrag not working - python

I've been trying to make a paint program in Python Turtle and for some reason it won't work. I'm using the pen() tool and my code looks like this
from turtle import *
import random
pen()
bgcolor('black')
pencolor('white')
pen.ondrag(pen.goto)
listen()
mainloop()
I've look at this http://docs.python.org/2/library/turtle.html and it says to type turtle.ondrag(turtle.goto) but since I'm using the pen it should work as pen.ondrag but it doesn't, so can someone please clear this up.
Thanks Jellominer

I will simplify and clarify the code given by the questionner:
from turtle import *
ts = Screen(); tu = Turtle()
ts.listen()
ondrag(tu.goto)
mainloop()
This works. You have to click on the turtle and drag it.

First, pen() is not the function you want. Second, although Pen is a synonym for Turtle, pen is not a synonym for turtle. Here's how to go about using ondrag() if you'd like to use Pen instead of Turtle:
from turtle import Pen, Screen, mainloop
def ondrag_handler(x, y):
pen.ondrag(None) # disable handler inside handler
pen.setheading(pen.towards(x, y)) # turn toward cursor
pen.goto(x, y) # move toward cursor
pen.ondrag(ondrag_handler)
screen = Screen()
screen.bgcolor('black')
pen = Pen()
pen.color('white')
pen.shapesize(2) # make it larger so it's easier to drag
pen.ondrag(ondrag_handler)
screen.listen()
mainloop() # screen.mainloop() preferred but not in Python 2
The turtle.ondrag(turtle.goto) makes for a nice short example in the documentation but in reality isn't practical. You want to disable the event handler while handling the event otherwise the events stack up against you. And it's nice to turn the mouse towards your cursor as you drag it.

from turtle import *
ts = Screen()
ondrag(goto)
shapesize(10)
pensize(40)
speed(0)
mainloop()
I think this will surely work.
You can change the size and other things
In here you are using the default turtle .
Sorry but you'll need to take care of the indentation

Related

Up arrow key not working for python turtle

I have used the onkey function for the right and left:
sc.onkey(user_left,"left")
sc.onkey(user_right,"right")
I have also set the screen after setting the turtle and importing turtle:
sc=Screen()
But when I use the same format for up and down:
sc.onkey(user_up,"up")
sc.onkey(user_down,"down")
It does nothing. I also have my functions:
def user_right:
t3.forward(5)
def user_left:
t3.backward(5)
t3 is my user turtle, and it is sideways, the shape is turtle, and its head is facing right. t3 is automatically set to make its head facing the right side when the code runs. By the way, I import from turtle import*
I see several issues here. First, this can't work as you claim:
def user_right:
t3.forward(5)
def user_left:
t3.backward(5)
It would need to be:
def user_right():
t3.forward(5)
def user_left():
t3.backward(5)
Next, this won't work in turtle in standard Python:
sc.onkey(user_left,"left")
sc.onkey(user_right,"right")
These keys would have to be "Left" and "Right". Are you using a non-standard turtle implementation? (E.g. the one on repl.it) You show your two event handlers that work, but fail to show the two that don't which would be of more interest when trying to debug your code.
Finally, your missing a call to the screen's listen() method, so your keystrokes are ignored. Here's how I might implement the functionality your code is hinting at:
from turtle import Screen, Turtle
def user_right():
turtle.forward(5)
def user_left():
turtle.backward(5)
def user_up():
turtle.sety(turtle.ycor() + 5)
def user_down():
turtle.sety(turtle.ycor() - 5)
turtle = Turtle()
turtle.shape('turtle')
screen = Screen()
screen.onkey(user_left, 'Left')
screen.onkey(user_right, 'Right')
screen.onkey(user_up, 'Up')
screen.onkey(user_down, 'Down')
screen.listen()
screen.mainloop()

How do I change the Hitbox size of a turtle in python turtle graphics?

I dont know how to change the size of a turtle hitbox in python turtle graphics
I haven't tried anything yet because I'm new, and know very little about this. I've tried googling it, though, but nothing popped up.
from turtle import *
import turtle
from random import randint
import time
screen = turtle.Screen()
screen.setup(1920, 1080)
player = turtle.Turtle()
I want to add a button that you have to click to start right here
The game starts right here :
wn = turtle.Screen()
last_pressed = 'up'
def setup(col, x, y, w, s, shape):
player.penup()
player.up()
player.goto(x,y)
player.width(w)
player.turtlesize(s)
player.color(col)
player.lt(90)
player.down()
wn.onkey(up, "s")
wn.onkey(left, "d")
wn.onkey(right, "a")
wn.onkey(back, "w")
wn.onkey(quitTurtles, "Escape")
wn.listen()
wn.mainloop()
This may not be exactly what you are looking for, but this might work in your situation.
Detecting collision in Python turtle game
This is a thread on collision detection between objects and with some tweaking of numbers you could increase the hitbox of the turtle using the abs() function
I dont know how to change the size of a turtle hitbox in python turtle graphics
What do you mean by "hitbox"? I'm not sure what you mean by that (and neither does Google, apparently).
Do you mean that you want a rectangular button to click on? If that's the case, you could use the tkinter module together with the turtle module to create a button to click. (But be aware that it's not always easy to get the tkinter and turtle modules to work together to do what you want.)
If you want a button to click on, but don't need a Tkinter button, you could just try creating a new turtle in the shape of a rectangle that intercepts mouse clicks with onclick(). You can see an example of this if you run:
python3 -m turtledemo
and select Examples >> colormixer from the main menubar.
Or, if by "hitbox" you mean how to detect when one turtle has intercepted another turtle (as in, one has come close enough to the other to be considered a "hit"), I suggest querying each turtle's location, then using the Pythagorean Theorem to calculate the distance from each other. If this distance is within a predetermined threshold, consider the hitbox as being "hit."
You can see an example of this by typing:
python3 -m turtle
(Pay attention to the yellow turtle as he tries to catch up to the other turtle.)
I apologize if this answer isn't quite what you're looking for, but I'm just not sure what you mean by "hitbox." Maybe you could clarify?
I just saw this question today (2 years too late i know), and was having a similar problem / question.
What I ended up doing was running 3 distance checks (as i had increased my object size by 3) which differed along the x-axis (width). So it would check the distance between the ball(turtle) and the paddle (any 3 points and if it was shorter than X it would trigger the collision mechanic.
so it was something like :
check the ball class' ball object, and see how far away it is from the paddle,
and if its either in the center, or 30 pixels to the left or right of the center then hit.
if
ball.ball.distance(pad.paddle(), pad.paddle.ycor()) < 30 or
ball.ball.distance(pad.paddle.xcor() - 30, pad.paddle.ycor()) < 30 or
ball.ball.distance(pad.paddle.xcor() + 30, pad.paddle.ycor()) < 30

Bind Python turtle exitonclick() function to another key

I am using Python 2.7 turtle graphics to make a simple mouse sensor that draws whenever you hold down the mouse button. Since my function is based on the user, it crashes right when you run it. I found out that turtle.exitonclick() will help keep the interface on, but I can't draw because my draw is bound to the left mouse button click. Is there any solution to get around this or is it possible to rebind turtle.exitonclick() to something else? Here's my code:
import turtle
wn = turtle.Screen()
wn.bgcolor("lightblue")
#wn.screensize(400,300)
turtle.setup(400,300)
draw = turtle.Turtle()
def gothere(event):
draw.penup()
draw.goto(event.x-360, 340-event.y)
draw.pendown()
#draw.color(blue)
def movearound(event):
draw.goto(event.x-360, 340-event.y)
draw.color(blue)
def release(event):
draw.penup()
def reset(event):
draw.clear()
cavset = turtle.getcanvas()
cavset.bind("<Button-2>", gothere)
cavset.bind("<B1-Motion>", movearound)
cavset.bind("<ButtonRelease-2>", release)
cavset.bind("<Escape>", reset)
wn.listen()
wn.exitonclick()
(I am running through command prompt, BTW.)
What you most likely want is:
turtle.mainloop()
instead of:
wn.exitonclick()
as that's what exitonclick() calls after setting up a handler for the "onclick" part.
However, there are other issues. You seem to be mixing three different coding models: functional interface to turtle; object-oriented interface to turtle; calling into turtle's Tkinter underpinnings.
Let's simplify and just use the object-oriented interface to turtle:
from turtle import Turtle, Screen, mainloop
def gothere(x, y):
draw.penup()
draw.goto(x, y)
draw.pendown()
def movearound(x, y):
draw.ondrag(None) # disable handler in handler!
draw.color("blue")
draw.goto(x, y)
draw.ondrag(movearound)
def release(x, y):
draw.penup()
def reset():
draw.clear()
wn = Screen()
wn.setup(400, 300)
wn.bgcolor("lightblue")
draw = Turtle()
wn.onclick(gothere, 2)
draw.ondrag(movearound)
draw.onrelease(release, 2)
wn.onkey(reset, "Escape")
wn.listen()
mainloop()
I believe Python 3 turtle tweaks the turtle event interface to add some methods and use clearer names for others.

Python 3 Turtle Graphics: Mouse coordinates [duplicate]

I'm assigned to create a similar version of slither.io in python. I planned on using Turtle. How do I make the turtle follow my mouse without having to click every time?
This is how I would do it when clicking, but I would rather not have to click:
from turtle import *
turtle = Turtle()
screen = Screen()
screen.onscreenclick(turtle.goto)
turtle.getscreen()._root.mainloop()
The key to it is to use the ondrag() event handler on a turtle. A short and not so sweet solution:
import turtle
turtle.ondrag(turtle.goto)
turtle.mainloop()
which will likely crash shortly after you start dragging. A better solution with a larger turtle to drag, and that turns off the drag handler inside the drag hander to prevent events from piling up:
from turtle import Turtle, Screen
def dragging(x, y):
yertle.ondrag(None)
yertle.setheading(yertle.towards(x, y))
yertle.goto(x, y)
yertle.ondrag(dragging)
screen = Screen()
yertle = Turtle('turtle')
yertle.speed('fastest')
yertle.ondrag(dragging)
screen.mainloop()
Note that you have to click and drag the turtle itself, not just click somewhere on the screen. If you want to get the turtle to follow the mouse without keeping the left button held down, see my answer to Move python turtle with mouse pointer.

Re-open turtle after turtle.bye()

I have some code as follows:
# My code here
turtle.bye()
After that, is there any way I can reopen the turtle window.
I know you can do turtle.clearscreen() but that does not close the turtle window.
I will accept any answer which allows me to close the turtle graphics window and then reopen it without opening and running another python program to do this.
Thank you in advance
I've seen situations where the approach of #LukeTimmons worked but not always reliably and not in every situation. Give this solution a try:
import time
import turtle
turtle.dot(200, 'green')
time.sleep(2)
turtle.bye()
# These two lines (indirectly) resurrect turtle environment after turtle.bye()
turtle.Turtle._screen = None # force recreation of singleton Screen object
turtle.TurtleScreen._RUNNING = True # only set upon TurtleScreen() definition
turtle.dot(200, 'red')
turtle.mainloop()
It resets two flags that keep turtle from starting up again. It may be safer to create your own turtle after restart rather than use the default turtle which may point back to the departed environment.
There may be other ways but this is the only way I know.
from turtle import *
def turtle1():
#Your code here
turtle1()
turtle.bye()
turtle1()
This should re-run your code without re-typing it.

Categories