Error with the command onkey()
Question: I'm trying to create a shooter-like game in Python turtle (it's basically a
copy of the game `Boom dots`). But I'm having a lot of issues, because I'm
kind of new to programming. This time the command onkey() doesn't work. I
tried everything but nothing seems to be of help. I don't get any traceback
errors. It's just that defined command doesn't work when I press the button
which is assigned to the command.

Part of code in which I suspect the problem is:

    
    
    def cannon_left():
      cannon_x = cannon_x - 10
      cannon.goto(cannon_x, 0)
    
    def cannon_right():
      cannon_x = cannon_x + 10
      cannon.goto(cannon_x, 0)
    
    def reset1():
      live_score = 0
    

The whole code:

    
    
    import random
    import turtle
    
    #images
    image_coconut = "Coconut.png"
    image_banana = "Banana.png"
    image_pineapple = "Pineapple.png"
    image_cannon = "Cannon.png"
    
    #definitions
    live_score = 0
    screen = turtle.Screen()
    wn = turtle.Screen()
    cannon = turtle.Turtle()
    enemy = turtle.Turtle()
    score = turtle.Turtle()
    background = turtle.Turtle()
    reset = turtle.Turtle()
    bullet = turtle.Turtle()
    enemy_x = enemy.xcor()
    enemy_y = enemy.ycor()
    cannon_x = 0
    move_speed = 2
    enemy1 = 0
    
    def cannon_shooting(x, y):
      bullet.showturtle()
      bullet.forward(280)
      if bullet.ycor() == enemy_y - 10:
        if not bullet.xcor() == enemy_x - 10:
          if live_score == 0:
            live_score = 0
          else:
            live_score = live_score + 1
        if bullet.xcor() == enemy_x - 10:
          live_score = live_score + 1
          enemy1 = random.randint(1, 3)
      bullet.hideturtle()
    
    
    #image adding
    screen.addshape(image_coconut)
    screen.addshape(image_banana)
    screen.addshape(image_pineapple)
    screen.addshape(image_cannon)
    
    def cannon_left():
      cannon_x = cannon_x - 10
      cannon.goto(cannon_x, 0)
    
    def cannon_right():
      cannon_x = cannon_x + 10
      cannon.goto(cannon_x, 0)
    
    def reset1():
      live_score = 0
    
    #setup
    bullet.hideturtle()
    bullet.speed(50)
    bullet.penup()
    bullet.shape('circle')
    bullet.goto(0, -140)
    bullet.left(90)
    
    enemy.speed(0)
    enemy.penup()
    enemy.hideturtle()
    enemy.goto(0, 140)
    screen.addshape(image_coconut)
    enemy.shape(image_coconut)
    enemy.showturtle()
    
    cannon.speed(0)
    cannon.penup()
    cannon.hideturtle()
    cannon.goto(0, -140)
    screen.addshape(image_cannon)
    cannon.shape(image_cannon)
    cannon.showturtle()
    cannon.left(90)
    
    score.speed(0)
    score.penup()
    score.hideturtle()
    score.goto(90, -190)
    score.color('white')
    score.write("Your score: %s" % live_score, font=(None, 11, "bold"))
    
    reset.speed(0)
    reset.penup()
    reset.hideturtle()
    reset.goto(-185, -190)
    reset.color('white')
    reset.write("Reset (R)", font=(None, 11, "bold"))
    
    #movement
    while True:
      enemy.forward(move_speed)
      if enemy.xcor() == 140:
        enemy.left(180)
        enemy.forward(move_speed)
      if enemy.xcor() == -140:
        enemy.right(180)
        enemy.forward(move_speed)
        if enemy1 == 1:
          screen.addshape(image_banana)
          enemy.shape(image_banana)
        if enemy1 == 2:
          screen.addshape(image_pineapple)
          enemy.shape(image_pineapple)
        if enemy1 == 3:
          enemy.shape(image_coconut)
    
    #key presses
    wn.onkey(cannon_right, "D")
    wn.onkey(cannon_left, "A")
    wn.onkey(cannon_right, "Right")
    wn.onkey(cannon_left, "Left")
    wn.onkey(cannon_shooting, "SPACE")
    wn.onkey(reset1, "R")
    
    #others
    wn.listen()
    wn.mainloop()
    

**Note:** I'm creating the game in `Trinket.io`. Click
[here](https://trinket.io/python/ed2c612824 "Trinket.io") to go to the
`Trinket.io` version.


Answer: Python is an imperative programming language. This means that _order matters_.
What appears to be the main logic of your game is declared before the `onkey`
initialization part as an infinite loop:

    
    
    #movement
    while True:
      enemy.forward(move_speed)
      ...
    

As this loop runs forever, it means that will start executing and the code
will never reach the part where you set up the key mapping.

You need the code that is in the loop put this code in a function, and decide
when exactly it needs to be called by Turtle. You should not put the `while
True` as part of the function, as there already exists a main loop managed by
Turtle.

