Enter button in Python turtle program is not responding - python

import turtle
import random
wn = turtle.Screen() #sets the screen
wn.setup(1000,900)
wn.screensize(2000,2000)
ad = turtle.Turtle() #names the turtle
ad.shape("circle") #changes turtles or "ad's" shape
ad.speed("fastest")
r = int(60) #CHANGES THE SIZE OF THE WRITING
x = int(-950)
y = int(200)
ad.penup()
ad.goto(x,y)
def enter():
ad.penup()
y -= 100
ad.goto(x,y)
wn.onkey(lambda: enter(), "Return")
wn.listen()
Trying to do an enter button in turtle but this wont work.
It says that there is an error with the local variable.

Although your immediate problem is the lack of a global y statement in your enter() function, there's a lot of noise in your code that we should eliminate to make it a better MVCE:
import random # not used so leave out of SO question example
r = int(60) # ditto
x = int(-950) # int() not needed for ints
y = int(200) # ditto
wn.onkey(lambda: enter(), "Return") # lambda not needed
Although we could fix this with the addition of a global y statement, I prefer to simply interrogate the turtle itself and avoid the global:
from turtle import Turtle, Screen
def enter():
ad.sety(ad.ycor() - 100)
X, Y = -950, 200
wn = Screen()
wn.setup(1000, 1000) # visible field
wn.screensize(2000, 2000) # total field
ad = Turtle("circle")
ad.speed("fastest")
ad.penup()
ad.goto(X, Y)
wn.onkey(enter, "Return")
wn.listen()
wn.mainloop()
Note, you positioned the turtle off the visible portion of the screen so you need to scroll to the left side of the window to see the turtle cursor. Once you do, you can move it down by hitting, "Return".

Related

Hiding the turtle in python turtle drawing

I am trying to make it so that the turtle is hidden from the beginning of the program but even after putting t.hideturtle() right below where I declare the turtle as variable t the turtle still seems to show up in the middle of the drawing.
import turtle
from random import randint
s = turtle.getscreen()
t = turtle.Turtle()
t.hideturtle()
rx = randint(50,100)
ry = randint(50,100)
width, height = 32,32
s.screensize(width, height)
s.bgcolor("black")
t.goto(0,0)
t.speed(15)
num=10
while num<=1000:
r = randint(1,5)
if r == 1:
t.pencolor("white")
elif r == 2:
t.pencolor("#00FFFF")
elif r == 3:
t.pencolor("#89CFF0")
elif r == 4:
t.pencolor("#0000FF")
elif r == 5:
t.pencolor("#00FFFF")
t.right(25)
t.circle(num)
num=num+10
count=num//10
print("ran",count,"times")
This was a tricky one.
The key problem here is that your first statement creates one turtle and returns you its screen. That turtle remains visible. Your second statement creates a new turtle, which you hide. Change the order to:
t = turtle.Turtle()
s = t.getscreen()
and it all works as expected.
#TimRoberts writes:
The key problem here is that your first statement creates one turtle
and returns you its screen. That turtle remains visible. Your second
statement creates a new turtle, which you hide.
This is the problem with mixing turtle's object-oriented API and it's functional API. If we change the import to force just the object-oriented API, and block the functional one, we can do:
from turtle import Screen, Turtle
screen = Screen()
turtle = Turtle()
turtle.hideturtle()
or instead do:
from turtle import Screen, Turtle
turtle = Turtle()
turtle.hideturtle()
screen = Screen()
And it makes no difference. By mixing the functional API and the object-oriented API, you can easily unintentionally create the default turtle which isn't called for in this code.
I tried this line of code and it worked for me:
import turtle
turtle.hideturtle()

Is there a way to avoid the recursion limit in my Turtle-program?

import turtle
from turtle import Turtle
WIDTH = 1000
HEIGHT = 1000
#Screen setup
screen = turtle.Screen()
screen.setup(WIDTH, HEIGHT)
screen.title(" " *150 + "Test_GIU")
screen.bgcolor("black")
screen.setup(1000, 1000)
#Pen
pen = Turtle("circle")
pen.pensize = 5
pen.color("green")
pen.speed(-1)
def dragging(x, y): # These parameters will be the mouse position
pen.ondrag(None)
pen.setheading(pen.towards(x, y))
pen.goto(x, y)
pen.ondrag(dragging)
def click_on_c():
screen.reset()
pen = Turtle("circle")
pen.pensize = 5
pen.color("green")
pen.speed(-1)
pen.ondrag(dragging)
def main(): # This will run the program
turtle.listen()
pen.ondrag(dragging) # When we drag the turtle object call dragging
turtle.onkeypress(click_on_c, "c")
screen.mainloop() # This will continue running main()
main()
This is my code, im pretty new to it, so its not very good, but its my first real project. I´ve already tried to increase the recursin limit, but it crashes even if I set it to 10000. I also tried to catch the error with an try and exept block, but it also doesnt work.
Let's try a simpler design where instead of calling screen.reset() and recreating the turtle, we instead call pen.reset() to clear the drawing:
from turtle import Screen, Turtle
WIDTH = 1000
HEIGHT = 1000
def dragging(x, y): # Parameters are the mouse position
pen.ondrag(None)
pen.setheading(pen.towards(x, y))
pen.goto(x, y)
pen.ondrag(dragging)
def click_on_c():
pen.reset()
pen.pensize = 5
pen.color("green")
pen.speed('fastest')
# Screen setup
screen = Screen()
screen.setup(WIDTH, HEIGHT)
screen.title("Test_GUI")
screen.bgcolor("black")
# Pen
pen = Turtle("circle")
pen.pensize = 5
pen.color("green")
pen.speed('fastest')
pen.ondrag(dragging)
screen.onkeypress(click_on_c, "c")
screen.listen()
screen.mainloop()
We have to reset some aspects of the pen after calling reset() as that call clears the settings back to the defaults.

Why isn't this code working? I am new and I really need assistance

So I am trying to make it so when the lt turtle collides with the circle turtles(the ones in the list) it draws a star. But when I run it and try it the turtle does not draw a star. Please run it and see that I am trying to make it so when my turtle collides with the circles the turtle draws a star.
import turtle
import random
screen=turtle.Screen()
screen.listen()
list=[]
lt=turtle.Turtle()
lt.penup()
lt.shape("turtle")
for i in range(10):
x=random.randint(-250,250)
y=random.randint(-250,250)
st=turtle.Turtle()
list.append(st)
for z in list:
z.speed(1000)
z.shape("circle")
z.color("white")
x=random.randint(-250,250)
y=random.randint(-250,250)
z.penup()
z.goto(x,y)
z.pendown()
def left():
lt.forward(2)
lt.left(10)
screen.onkey(left,"A")
def right():
lt.forward(2)
lt.right(10)
screen.onkey(right,"D")
r=195
g=20
b=50
screen.bgcolor(r,g,b)
def StarCheck(z):
if abs(lt.xcor()-z.xcor()) <15 and abs(lt.ycor()-z.ycor()) <15:
z.clear()
lt.color("yellow")
lt.begin_fill()
for i in range(5):
lt.forward(5)
lt.right(145)
lt.forward(10)
lt.end_fill()
while True:
r=r-0.20
screen.bgcolor(r,g,b)
lt.forward(1)
for n in list:
StarCheck(z)
I would assume you have a typo in your while loop. It should be
StarCheck(n) instead of StarCheck(z)
Below is the listing of your altered code.
import turtle
import random
screen = turtle.Screen()
screen.listen()
list = []
lt = turtle.Turtle()
lt.penup()
lt.shape("turtle")
for i in range(10):
x = random.randint(-250, 250)
y = random.randint(-250, 250)
st = turtle.Turtle()
list.append(st)
for z in list:
z.speed(1000)
z.shape("circle")
z.color("white")
x = random.randint(-250, 250)
y = random.randint(-250, 250)
z.penup()
z.goto(x, y)
z.pendown()
def left():
lt.forward(2)
lt.left(10)
screen.onkey(left, "A")
def right():
lt.forward(2)
lt.right(10)
screen.onkey(right, "D")
r = 0.9
g = 0.2
b = 0.5
screen.bgcolor('red')
def StarCheck(z):
if abs(lt.xcor() - z.xcor()) < 10 and abs(lt.ycor() - z.ycor()) < 10:
z.clear()
lt.color("yellow")
lt.begin_fill()
for i in range(5):
lt.forward(10)
lt.right(120)
lt.forward(10)
lt.right(72 - 120)
lt.end_fill()
return
while True:
r = r - 0.000002
screen.bgcolor(r, g, b)
lt.forward(1)
for n in list:
StarCheck(n)
I ran this code and a yellow star is created as the turtle goes over the white circles.
You might also want to refer colormode for setting appropriate RGB values or color. I am using python 3.7.
HTH
I made the changes that #MustafaHaider suggests and implies but I couldn't get your code to work in any real sense. There's a lot broken:
As #MustafaHaider noted, if this is standard Python turtle, you'd need to call:
colormode(255)
If you're not using standard Python turtle, eg. the Repl site, you need to mention that in your question. This makes no sense:
z.speed(1000)
The numeric arguments range from 0 to 10, though I suggest a symbolic argument like "fastest". This will eventually underflow and cause an error:
r=r-0.20
#MustafaHaider switched to a smaller increment but that's the same issue -- using a multiplicative reduction and int() wouldn't have this problem. Did you really want the user to have the CAPSLOCK pressed on some systems:
screen.onkey(left,"A")
screen.onkey(right,"D")
If not, I suggest "a" and "d" instead. There's a turtle method for this:
if abs(lt.xcor()-z.xcor()) <15 and abs(lt.ycor()-z.ycor()) <15:
it's called distance(). This doesn't do what you want:
z.clear()
as z hasn't drawn anything. You want z.hideturtle() and only call StarCheck(z) if z.isvisible(). Below is my rework of your code that addresses the above issues as well as others I haven't mentioned and general style:
from turtle import Screen, Turtle
from random import randint
def left():
player.left(10)
def right():
player.right(10)
def StarCheck(enemy):
if player.distance(enemy) < 15:
enemy.hideturtle()
player.begin_fill()
for _ in range(5): # a la #MustafaHaider
player.forward(10)
player.right(120)
player.forward(10)
player.left(48)
player.end_fill()
r, g, b = 195, 20, 50
screen = Screen()
screen.colormode(255)
screen.bgcolor(r, g, b)
player = Turtle()
player.shape('turtle')
player.color('yellow')
player.speed('fastest')
player.penup()
enemies = []
for _ in range(10):
enemy = Turtle()
enemy.hideturtle()
enemy.shape('circle')
enemy.color('white')
x = randint(-250, 250)
y = randint(-250, 250)
enemy.penup()
enemy.goto(x, y)
enemy.pendown()
enemy.showturtle()
enemies.append(enemy)
screen.onkey(left, 'a')
screen.onkey(right, 'd')
screen.listen()
while True:
r *= 0.9999
screen.bgcolor(int(r), g, b)
player.forward(1)
for enemy in enemies:
if enemy.isvisible():
StarCheck(enemy)
screen.mainloop() # never reached
This should be playable now. There's more to do, e.g. replace your while True: loop with a function and timed event if this is standard Python turtle.

Use onkey() to do multiple functions with Python turtle

I'm trying to write a basic turtle drawing game/program and I've been using onkey(function, "key") to have the user input keystrokes. Well I wanted the user to be able to change the width of the pen by either hitting the up key to increase the width by one, or the down key to decrease the width by one. I know I need some kind of loop, but I don't really know where to implement it.
Here's a simple example that will make the turtle walk in a continuous circle while you press up and down arrows to change the pen width:
from turtle import Turtle, Screen
def larger():
size = turtle.pensize()
if size < 10:
turtle.pensize(size + 1)
def smaller():
size = turtle.pensize()
if size > 1:
turtle.pensize(size - 1)
def move():
turtle.circle(150, extent=3)
screen.ontimer(move, 100)
turtle = Turtle()
screen = Screen()
screen.onkey(larger, "Up")
screen.onkey(smaller, "Down")
screen.listen()
move()
screen.mainloop()
Make sure you click on the window first to make it the key listener.
I think you can't, but you can call the function insde the function you bind to the key:
from turtle import *
def function1():
do_that = "do that"
print(do_that)
def function2():
do_this = "do this"
print(do_this)
function1()
onkey(function2, "space")
do this
do that
It worked for me ;)

Python - Keyboard Multiple Turtle Objects

I would like to create a program in which a Turtle object responds to key presses. I can do this, but I can't seem to understand how to move a second Turtle object, which is controlled by the computer, while the first one is moving. Any help would be appreciated.
Here is my code:
from turtle import *
from Tkinter import Tk
root = Tk()
root.withdraw()
turtle = Turtle()
def h1():turtle.forward(10)
def h2():turtle.left(45)
def h3():turtle.right(45)
def h4():turtle.back(10)
def h5(root=root):root.quit()
onkey(h1,"Up")
onkey(h2,"Left")
onkey(h3,"Right")
onkey(h4,"Down")
onkey(h5,"q")
listen()
root.mainloop()
Insert a second turtle before listen() that moves with keys w,a,s,d:
turtle2 = Turtle()
def h11():turtle2.forward(10)
def h21():turtle2.left(45)
def h31():turtle2.right(45)
def h41():turtle2.back(10)
onkey(h11,"w")
onkey(h21,"a")
onkey(h31,"d")
onkey(h41,"s")
I can't seem to understand how to move a second Turtle object, which
is controlled by the computer, while the first one is moving.
Below is some minimal code that does as you describe. Green turtle Pokey is computer controlled while red turtle Hokey is user controlled (click on the window first so your keystrokes are heard):
from turtle import Turtle, Screen
def move_pokey():
pokey.forward(10)
x, y = pokey.position()
if not (-width/2 < x < width/2 and -height/2 < y < height/2):
pokey.undo()
pokey.left(90)
screen.ontimer(move_pokey, 100)
hokey = Turtle(shape="turtle")
hokey.color("red")
hokey.penup()
pokey = Turtle(shape="turtle")
pokey.setheading(30)
pokey.color("green")
pokey.penup()
screen = Screen()
width = screen.window_width()
height = screen.window_height()
screen.onkey(lambda: hokey.forward(10), "Up")
screen.onkey(lambda: hokey.left(45), "Left")
screen.onkey(lambda: hokey.right(45), "Right")
screen.onkey(lambda: hokey.back(10), "Down")
screen.onkey(screen.bye, "q")
screen.listen()
screen.ontimer(move_pokey, 100)
screen.mainloop()
This is not finished code (shutdown of the timer event should be cleaner, Hokey's handlers should lock out additional events while running, etc.) but should give you a basic idea of how to go about it.

Categories