3

I've added a function definition to tell my turtle to jump when you press the space bar. There is also a while True loop in my code, and whenever the space button is pressed, the while True loop freezes momentarily until the jump is finished and then carries on.

I've tried adding the function definition in the while True loop and outside. I can only put the function definition before the while True loop, because if I put it after the while True, the code will never reach it.

#making the player jump
def jump():
    player.fd(100)
    player.rt(180)
    player.fd(100)
    player.lt(180)

turtle.listen()
turtle.onkey(jump, "space")

I'm expecting the while True loop to not freeze, but wherever I've tried putting the def, it doesn't seem to work.

I also saw another answer to something similar to this, but didn't understand how I could apply that to my code.

Any other suggestions would be great.

1
  • Just saying, some modules are single threaded, which means they take command by command, and while loops crash them Commented Apr 9, 2019 at 23:28

3 Answers 3

2

Until you get that async stuff to work, here's a minimalist implementation using turtle's own timer event to keep an obstacle moving forward, even when jumping:

from turtle import Screen, Turtle

def jump():
    screen.onkey(None, 'space')  # disable handler inside handler

    if jumper.ycor() == 0:  # if jumper isn't in the air
        jumper.forward(150)
        jumper.backward(150)

    screen.onkey(jump, 'space')

def move():
    hurdle.forward(6)
    if hurdle.xcor() > -400:
        screen.ontimer(move, 100)

jumper = Turtle('turtle')
jumper.speed('slowest')
jumper.penup()
jumper.setheading(90)

hurdle = Turtle('turtle')
hurdle.speed('fastest')
hurdle.penup()
hurdle.setheading(180)
hurdle.setx(400)

screen = Screen()
screen.onkey(jump, 'space')
screen.listen()

move()

screen.mainloop()

You can find several, more fleshed out versions of this on SO by searching for '[turtle-graphics] jump'

Avoid using a while True: loop in turtle's event-based environment.

Sign up to request clarification or add additional context in comments.

Comments

1

I expected that it can be hard to do it with async but I built example which works.

Inside jump I use asyncio.sleep so this way when one turtle is sleeping then other turtle can walk. Without asyncio.sleep first turtle walk all the time.

import asyncio
import turtle

t1 = turtle.Turtle()
t2 = turtle.Turtle()

async def jump1():
    while True:
        t1.fd(100)
        await asyncio.sleep(0.01)
        t1.left(90)


async def jump2():
    while True:
        t2.fd(100)
        await asyncio.sleep(0.01)
        t2.right(90)

tasks = [jump1(), jump2()]

# Python 3.6.7
loop = asyncio.get_event_loop()    
loop.run_until_complete(asyncio.wait(tasks))

# Python 3.7
#asyncio.run(asyncio.wait(tasks))

But building something more complex can be more difficult.

I also found aioturtle - turtle which use async. Maybe it will be easier to use aioturtle.

4 Comments

@cdlane I run python 3.7 - maybe there is the problem. I never used async before but I will try to find solution for this problem.
@cdlane I made version which works with Python 3.6.7. I don't have older version any more.
You didn't have to do that--I was going to move to a machine with 3.7! Update works fine on my 3.6.4. I appreciate conceptually what it's doing, but visually I don't see anything that I couldn't also do synchronously. Needs more wow! factor.
@cdlane frankly I start building this code to confirm that it will NOT work or it will be very hard to build it - especially to use async's loop with mainloop. But accidently it works and it wasn't hard to build it. But adding other elements can make problem. But after creating working code I decide to show it even if it not so useful. Normally I would rather create code with threading or try to use ontimer. async needs to build code in different way and it is still new way for me.
0

The problem is the following:
the code for the jump event is called synchronously. That means, everything has to wait for jump() to finish before continuing. this can maybe be fixed by declaring / calling the jump() method asynchronously. This website does a good job of explaining what asynchronous python means and how to implement it: https://hackernoon.com/asynchronous-python-45df84b82434

in short, here's how it would be implemented(in python 3.3 or higher):

async def jump():
    #your code here

this just makes the jump() function run asynchronously.
now, whenever you call it, you have to call it like this:

await jump()

this might not work, depending on your exact setup.

i hope this helps. please, ask me if you have any further questions.

EDIT: example

4 Comments

thankyouu, im sure it willl help but ill have to read it a couple times to fully understand it
Sure. I sure know it took me an hour to fully understand :D . it's a lot of information at once.
I see two problems with this: (1) turtle's functions wasn't created to work asynchronously so jump also may not work asynchronously. (2) turtle runs mainloop() which works all time and async also need to run loop which works all time - so there is problem to work both at the same time.
I found aioturtle which use async/await to work but I didn't test it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.