How to fix infinite loop in Python - turtle graphics - python

I am trying to code a program that allows the user to choose out of several options of a scene to draw. I come to an issue with drawing the sun. When I run the program the sun wont stop drawing and fill in the color. Everything else works.
import turtle
import random
t = turtle.Turtle()
turtle.setup(800,600)
def draw_sunshine():
t.penup()
t.goto(350,250)
t.pendown()
t.color('black', 'yellow')
t.speed(9)
t.begin_fill()
while True:
t.forward(100)
t.left(170)
t.right(100)
if abs(t.pos()) < 1:
break
t.end_fill()
t.done()
weather = False
while weather == False:
weather = input("Would you like to draw rain or sunshine? ")
if weather == "rain":
draw_rain()
else:
draw_sunshine()

The problem is likely this termination test:
if abs(t.pos()) < 1:
break
The pos() method returns a pair of numbers, e.g. (0.0, 0.0), as a turtle.Vec2D type, which abs() only operates on the first, x. In this situation, x will never be less than 1 as that's near the center of the screen and we're far off to the right.
Below is a different approach where we control the loop based on the number of iterations it will take to complete the drawing of the sun. To make this work, I've adjusted the sun drawing to finish in a reasonable (integral) number of iterations and still fill with color nicely:
from turtle import Turtle, Screen
def draw_sunshine(turtle):
turtle.penup()
turtle.goto(350, 250)
turtle.pendown()
turtle.color('black', 'yellow')
turtle.speed("fast")
turtle.begin_fill()
for _ in range(24):
turtle.forward(100)
turtle.left(75)
turtle.end_fill()
screen = Screen()
screen.setup(800, 600)
yertle = Turtle()
weather = ''
while not weather:
weather = input("Would you like to draw 'rain' or 'sunshine'? ")
if weather == "rain":
draw_rain(yertle)
else:
draw_sunshine(yertle)
yertle.hideturtle()
screen.exitonclick()

Related

How do you make a conditional loop with onkeypress()?

I'm working on a python project for my intro class where I want to make a blizzard with the turtle module. So far, I've been able to make a "snowflake" appear on each keypress but I'm not sure how to make it into a conditional loop where when I click, it becomes true and keeps looping without me having to click again.
Here's the code I have right now:
def snowing(x, y):
w.speed(0)
flake_size = randint(1, 5)
rx = randint(-250, 250)
ry = randint(-300, 300)
w.color(colours[5])
w.setposition(rx, ry)
w.pendown()
w.begin_fill()
w.circle(flake_size)
w.end_fill()
w.penup()
listen()
onscreenclick(snowing, add=None)
when I click, it becomes true and keeps looping without me having to
click again.
We can make a separate event handler that is a toggle, using a global to switch between on and off on subsequent clicks. We'll combine that with a timer event to keeps the flakes coming:
from turtle import Screen, Turtle
from random import randint, choice
COLOURS = ['light gray', 'white', 'pink', 'light blue']
is_snowing = False
def toggle_snowing(x, y):
global is_snowing
if is_snowing := not is_snowing:
screen.ontimer(drop_flake)
def drop_flake():
flake_radius = randint(1, 5)
x = randint(-250, 250)
y = randint(-300, 300)
turtle.setposition(x, y)
turtle.color(choice(COLOURS))
turtle.begin_fill()
turtle.circle(flake_radius)
turtle.end_fill()
if is_snowing:
screen.ontimer(drop_flake)
turtle = Turtle()
turtle.hideturtle()
turtle.speed('fastest')
turtle.penup()
screen = Screen()
screen.setup(500, 600)
screen.bgcolor('dark blue')
screen.onclick(toggle_snowing)
screen.listen()
screen.mainloop()
When you click on the screen, the flakes will start appearing. When you click again, they will stop.

Is there a way that I can open the turtle screen midway through the program?

I am sort of a noob, and making a project where I need the turtle graphics screen to pop up towards the end of the program(I need to get user input to show what needs to be displayed). I have tried just having the rest of the code first before defining what the setup of the screen is, but the turtle screen never pops up(what I expected). Is there any way that this would work, or does anybody have suggestions on another way to display something like what turtle does? I did
import turtle
and then the first part of the code, some input and other stuff, looks like this
while c == 1:
if a == "just bring me to the composition viewer":
print("k")
break
# I did try using a goto(2) command and then putting line = 2 after doing
# def goto(linenum):
# global line
# line = linenum
# over the turtle setup instead of break, but it was the same result
if a == "+help":
print()
words3 = "What would you like help with? press +help again to clos"
for char in words3:
time.sleep(0.008)
sys.stdout.write(char)
sys.stdout.flush()
howcanihelp = input("e ")
if howcanihelp.find("code") == -1:
codehelp = 1
while codehelp == 1:
words4 = "Separate the notes from one another with commas, separate note duration from pitch with a " \
"space, note length is determined by how many fit in a measure of 4/4."
else:
note_pitch = a.split(", ")
note_duration = note_pitch[1::2]
note_pitch = [v for i, v in enumerate(note_pitch) if i % 2 == 0]
print(note_pitch)
print(note_duration)
note_one = [note_pitch[0] + " " + note_duration[0]]
print(note_one)
break
Then setting up the turtle screen
wn = turtle.Screen()
wn.title("Composition viewer")
wn.bgcolor("white")
wn.setup(width=800, height=1000, startx=1100, starty=0)
turtle.speed(0)
and it doesn't pop up. After that I have some movement commands and typical turtle commands that work when everything is at the start looks like this:
# setting up turtle
wn = turtle.Screen()
wn.title("Composition viewer")
wn.bgcolor("white")
wn.setup(width=800, height=1000, startx=1100, starty=0)
turtle.speed(0)
turtle.hideturtle()
# Variables
line_count = 0
num_of_staffs = 0
# Movement
turtle.pu()
turtle.left(180)
turtle.forward(320)
turtle.right(90)
turtle.forward(450)
turtle.right(90)
line = 1
# line = 1 is so i can do goto(1) later on to get here. It works, so is not a problem
while num_of_staffs <= 12:
while line_count < 5:
turtle.pd()
turtle.forward(640)
turtle.back(640)
turtle.pu()
turtle.right(90)
turtle.forward(10)
turtle.left(90)
line_count += 1
num_of_staffs += 0.2
turtle.right(90)
turtle.forward(20)
turtle.left(90)
if line_count == 5:
line_count = 0
goto(1)
turtle.pd()
turtle.left(90)
turtle.forward(910)
turtle.right(90)
turtle.forward(640)
turtle.right(90)
turtle.forward(910)
turtle.back(910)
What your looking for is called textinput().
import turtle
screen = turtle.Screen()
answer = screen.textinput("Text Input Popup", "Quit Now?")
if answer is None or answer.lower().startswith('y'):
print("Goodbye!")
screen.clear()
screen.bye()
else:
print("Return to game!")
I would generally agree with #bashBedlam about using textinput() and numinput(). Ignoring that:
The turtle screen won't pop up until you do your first turtle-related command. You can do all sorts of console input and calculations and when you're ready, invoke something like screen = turtle.Screen() to get your turtles crawling.
If this approach isn't working, show your code in your question so we can see where things go wrong.

Multiple Turtles, multiple random movements

I have an assignment where I have to make a game in python with turtles.
I am able to generate a grid like I want to, and I am able to generate multiple different turtles. my
- I have no clue where to start in terms of figuring out how to have each of my three different turtles each move throughout the board randomly, while staying on the grid line.
- the "game" must stop after two of the turtles have hit the edge of the screen, I do not know how to do this, either.
here is what I have so far:
import turtle
import random
turtle.pensize(2)
turtle.penup()
turtle.goto(-160,-160)
turtle.pendown()
turtle.color("green")
turtle.speed(0)
for i in range(4):
turtle.forward(320)
turtle.left(90)
for y in range(-160,160,80):
for x in range(-160,160,80):
turtle.penup()
turtle.goto(x,y)
turtle.pendown()
for k in range(4):
turtle.forward(40)
turtle.left(90)
turtle.end_fill()
for y in range(-120,160,80):
for x in range(-120,160,80):
turtle.penup()
turtle.goto(x,y)
turtle.pendown()
for k in range(4):
turtle.forward(40)
turtle.left(90)
billy = turtle.Turtle()
billy.shape("turtle")
billy.color("red")
billy.penup()
billy.left(90)
rick = turtle.Turtle()
rick.shape("turtle")
rick.color("orange")
rick.penup()
mike = turtle.Turtle()
mike.shape("turtle")
mike.color("purple")
mike.penup()
turtle.done()
strong guidance would be VERY helpful.
You could take advantage of object orientation. Here is my version of your turtle script:
import turtle
import random
# I added randint.
from random import randint
# Let's define a class so we can create turtles
class MyTurtle():
# Here's the constructor. Where we give some initial values.
def __init__(self, name, color):
self.name = name
self.color = color
self.turtle = turtle.Turtle()
self.turtle.shape("turtle")
self.turtle.color(self.color)
self.turtle.speed(1)
self.turtle.pd()
# We need to know if this turtle is off the board.
def off_board(self):
x = self.turtle.xcor()
y = self.turtle.ycor()
return x < -160 or 160 < x or y < -160 or 160 < y
# calling this will move the turtle in a random direction.
def move(self):
turn = randint(0,2)
if turn == 1:
self.turtle.lt(45)
elif turn == 2:
self.turtle.rt(45)
self.turtle.forward(5)
# Put your code for drawing the grid
# Let's create some turtles and start moving them.
turtles = []
turtles.append( MyTurtle('billy', 'red'))
turtles.append( MyTurtle('chris', 'blue'))
turtles.append( MyTurtle('lilly', 'pink'))
turtles.append( MyTurtle('kevin', 'green'))
ok = True
while ok:
for t in turtles:
t.move()
if t.off_board():
print ("Turtle %s wins!!!" % (t.name))
ok = False
turtle.done()
Come on! Just one upvote for this awesome turtle script?

players not moving simultaneously

I am attempting to make a game in python with the turtle module, I have the square moving towards the player (the circle) and the aim is for the circle to jump over the square and not get hit.
The player can jump by pressing the spacebar,
but every time you hit the space bar to jump the player jumps, but the square stops moving and you are unable to jump over.
here is my code:
import turtle
import time
wn = turtle.Screen()
wn.bgcolor("white")
wn.title("dinosaur run")
wn.tracer(1,20)
floor = turtle.Turtle()
floor.fd(370)
floor.bk(370*2)
floor.ht()
player = turtle.Turtle()
player.shape("circle")
player.penup()
player.setpos(-370,14)
def jump():
player.lt(90)
player.fd(40)
time.sleep(0.5)
player.bk(40)
player.rt(90)
turtle.listen()
turtle.onkey(jump, "space")
class cactus(turtle.Turtle):
turtle.shape("square")
turtle.penup()
turtle.speed(0)
turtle.setpos(370,14)
cactusspeed = 2
while True:
x = turtle.xcor()
x -= cactusspeed
turtle.setx(x)
Thanks a lot,
all ideas welcome,
I've tried wn.update() at the end
As provided above, your code doesn't run at all as cactusspeed never gets defined. And your class cactus doesn't have a hope of working as currently laid out (reread about Python classes.) Finally, your while True: has no business in an event driven world like turtle.
Below is my rework of your code to use an ontimer() event to control the cactus independent of the player. I also eliminated the sleep() and simply made the player move slower and jump higher. I believe this should give you the dynamic you're looking for:
from turtle import Turtle, Screen
def jump():
player.forward(100)
player.backward(100)
def move():
if cactus.xcor() < -screen.window_width()/2:
cactus.hideturtle()
cactus.setx(370)
cactus.showturtle()
else:
cactus.forward(cactusspeed)
screen.ontimer(move, 40)
screen = Screen()
floor = Turtle(visible=False)
floor.speed('fastest')
floor.fd(370)
floor.bk(370 * 2)
player = Turtle("circle", visible=False)
player.penup()
player.setpos(-370, 14)
player.setheading(90)
player.speed('slowest')
player.showturtle()
cactusspeed = 4
cactus = Turtle("square", visible=False)
cactus.speed('fastest')
cactus.penup()
cactus.setpos(370, 14)
cactus.setheading(180)
cactus.showturtle()
screen.onkey(jump, "space")
screen.listen()
move()
screen.mainloop()

Turtle graphics snake game

I just started turtle graphics yesterday. I decided to make a little snake game in turtle graphics. But later on, I got some problems after another. :(
The problem is that, I couldn't level up the game whenever my snake eats the food :( and the movement of my snake is a little bit not the same to the typical snake game... so I'm here to ask for suggestions what to do to solve these problems. so please lend me your ideas :D
well, here's my very long long code..
from turtle import *
import random
title("Snake Game") #title of the game
setup(555,555) #sets the screensize into 555x555 px
bgcolor("orange") #background color
#pressed key functions
def up():
penup()
pendown()
head(90)
def right():
penup()
pendown()
head(0)
def left():
penup()
pendown()
head(180)
def down():
penup()
pendown()
head(270)
#draw dot
def dotx():
pen2.penup()
pen2.goto(x1,y1)
pen2.pendown()
pen2.dot(20,"green")
#heading of the snake
def head(x):
for i in range(9999999):
for ii in range(20):
seth(x)
fd(2)
if xcor()>=250.0 or ycor()>=250.0 or xcor()<=-250.0 or ycor()<=-250.0:
clear()
pen2.clear()
pen4.write("GAME OVER")
break
elif (xcor() in x2) and (ycor() in y2):
pen2.clear()
pen4.write("EATEN",False,'center',font=('Arial',15,'normal'))
if xcor()>=250.0 or ycor()>=250.0 or xcor()<=-250.0 or ycor()<=-250.0:
clear()
pen2.clear()
pen4.write("GAME OVER")
break
clear()
color("white")
pensize(5) #pensize
shape('turtle')
#hideturtle()
delay(2) #delay of animation
speed(10) #speed of animation
pen2=Pen() #dots
pen2.hideturtle()
pen4=Pen()
pen4.hideturtle()
pen4.color("white")
#border
pen3=Pen()
pen3.color("white")
pen3.pensize(3)
pen3.hideturtle()
pen3.speed(10)
pen3.penup()
pen3.goto(-250,-250)
pen3.pendown()
for p3 in range(4):
pen3.fd(500)
pen3.left(90)
#dots coordinates
x1=random.randint(-225,225)
y1=random.randint(-225,225)
x2=list(range(x1-6,x1+6))
y2=list(range(y1-6,y1+6))
dotx() #call dots
#controls
onkey(up,"Up")
onkey(right,"Right")
onkey(left,"Left")
onkey(down,"Down")
listen()
To make the snake grow I find it easy to create a list and use pop and insert functions to have a constant list of all of the snake locations. Then you can use turtles stamp method to stamp all of these list locations so that it displays in all locations. Here's an example of a turtle snake game I made a while ago so you can see how to use these concepts
pos.insert(0,[round((snake.xcor())),round((snake.ycor()))]) #round x turns the float value of position into integer
pos.pop(-1)
for x in range(1, len(pos)):
if pos[x] == pos[0]:
sys.exit()
elif pos[x]!= pos[0]:
pass;
#pop removes last element of list, used to update position
else: #insert inserts an element into list at position
pos.insert(0,[round((snake.xcor())),round((snake.ycor()))])

Categories

Resources