Python turtle not moving on arrow press - python

I am trying to make my turtle (main_ship) move across the bottom of my screen according to when the user presses the left and right arrow keys but the turtle is not moving. I have used the same code before when making Pong so I'm not sure why it's not working.
import turtle
wn = turtle.Screen()
wn.title("Game")
wn.bgcolor("black")
wn.setup(width=800, height=600)
wn.tracer(0)
main_ship = turtle.Turtle()
main_ship.speed(0)
main_ship.shape("turtle")
main_ship.color("green")
main_ship.shapesize(stretch_wid=2, stretch_len=4)
main_ship.penup()
main_ship.goto(0, -290)
main_ship.left(90)
def main_ship_right():
x = main_ship.xcor()
x += 20
main_ship.setx(x)
def main_ship_left():
x = main_ship.xcor()
x -= 20
main_ship.setx(x)
while True:
wn.update()
wn.mainloop()
wn.listen()
wn.onkeypress(main_ship_right, "Right")
wn.onkeypress(main_ship_left, "Left")
When I press the arrow keys, nothing happens but the code still runs and there are no error messages.

You have to assign keys before mainloop() which runs all time till you close window.
You don't need while True because mainloop() already runs internal loop.
You may have to remove wm.tracer(0) or you will have to run wn.update() to refresh elements in window.
import turtle
# --- functions ---
def main_ship_right():
x = main_ship.xcor()
x += 20
main_ship.setx(x)
wn.update()
def main_ship_left():
x = main_ship.xcor()
x -= 20
main_ship.setx(x)
wn.update()
# --- main ---
wn = turtle.Screen()
wn.title("Game")
wn.bgcolor("black")
wn.setup(width=800, height=600)
wn.tracer(0)
main_ship = turtle.Turtle()
main_ship.speed(0)
main_ship.shape("turtle")
main_ship.color("green")
main_ship.shapesize(stretch_wid=2, stretch_len=4)
main_ship.penup()
main_ship.goto(0, -290)
main_ship.left(90)
wn.update()
wn.listen()
wn.onkeypress(main_ship_right, "Right")
wn.onkeypress(main_ship_left, "Left")
wn.mainloop()

For this style of motion, there's another way to implement it. The idea is to leave the cursor moving in it's original orientation, but use settiltangle() to make it look like it's facing upward.
This lets us use forward(20) and backward(20) to move our cursor, and not have to write:
x = main_ship.xcor()
x += 20
main_ship.setx(x)
Works great for Space Invader style games, where the player faces upwards but moves sideways:
from turtle import Screen, Turtle
from functools import partial
screen = Screen()
screen.title("Game")
screen.bgcolor('black')
screen.setup(width=800, height=600)
main_ship = Turtle('turtle')
main_ship.speed('fastest')
main_ship.color('green')
main_ship.shapesize(stretch_wid=2, stretch_len=4)
main_ship.settiltangle(90)
main_ship.penup()
main_ship.sety(-290)
screen.onkeypress(partial(main_ship.forward, 20), 'Right')
screen.onkeypress(partial(main_ship.backward, 20), 'Left')
screen.listen()
screen.mainloop()
Only works in the turtle library that comes with Python -- online Python development sites usually provide limited turtle implementations that don't include methods like settiltangle().

Related

Why won't my square move right? I'm trying all different methods to move it in turtle module it works for up and down but not left and right?

# Game creation
import turtle
wn = turtle.Screen()
wn.title("Pong")
wn.bgcolor("Black")
wn.setup(width=800, height=800)
wn.tracer(0)
# paddle a
paddle_a = turtle.Turtle()
paddle_a.speed(0)
paddle_a.shape("square")
paddle_a.color("white")
paddle_a.penup()
paddle_a.goto(0, 0)
# Functions
def paddle_a_right():
turtle.forward(100)
wn.onkeypress(paddle_a_right, 'd')
while True:
wn.update()
Want the square to move to the right or left using 'a' or 'd' I don't know very much about turtle, I just want to program a simple game.
There are three major issues with your code. First, you need to call wn.listen() to allow the window to receive keyboard input. Second, you do turtle.forward(100) when you mean paddle_a.forward(100). Finally, since you did tracer(0), you now need to call wn.update() anytime a change is made that you want your user to see.
Here's a simplified example:
from turtle import Screen, Turtle
def paddle_right():
paddle.forward(10)
screen.update()
screen = Screen()
screen.title("Pong")
screen.bgcolor("Black")
screen.setup(width=800, height=800)
screen.tracer(0)
paddle = Turtle()
paddle.shape("square")
paddle.color("white")
paddle.penup()
screen.onkeypress(paddle_right, 'd')
screen.listen()
screen.update()
screen.mainloop()

Why my python kept crashing when it tried to run the turtle.tracer() method in turtle module?

I was coding a Snake Game using turtle module but when I add this line into my code the turtle screen and python crashed:
turtle.tracer(0)
can somebody help me so I can complete the game? Thanks a lot
my code:
from turtle import Turtle, Screen, colormode
screen = Screen()
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.title("My Snake Game")
screen.tracer(0)
x = 0
segments = []
for turtle in range(3):
turtle = Turtle("square")
turtle.color("white")
turtle.penup()
turtle.goto(0-x, 0)
x += 20
segments.append(turtle)
game_is_on = True
screen.update()
while game_is_on:
for segment in segments:
segment.forward(20)
screen.exitonclick()
I think we need to know more about what you mean by 'crashed'. If you mean everything froze, that's the code you wrote. Once you introduce tracer() you need to provide an update() for every change you want the user to see. But you don't have any update() calls in your loop so everything visually remains as it was before the loop. If you want to see the segments move, you need to do something like:
from turtle import Turtle, Screen
screen = Screen()
screen.bgcolor('black')
screen.setup(width=600, height=600)
screen.title("My Snake Game")
screen.tracer(0)
x = 0
segments = []
for turtle in range(3):
turtle = Turtle('square')
turtle.color('white')
turtle.penup()
turtle.setx(x)
x -= 20
segments.append(turtle)
screen.update()
game_is_on = True
while game_is_on:
for segment in segments:
segment.forward(20)
screen.update()
screen.exitonclick() # never reached
If you mean by 'crashed' that Python quit back to the operating system, then you need to describe the environment under which you're running this code.

Why does the turtle window stops responding?

I am trying to use the turtle module for a python, but it stops responding in further compilations after the first successful compilation. I have tried this both in Spyder and Jupyter but the result is the same.
Edit 1: This is the code I used, it is not self-made I learnt it from youtube.
Edit 2: The kernel keeps dying after I close the turtle window due to it not responding
import turtle
wn=turtle.Screen()
wn.title("Made by ")
wn.bgcolor("black")
wn.setup(width=800,height=600)
wn.tracer(0) #Keeps the screen up
#Paddle A
paddle_a=turtle.Turtle() #object of turtle
paddle_a.speed(0) #speed of animation
paddle_a.shape("square")
paddle_a.color("red")
paddle_a.shapesize(stretch_wid=5, stretch_len=1) #default size is 20*20
paddle_a.penup() #not to draw lines
paddle_a.goto(-350,0)
#Paddle B
paddle_b=turtle.Turtle() #object of turtle
paddle_b.speed(0) #speed of animation
paddle_b.shape("square")
paddle_b.color("blue")
paddle_b.shapesize(stretch_wid=5, stretch_len=1) #default size is 20*20
paddle_b.penup() #not to draw lines
paddle_b.goto(350,0)
#Ball
ball=turtle.Turtle() #object of turtle
ball.speed(0) #speed of animation
ball.shape("circle")
ball.color("white")
ball.penup() #not to draw lines
ball.goto(0,0)
ball.dx=0.09 #moves by 2 pixels
ball.dy=0.09
#Function
def paddle_a_up():
y=paddle_a.ycor() #mentions the y coordinate
y=y+20
paddle_a.sety(y) #set y coordinate to new y
def paddle_a_down():
y=paddle_a.ycor() #mentions the y coordinate
y=y-20
paddle_a.sety(y) #set y coordinate to new y
def paddle_b_up():
y=paddle_b.ycor() #mentions the y coordinate
y=y+20
paddle_b.sety(y) #set y coordinate to new y
def paddle_b_down():
y=paddle_b.ycor() #mentions the y coordinate
y=y-20
paddle_b.sety(y) #set y coordinate to new y
#Keyboard binding
wn.listen() #listen keyboard input
wn.onkeypress(paddle_a_up,'w')
wn.onkeypress(paddle_a_down,'s')
wn.onkeypress(paddle_b_up,"Up")
wn.onkeypress(paddle_b_down,"Down")
#Main loop
running=True
while running:
wn.update() #updates the screen
#movement the ball
ball.setx(ball.xcor()+ball.dx)
ball.sety(ball.ycor()+ball.dy)
This is the code I used, it is not self-made I learnt it from youtube.
It would have helped if the person who posted it on YouTube had learnt turtle properly. The main loop of this code is potentially blocking tkinter events. The code also does more work than necessary by not oriented the turtles to its advantage. See if my rewrite works better for you:
from turtle import Screen, Turtle
# Functions
def paddle_a_up():
paddle_a.forward(20)
def paddle_a_down():
paddle_a.backward(20)
def paddle_b_up():
paddle_b.forward(20)
def paddle_b_down():
paddle_b.backward(20)
# Main loop
def move():
x, y = ball.position()
ball.setposition(x + ball.dx, y + ball.dy)
screen.update()
screen.ontimer(move)
screen = Screen()
screen.bgcolor('black')
screen.setup(width=800, height=600)
screen.tracer(False)
# Paddle A
paddle_a = Turtle()
paddle_a.shape('square')
paddle_a.shapesize(stretch_wid=1, stretch_len=5)
paddle_a.setheading(90)
paddle_a.penup()
paddle_a.color('red')
paddle_a.setx(-350)
# Paddle B
paddle_b = paddle_a.clone()
paddle_b.color('blue')
paddle_b.setx(350)
# Ball
ball = Turtle()
ball.shape('circle')
ball.color('white')
ball.penup()
ball.dx = 1 # user defined object properties
ball.dy = 1
# Keyboard binding
screen.onkeypress(paddle_a_up, 'w')
screen.onkeypress(paddle_a_down, 's')
screen.onkeypress(paddle_b_up, 'Up')
screen.onkeypress(paddle_b_down, 'Down')
screen.listen()
move()
screen.mainloop()
Running under Spyder and/or Jupyter adds further complications when you restart a turtle program. The above was only tested at the command line.

How to make one turtle follow another side by side?

I am just trying to make something very simple in turtle graphics, but I'm having trouble figuring out how to make one turtle stay next to another turtle, when that turtle is being controlled by someone using the keyboard.
I've tried looking this up but I couldn't find any answers.
'''
import turtle
wn = turtle.Screen()
wn.bgcolor("black")
def bob_start():
bob.speed(0)
bob.penup()
bob.hideturtle()
bob.goto(500,0)
bob.showturtle()
def fred_start():
fred.speed(0)
fred.penup()
fred.hideturtle()
fred.goto(-500,0)
fred.showturtle()
#Fred
fred = turtle.Turtle()
fred.color("red")
fred.shape("square")
fred.shapesize(stretch_len=2,stretch_wid=2)
fred_start()
#Bob
bob = turtle.Turtle()
bob.color("blue")
bob.shape("square")
bob.shapesize(stretch_len=2,stretch_wid=2)
bob_start()
#Bob Laser
bob_laser = turtle.Turtle()
bob_laser.shape("square")
bob_laser.shapesize(stretch_len=5,stretch_wid=0.5)
bob_laser.color("yellow")
bob_laser.penup()
def fred_up():
y = fred.ycor()
y += 4
fred.sety(y)
def fred_down():
y = fred.ycor()
y -= 4
fred.sety(y)
def bob_up():
y = bob.ycor()
y += 4
bob.sety(y)
def bob_down():
y = bob.ycor()
y -= 4
bob.sety(y)
# Key Bindings
turtle.listen()
turtle.onkeypress(fred_up, "w")
turtle.onkeypress(fred_down, "s")
turtle.onkeypress(bob_up, "Up")
turtle.onkeypress(bob_down, "Down")
wn.exitonclick()
while bob_laser.ycor != bob.ycor:
bob_laser.penup()
bob_laser.hideturtle()
bob_laser.goto(500,bob.ycor)
bob_laser.showturtle()
'''
I am trying to make one turtle stay next to another turtle while that turtle is being controlled by a person.
Depending on what you're ultimately trying to do, the answer could be as simple as:
bob_laser.goto(bob.position())
whenever you move turtle bob. Here's a rework of your code using this approach:
from turtle import Screen, Turtle
def turtle_start(color, x_coordinate):
turtle = Turtle()
turtle.hideturtle()
turtle.shape('square')
turtle.shapesize(2)
turtle.speed('fastest')
turtle.setheading(90)
turtle.penup()
turtle.color(color)
turtle.setx(x_coordinate)
turtle.showturtle()
return turtle
def fred_up():
fred.forward(4)
def fred_down():
fred.backward(4)
def bob_up():
screen.onkeypress(None, 'Up') # disable complex handler inside handler
bob.forward(4)
bob_laser.goto(bob.position())
screen.onkeypress(bob_up, 'Up') # reenable handler
def bob_down():
screen.onkeypress(None, 'Down')
bob.backward(4)
bob_laser.goto(bob.position())
screen.onkeypress(bob_down, 'Down')
screen = Screen()
screen.setup(1200, 600)
screen.bgcolor('black')
# Fred
fred = turtle_start('red', -500)
# Bob
bob = turtle_start('blue', 500)
# Bob Laser
bob_laser = Turtle()
bob_laser.shape('square')
bob_laser.shapesize(stretch_len=5, stretch_wid=0.5)
bob_laser.color('yellow')
bob_laser.penup()
# Key Bindings
screen.onkeypress(fred_up, 'w')
screen.onkeypress(fred_down, 's')
screen.onkeypress(bob_up, 'Up')
screen.onkeypress(bob_down, 'Down')
screen.listen()
screen.exitonclick()

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