Use of ontimer function to make two turtles move at same time - python

I 've been struggling to make both turtles move at the same time. Either one moves or they are both are frozen. I'm currently using the ontimer() function but still don't understand it completely.
The game is if you are wondering based of the paperio game but two players go against each other on the same keyboard and screen
My code:
from turtle import *
import turtle
p1f = True
p2f = True
title("1v1 Paperio")
p1move = Turtle()
p2move = Turtle()
t1 = Turtle()
t2 = Turtle()
screen = Screen()
def Setup1():
t1.pencolor("aquamarine")
t1.pensize(5)
t1.speed(10)
t1.fillcolor("light sea green")
t1.hideturtle()
t1.penup()
t1.goto(-200, -200)
t1.pendown()
t1.begin_fill()
for i in range(4):
t1.forward(50)
t1.left(90)
t1.end_fill()
p1move.penup()
p1move.goto(-175, -175)
p1move.pendown()
def Setup2():
t2.pencolor("crimson")
t2.pensize(5)
t2.speed(10)
t2.fillcolor("red")
t2.hideturtle()
t2.penup()
t2.goto(200, 200)
t2.pendown()
t2.begin_fill()
for i in range(4):
t2.forward(50)
t2.left(90)
t2.end_fill()
p2move.penup()
p2move.goto(225, 225)
p2move.pendown()
def p1setup():
p1move.pencolor("aquamarine")
p1move.pensize(5)
p1move.speed(10)
p1move.fillcolor("light sea green")
def p2setup():
p2move.pencolor("crimson")
p2move.pensize(5)
p2move.speed(10)
p2move.fillcolor("red")
# ycord
# heading
def p1moving():
def p1k1():
p1x1 = p1move.xcor()
p1y1 = p1move.ycor()
while p1f == True:
p1move.forward(1)
screen.ontimer(p1moving, 1)
def p1k2():
p1move.left(90)
def p1k3():
p1move.right(90)
def p2moving():
def p2k1():
p2f = True
p2x2 = p2move.xcor()
p2y2 = p2move.ycor()
while p2f == True:
p2move.forward(1)
screen.ontimer(p2moving, 1)
def p2k2():
p2move.left(90)
def p2k3():
p2move.right(90)
screen.listen()
screen.onkey(p1k1, "w")
screen.onkey(p1k2, "a")
screen.onkey(p1k3, "d")
screen.onkey(p2k1, "Up")
screen.onkey(p2k2, "Left")
screen.onkey(p2k3, "Right")
if __name__ == "__main__":
Setup1()
Setup2()
p1setup()
p2setup()
screen.mainloop()

Most of your code seems reasonable until you get to the key and timer event functions -- you have unused variables and functions that don't get called. Your functions defined inside functions are particularly problematic. I've reworked your code below to run as you describe. I've also done some speed optimizations to make it "play" a little better:
from turtle import Screen, Turtle
def setup1():
base1.hideturtle()
base1.color("light sea green", "aquamarine")
base1.pensize(5)
base1.penup()
base1.goto(-200, -200)
base1.pendown()
base1.begin_fill()
for _ in range(4):
base1.forward(50)
base1.left(90)
base1.end_fill()
pen1.color("light sea green", "aquamarine")
pen1.pensize(5)
pen1.setheading(0)
pen1.penup()
pen1.goto(-175, -175)
pen1.pendown()
def setup2():
base2.hideturtle()
base2.color("red", "pink")
base2.pensize(5)
base2.penup()
base2.goto(200, 200)
base2.pendown()
base2.begin_fill()
for _ in range(4):
base2.forward(50)
base2.left(90)
base2.end_fill()
pen2.color("red", "pink")
pen2.pensize(5)
pen2.setheading(180)
pen2.penup()
pen2.goto(225, 225)
pen2.pendown()
def p1k1():
screen.onkey(None, 'w')
def p1forward():
pen1.forward(1)
screen.update()
screen.ontimer(p1forward, 10)
p1forward()
def p1k2():
pen1.left(90)
screen.update()
def p1k3():
pen1.right(90)
screen.update()
def p2k1():
screen.onkey(None, 'Up')
def p2forward():
pen2.forward(1)
screen.update()
screen.ontimer(p2forward, 10)
p2forward()
def p2k2():
pen2.left(90)
screen.update()
def p2k3():
pen2.right(90)
screen.update()
screen = Screen()
screen.title("1v1 Paperio")
screen.tracer(False)
base1 = Turtle()
pen1 = Turtle()
setup1()
base2 = Turtle()
pen2 = Turtle()
setup2()
screen.onkey(p1k1, 'w')
screen.onkey(p1k2, 'a')
screen.onkey(p1k3, 'd')
screen.onkey(p2k1, 'Up')
screen.onkey(p2k2, 'Left')
screen.onkey(p2k3, 'Right')
screen.update()
screen.listen()
screen.mainloop()

Related

i am getting an error it is saying turtle object not callable

import turtle
import tkinter as tk
def importantmoving():
win = turtle.Screen()
win.title("moving")
win.bgcolor("black")
win.setup(width=800, height=800)
win.tracer(0)
#moving
a = turtle.Turtle()
a.speed(0)
a.shape("square")
a.color("white")
a.shapesize(stretch_wid=5,stretch_len=5)
a.penup()
a.goto(0,0)
#functions
def a_up():
y = a.ycor()
y += 20
a.sety(y)
def a_down():
y = a.ycor()
y -= 20
a.sety(y)
def a_right():
x = a.xcor()
x += 20
a.setx(x)
def a_left():
x = a.xcor()
x -= 20
a.setx(x)
#keyboard binding
win.listen()
win.onkeypress(a,"Up")
win.onkeypress(a,"Right")
win.onkeypress(a,"Down")
win.onkeypress(a,"Left")
while True:
win.update()
importantmoving()
and this is the code
i first tried to run my code see in which line my error was and the it came up with line 1921 and my code is 43 lines so i didn't know what to do so i ask here
Besides the callback issue that #JohnnyMopp notes (+1), this code is poorly constructed. The while True: loop is simply not needed nor desirable. It's not clear why everything is bundled inside importantmoving(). You also don't need to import tkinter. Below is my rework of your code, see if it does what you intend:
from turtle import Screen, Turtle
def a_up():
turtle.sety(turtle.ycor() + 20)
def a_down():
turtle.sety(turtle.ycor() - 20)
def a_right():
turtle.setx(turtle.xcor() + 20)
def a_left():
turtle.setx(turtle.xcor() - 20)
screen = Screen()
screen.title("moving")
screen.bgcolor('black')
screen.setup(width=800, height=800)
turtle = Turtle()
turtle.shape('square')
turtle.shapesize(5)
turtle.color('white')
turtle.speed('fastest')
turtle.penup()
screen.onkeypress(a_up, 'Up')
screen.onkeypress(a_right, 'Right')
screen.onkeypress(a_down, 'Down')
screen.onkeypress(a_left, 'Left')
screen.listen()
screen.mainloop()

Why aren't my turtles turning around with gooma.xcor()?

I'm remaking mario, and I have some goombas, but they aren't turning around at the end. I don't know why, since it looks fine to me. I know they don't have hitboxes, because I haven't added them yet, and I'm a beginer. Please use the same names.
import random
import math
import time
turt = turtle.Turtle()
tart = turtle.Turtle()
goomba = turtle.Turtle()
nb = turtle.Turtle()
qb = turtle.Turtle()
m = turtle.Turtle()
m.ht()
screen = turtle.Screen()
screen.tracer(0)
screen.bgcolor("lightblue")
turt.up()
turt.goto(-500,-350)
turt.down()
def block():
turt.color("goldenrod")
turt.begin_fill()
for i in range(4):
turt.forward(50)
turt.right(90)
turt.end_fill()
turt.ht()
b = -500
#r1
for i in range(20):
turt.st()
block()
turt.up()
b = b+50
turt.goto(b,-300)
turt.down()
tart.up()
tart.color("red")
tart.pensize("10")
tart.shape("circle")
tart.goto(-350,-290)
tart.down()
goomba.up()
goomba.color("brown")
goomba.shape("circle")
goomba.pensize(20)
goomba.goto(-200,-290)
goomba.down()
nb.up()
nb.goto(-100,-200)
nb.shape("square")
nb.pensize(10)
nb.color("brown")
nb.down()
nb2 = nb.clone()
nb2.goto(-80,-200)
qb.up()
qb.goto(-60,-200)
qb.color("yellow")
qb.shape("square")
qb.down()
nb3 = nb.clone()
nb3.goto(-40,-200)
goomba2 = goomba.clone()
goomba2.up()
goomba2.goto(200,-290)
def up():
tart.setheading(90)
screen.tracer(1)
for i in range(75):
tart.forward(1)
tart.setheading(270)
tart.forward(75)
screen.tracer(0)
def down():
tart.setheading(270)
tart.forward(10)
def right():
tart.setheading(0)
tart.forward(10)
def left():
tart.setheading(180)
tart.forward(10)
tart.up()
screen.onkey(up, "w")
screen.onkey(down, "s")
screen.onkey(right, "d")
screen.onkey(left, "a")
screen.listen()
goomba.up()
screen.update()
goomba.right(180)
goomba2.right(180)
tart.goto(-350,-280)
while True:
goomba.forward(1)
if tart.ycor() < -281:
tart.setheading(0)
tart.goto(-350,-280)
goomba2.forward(1)
if goomba.xcor() > 351:
goomba.right(180)
if goomba2.xcor() > 351:
goomba2.right(180)
screen.update()

Make a score system

How can I make a score system, that increases by one, when I hit square1. A score system, that restart back to 0, when I hit square2. And also loop back to the beginning position, when I hit square2. So loop back and restart the score to 0, when I hit square 2.
import turtle
import math
from time import sleep
wn = 0
player = turtle.Turtle()
square1 = turtle.Turtle()
square2 = turtle.Turtle()
speed = 1
def init():
wn = turtle.Screen()
wn.bgcolor("blue")
wn.tracer(3)
turtle.listen()
turtle.onkey(turnLeft, "Left")
turtle.onkey(turnRight, "Right")
def initCharacters():
player.color("red")
player.shape("circle")
player.penup()
player.speed(0)
player.setposition(25, 20)
square1.color("white")
square1.shape("square")
square1.penup()
square1.speed(0)
square1.setposition(100, 100)
square2.color("yellow")
square2.shape("square")
square2.penup()
square2.speed(0)
square2.setposition(150, 50)
def distanceIsLessThan(p, q, distance):
return math.pow(p.xcor() - q.xcor(), 2) + math.pow(p.ycor() - q.ycor(), 2) < math.pow(distance, 2)
def turnLeft():
player.left(90)
def turnRight():
player.right(90)
def main():
init()
initCharacters()
while True:
player.forward(speed)
if distanceIsLessThan(player, square1, 20) or \
distanceIsLessThan(player, square2, 20):
# print("Touch")
initCharacters()
sleep(0.02)
if __name__ == "__main__":
main()
This is basically what you want:
import turtle
import math
from time import sleep
#Adding the integer for the score
score=0
wn = 0
player = turtle.Turtle()
square1 = turtle.Turtle()
square2 = turtle.Turtle()
speed = 1
#Here Im making a new turtle for showing the score
turtle_score=turtle.Turtle()
turtle_score.penup()
turtle_score.hideturtle()
turtle_score.goto(-300.00,-245.00)
turtle_score.write("")
def init():
wn = turtle.Screen()
wn.bgcolor("blue")
wn.tracer(3)
turtle.listen()
turtle.onkey(turnLeft, "Left")
turtle.onkey(turnRight, "Right")
def initCharacters():
player.color("red")
player.shape("circle")
player.penup()
player.speed(0)
player.setposition(25, 20)
square1.color("white")
square1.shape("square")
square1.penup()
square1.speed(0)
square1.setposition(100, 100)
square2.color("yellow")
square2.shape("square")
square2.penup()
square2.speed(0)
square2.setposition(150, 50)
def distanceIsLessThan(p, q, distance):
return math.pow(p.xcor() - q.xcor(), 2) + math.pow(p.ycor() - q.ycor(), 2) < math.pow(distance, 2)
def turnLeft():
player.left(90)
def turnRight():
player.right(90)
def main():
init()
initCharacters()
global score
while True:
player.forward(speed)
#Checking which square the player collided with and updating the score.
if distanceIsLessThan(player, square1, 20):
score=score+1
player.fd(40)
turtle_score.undo()
turtle_score.write(str(score))
if distanceIsLessThan(player, square2, 20):
score=0
turtle_score.undo()
turtle_score.write(str(score))
# print("Touch")
initCharacters()
sleep(0.02)
if __name__ == "__main__":
main()
The score shows up at the bottom left corner of the screen.

Is there a way to keep drawing a square with one turtle while, at the same time, moving another turtle with the arrow keys?

I am trying to move a drawing slowly across the screen as I move another turtle with the arrow keys. The problem is that my code only makes the drawing move across the screen, not allowing me to move the other turtle with the keys. I have tried defining the keys inside of the while true statement and it still came out with the same outcome.
Here is my code:
from turtle import *
setup(500, 500)
Screen()
screen = Screen()
title("Turtle Keys")
turtle1 = Turtle()
turtle2 = Turtle()
def moving_square():
turtle1.fillcolor("Red")
turtle1.begin_fill()
for i in range(4):
turtle1.forward(50)
turtle1.right(90)
turtle1.end_fill()
turtle1.goto(-350, 0)
turtle1.pendown()
turtle1.hideturtle()
def k1():
turtle2.forward(50)
def k2():
turtle2.left(45)
def k3():
turtle2.right(45)
def k4():
turtle2.back(25)
onkey(k1, "Up")
onkey(k2, "Left")
onkey(k3, "Right")
onkey(k4, "Down")
while True:
moving_square()
screen.update()
turtle1.forward(5)
It needs listen() to react on pressed keys.
And you have this information even in documentation for onkey()
from turtle import *
# --- functions ---
def moving_square():
turtle1.fillcolor("Red")
turtle1.begin_fill()
for i in range(4):
turtle1.forward(50)
turtle1.right(90)
turtle1.end_fill()
def k1():
turtle2.forward(50)
def k2():
turtle2.left(45)
def k3():
turtle2.right(45)
def k4():
turtle2.back(25)
# -- main ---
setup(500, 500)
Screen()
screen = Screen()
title("Turtle Keys")
turtle1 = Turtle()
turtle2 = Turtle()
turtle1.goto(-350, 0)
turtle1.pendown()
turtle1.hideturtle()
onkey(k1, "Up")
onkey(k2, "Left")
onkey(k3, "Right")
onkey(k4, "Down")
listen()
while True:
moving_square()
screen.update()
turtle1.forward(5)
For more game-like action, I would go about this a different way. First, by not drawing a red square but by making the first turtle into a red square. Second, by using a timed event instead of a while True: loop:
from turtle import Screen, Turtle
WIDTH, HEIGHT = 500, 500
BLOCK_SIZE = 50
CURSOR_SIZE = 20
def k1():
turtle.forward(50)
def k2():
turtle.left(45)
def k3():
turtle.right(45)
def k4():
turtle.back(25)
def move():
block.forward(1)
if block.xcor() < WIDTH/2 + BLOCK_SIZE/2:
screen.ontimer(move, 75) # milliseconds
screen = Screen()
screen.setup(WIDTH, HEIGHT)
screen.title("Turtle Keys")
block = Turtle()
block.hideturtle()
block.shape('square')
block.fillcolor('red')
block.shapesize(BLOCK_SIZE / CURSOR_SIZE)
block.penup()
block.setx(-WIDTH/2 - BLOCK_SIZE/2)
block.showturtle()
turtle = Turtle()
turtle.shape('turtle')
turtle.penup()
screen.onkey(k1, 'Up')
screen.onkey(k2, 'Left')
screen.onkey(k3, 'Right')
screen.onkey(k4, 'Down')
screen.listen()
move()
screen.mainloop()
You can increase the speed of the block by adjusting block.forward(1) to higher value. And if you need a trailing line, you can put the pen down.

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()

Categories