1

I'm trying to make an object (dot) float around the screen smoothly using the turtle library, but the movement on that is being produced right now is very "laggy" and "jumpy". Is there any way to fix this? If not, is there another library I can use to animate a dot floating around the screen?

# screen
Screen = turtle.Screen()
Screen.title("Moving Block")
Screen.bgcolor("black")
Screen.setup(width=1000, height=700)

# game
Block = turtle.Turtle()
Block.speed(0)
Block.shape("square")
Block.color("grey")
Block.penup()
Block.turtlesize(5,5)
Block.goto(0, 0)

# movement
def go_up():
    y = Block.ycor()
    if y <= 290:
        Block.sety(y + 10)

def go_down():
    y = Block.ycor()
    if y >= -280:
        Block.sety(y - 10)

def go_left():
    x = Block.xcor()
    if x >= -440:
        Block.setx(x - 10)

def go_right():
    x = Block.xcor()
    if x <= 430:
        Block.setx(x + 10)

# keyboard
Screen.onkey(go_up, "Up")
Screen.onkey(go_down, "Down")
Screen.onkey(go_left, "Left")
Screen.onkey(go_right, "Right")
Screen.listen()
Screen.mainloop()
martineau
  • 119,623
  • 25
  • 170
  • 301
chrlee
  • 21
  • 3
  • Can you post some of your code so we know what to work with? – SanguineL Aug 03 '22 at 15:50
  • I justed edited my post! This was previous code that I was working with. It had to do with just moving a block up, down, left and right. – chrlee Aug 03 '22 at 16:10
  • Use smaller steps but do them more often. – Klaus D. Aug 03 '22 at 16:12
  • @KlausD. Thank you. Do you mind elaborating a little bit more? I'm a beginner and don't really know how to do that. I really appreciate it! – chrlee Aug 03 '22 at 16:16
  • @chrlee Do you want the square to move each individual time you press down or while you hold the button down for a longer period of time? – SanguineL Aug 03 '22 at 16:42
  • @SanguineL I would like it to move smoother when I hold the button. – chrlee Aug 03 '22 at 16:49
  • 1
    Does this answer your question? [How to bind several key presses together in turtle graphics?](https://stackoverflow.com/a/70979967/6243352). I would disable tracer and run a custom update loop to free turtle from its built-in rendering loop. Use a separate set of keys that are checked during the update loop rather than trying to trigger movement directly from the handlers. There's a simple example that's more or less the same as your code in the linked post. – ggorlen Aug 03 '22 at 19:05

2 Answers2

0

I do just want to go ahead and say that since turtle is a GUI module for beginners, there are lots of limitations to customization and speed.

That being said, you can use onkeypress instead of onkey to be able to hold a button down.

It still has a little glitch but that's mainly the limitation of the keyboard and not anything you can really control.

However, if you were to change the amount of space the block moves each time, it will look smoother. You just have to substitute speed for smoothness.

delta = 5 #change this to make it smoother or faster. Small numbers make it smoother. Large numbers make it faster.

# movement
def go_up():
    y = Block.ycor()
    if y <= 290:
        Block.sety(y + delta)

def go_down():
    y = Block.ycor()
    if y >= -280:
        Block.sety(y - delta)

def go_left():
    x = Block.xcor()
    if x >= -440:
        Block.setx(x - delta)

def go_right():
    x = Block.xcor()
    if x <= 430:
        Block.setx(x + delta)


# keyboard
Screen.onkeypress(go_up, "Up")
Screen.onkeypress(go_down, "Down")
Screen.onkeypress(go_left, "Left")
Screen.onkeypress(go_right, "Right")

Hope this helps!

SanguineL
  • 1,189
  • 1
  • 7
  • 18
  • I tried this, substituting `onkeypress` for `onkeyrelease` (aka `onkey`) and saw *no difference* on my system. Key repeat kicks in, but its rate is set by the operating system through a preference panel. I don't see why `onkeypress` and `onkeyrelease` would react differently to holding a button down -- key repeat would cause each to be called in turn at the same rate. Please explain further. – cdlane Aug 03 '22 at 23:57
0

Below is the generic tracer(0) and update() approach, see if it's sufficient to your needs. One significant issue with "when I hold the button" is that the operating system can step in to control the rate of key repeat, of which Python is unaware:

from turtle import Screen, Turtle

# movement
def go_up():
    if (y := block.ycor()) <= 290:
        block.sety(y + 10)
        screen.update()

def go_down():
    if (y := block.ycor()) >= -280:
        block.sety(y - 10)
        screen.update()

def go_left():
    if block.xcor() >= -440:
        block.backward(10)
        screen.update()

def go_right():
    if block.xcor() <= 430:
        block.forward(10)
        screen.update()

# game
block = Turtle('square')
block.color('grey')
block.penup()
block.turtlesize(5)

# screen
screen = Screen()
screen.setup(width=1000, height=700)
screen.title("Moving block")
screen.bgcolor('black')
screen.tracer(False)

# keyboard
screen.onkey(go_up, 'Up')
screen.onkey(go_down, 'Down')
screen.onkey(go_left, 'Left')
screen.onkey(go_right, 'Right')

screen.listen()
screen.mainloop()
cdlane
  • 40,441
  • 5
  • 32
  • 81