Spam Issue With Inputs

63 Views Asked by At

I am trying to make a rhythm game in Python (with turtle) but I have so you have to press space bar twice to active the square (which for now is just a pink border as an indicator). I found out if you press space bar fast it kind of breaks which my way to solving that was to press right arrow key but is there any other way that doesn't require pressing a key on the keyboard?

Here is the code I tried:

from turtle import Turtle, Screen

screen = Screen()
turtle = Turtle()

def current_state():
  global moving
  moving = False
  turtle.penup()

def next_state():
  global moving
  turtle.pendown()
  moving = True
  move()

turtle.hideturtle()
turtle.penup()
turtle.right(90)
turtle.forward(125)
turtle.pendown()
turtle.left(180)
turtle.forward(50)
turtle.right(90)
turtle.forward(200)
turtle.right(90)
turtle.forward(50)
turtle.right(90)
turtle.forward(200)

def space_bar():
   global current_state, next_state
   next_state()
   current_state, next_state = next_state, current_state

   turtle.speed(10)
   turtle.color("pink", "black")
   turtle.right(90)
   turtle.forward(50)
   turtle.right(90)
   turtle.forward(200)
   turtle.right(90)
   turtle.forward(50)
   turtle.right(90)
   turtle.forward(200)
   turtle.color("black", "black")
   turtle.right(90)
   turtle.forward(50)
   turtle.right(90)
   turtle.forward(200)
   turtle.right(90)
   turtle.forward(50)
   turtle.right(90)
   turtle.forward(200)

def right():
  turtle.reset()
  turtle.hideturtle()
  turtle.penup()
  turtle.speed(10)
  turtle.right(90)
  turtle.forward(125)
  turtle.pendown()
  turtle.left(180)
  turtle.forward(50)
  turtle.right(90)
  turtle.forward(200)
  turtle.right(90)
  turtle.forward(50)
  turtle.right(90)
  turtle.forward(200)

def move():
  if moving:
    screen.ontimer(move, 50)

current_state()
screen.onkey(space_bar, "space")
screen.onkey(right, "Right")
screen.listen()
screen.mainloop()
2

There are 2 best solutions below

2
Cortard On

The source of your issue is that you continue to listen space bar press and start to draw when you are already drawing. You can fix like that :

def space_bar():
   global current_state, next_state

   screen.onkey(None, "space")

   #some code
   
   screen.onkey(space_bar, "space")

Or you can fix that with a boolean :

drawing=False
def space_bar():
   global current_state, next_state, drawing

   if(drawing) :
        return

   drawing=True

   #some code
   
   drawing=False

NB : I think the turtle module draws too slowly to make a musical game and in addition it cannot play sound. Maybe you should use pygame instead.

0
cdlane On

I'm going to suggest a different approach to achieve the result you describe. I've removed your explicit state machine to keep the example simple:

from turtle import Screen, Turtle

def first_space_bar():
    screen.onkey(second_space_bar, 'space')

def second_space_bar():
    screen.onkey(None, 'space')

    turtle.color(*reversed(turtle.color()))

    draw_rectangle()

    turtle.color(*reversed(turtle.color()))

    draw_rectangle()

    screen.onkey(first_space_bar, 'space')

def draw_rectangle():

    for _ in range(2):
        turtle.forward(50)
        turtle.right(90)
        turtle.forward(200)
        turtle.right(90)

screen = Screen()

turtle = Turtle()
turtle.hideturtle()
turtle.speed('fast')
turtle.color('black', 'pink')
turtle.width(5)

turtle.penup()
turtle.left(90)
turtle.backward(125)
turtle.pendown()

draw_rectangle()

screen.onkey(first_space_bar, 'space')
screen.listen()
screen.mainloop()