System sends to programs information about pressed key ("events"
) only when key changes state from not-pressed
to pressed
or from pressed
to not-pressed
(released
). It doesn't send events when you hold down key.
You have to use onkeypressed()
to set arrow_up_pressed = True
and onkeyreleased()
to reset arrow_up_pressed = False
and ontimer()
to run repeatedly code which checks if arrow_up_pressed
is True
and move object up. The same you should do with arrow_down_pressed
, etc.
Or you can use variable speed
instead of arrow_up_pressed
and arrow_down_pressed
so you can assing +15
or -15
to the same variable (or 0
when keys are released). And again you need ontimer
to run repeatedly code which add speed to position.
In example I use second method.
Minimal working code
import turtle
def paddle_a_up():
global a_speed_y
a_speed_y = +15
def paddle_a_down():
global a_speed_y
a_speed_y = -15
def paddle_a_left():
global a_speed_x
a_speed_x = -15
def paddle_a_right():
global a_speed_x
a_speed_x = +15
def paddle_a_stop_y():
global a_speed_y
a_speed_y = 0
def paddle_a_stop_x():
global a_speed_x
a_speed_x = 0
def update_frame():
x, y = paddle_a.position()
y += a_speed_y
x += a_speed_x
paddle_a.goto(x, y)
# here update position for other objects - ie. move ball
# run again after 50ms
wn.ontimer(update_frame, 50) # 50ms means ~20 FPS (Frames Per Second) (1000/50 = 20)
# --- main ---
# default values at start
a_speed_x = 0
a_speed_y = 0
wn = turtle.Screen()
paddle_a = turtle.Turtle()
# run first time after 50ms
wn.ontimer(update_frame, 50) # 50ms means ~20 FPS (Frames Per Second) (1000ms / 50ms = 20)
# binds
wn.onkeypress(paddle_a_up, "Up")
wn.onkeypress(paddle_a_down, "Down")
wn.onkeypress(paddle_a_left, "Left")
wn.onkeypress(paddle_a_right, "Right")
wn.onkeyrelease(paddle_a_stop_y, "Up")
wn.onkeyrelease(paddle_a_stop_y, "Down")
wn.onkeyrelease(paddle_a_stop_x, "Left")
wn.onkeyrelease(paddle_a_stop_x, "Right")
wn.listen()
wn.mainloop()
BTW: The same way you would have to do this in PyGame
or Pyglet
.
EDIT:
You get better result if you add/substract value to speed
instead of assigning - because when you press left
and right
at the same time then it will stop move (because speed +15 and -15 will gives 0), and when you release only one - ie. left
- then it will again move right
. In previous version when you release one but you still keep pressed other then it doesn't move again.
import turtle
def paddle_a_up_pressed():
global a_speed_y
a_speed_y += 15
def paddle_a_down_pressed():
global a_speed_y
a_speed_y -= 15
def paddle_a_left_pressed():
global a_speed_x
a_speed_x -= 15
def paddle_a_right_pressed():
global a_speed_x
a_speed_x += 15
def paddle_a_up_released():
global a_speed_y
a_speed_y -= 15
def paddle_a_down_released():
global a_speed_y
a_speed_y += 15
def paddle_a_left_released():
global a_speed_x
a_speed_x += 15
def paddle_a_right_released():
global a_speed_x
a_speed_x -= 15
def update_frame():
x, y = paddle_a.position()
x += a_speed_x
y += a_speed_y
paddle_a.goto(x, y)
# run again after 50ms
wn.ontimer(update_frame, 50) # 50ms means ~20 FPS (Frames Per Second) (1000/50 = 20)
# --- main ---
# default values at start
a_speed_x = 0
a_speed_y = 0
wn = turtle.Screen()
paddle_a = turtle.Turtle()
# run first time after 50ms
wn.ontimer(update_frame, 50) # 50ms means ~20 FPS (Frames Per Second) (1000/50 = 20)
# binds
wn.onkeypress(paddle_a_up_pressed, "Up")
wn.onkeypress(paddle_a_down_pressed, "Down")
wn.onkeypress(paddle_a_left_pressed, "Left")
wn.onkeypress(paddle_a_right_pressed, "Right")
wn.onkeyrelease(paddle_a_up_released, "Up")
wn.onkeyrelease(paddle_a_down_released, "Down")
wn.onkeyrelease(paddle_a_left_released, "Left")
wn.onkeyrelease(paddle_a_right_released, "Right")
wn.listen()
wn.mainloop()