pythonpython-3.xturtle-graphicsflappy-bird-clone

When press a key to move the turtle up, my other turtles freeze


When I run my code and I move my turtle up with the space bar, all the obstacles, that are supposed to be moving, stop moving. What causes the problem and how do I fix this?

I have no idea what can cause this problem and I've tried Googling but can't find anything. Since this is my first week of trying out Python, or programming in general, I have no idea what I've done wrong.

import turtle
import math
import random
#starting conditions
player = turtle.Turtle()
player.hideturtle()
player.penup()
player.shape("turtle")
player.setheading(90)
player.setpos(-200,0)
player.speed(1)
player.color("yellow")
canvas = turtle.Screen()
canvas.bgcolor("black")
canvas.title("gamescreen")
gameover = turtle.Turtle()
gameover.penup()
gameover.hideturtle()
gameover.color("red")
gameover.speed(0)
gameover.setpos(-150, 330)
scoreboard = turtle.Turtle()
scoreboard.hideturtle()
scoreboard.color("blue")
scoreboard.penup()
scoreboard.setpos(-300,320)
#borders
box = turtle.Turtle()
box.speed(0)
box.hideturtle()
box.setheading(0)
box.color("blue")
box.pensize(3)
box.penup()
box.setpos(-300,-300)
for i in range(4):
    box.pendown()
    box.forward(600)
    box.left(90)
player.showturtle()
#movement
spd = 50
def playerup():
    player.sety(player.ycor()+ spd)
    if (player.ycor()+ spd) > 287:
        player.speed(0)
        player.sety(287)
        player.speed(1)
def playerdown():
    player.sety(player.ycor()- spd)
    if (player.ycor()+ spd) < -287:
        player.speed(0)
        player.sety(-287)
        player.speed(1)
turtle.listen()
gravity = 3
obsspd = 3
#collision
def hit(t1, t2):
              xdistance = t1.xcor()-t2.xcor()
              ydistance = t1.ycor()-t2.ycor()
              if (abs(xdistance) < 20) and (abs(ydistance) < 130):
               return True

              else:
                  return False


#obstacle list
number_obstacles = 2
obstacles = []
numberslistx = list(range(-100,280))
numberslisty = list(range(143,190))  

for i in range(number_obstacles):
    obstacles.append(turtle.Turtle())
for obstacle in obstacles:
    obstacle.hideturtle()
    obstacle.speed(0)
    obstacle.color("green")
    obstacle.penup()
    obstacle.shape("square")
    obstacle.turtlesize(12,3)
    xobs = random.choice(numberslistx)
    yobs = random.choice(numberslisty)
    obstacle.setposition(xobs,yobs)
    obstacle.showturtle()
#obstacle2 list
number_obstacles2 = 2
obstacles2 = []
numberslistx = list(range(-100,280))
numberslisty = list(range(160,190))           
for i in range (number_obstacles2):
    obstacles2.append(turtle.Turtle())
for obstacle2 in obstacles2:
    obstacle2.hideturtle()
    obstacle2.speed(0)
    obstacle2.color("green")
    obstacle2.penup()
    obstacle2.shape("square")
    xobs = random.choice(numberslistx)
    yobs = random.choice(numberslisty)
    obstacle2.turtlesize(12,3)
    obstacle2.setposition(xobs,-yobs)
    obstacle2.showturtle()
    if(obstacle.xcor()-obstacle2.xcor())> 10:
        obstacle.setposition(xobs,yobs)
        obstacle2.setposition(xobs,-yobs)


#border
def fall():
    if (player.ycor()< -300):
        return True
def ceiling():
    if (player.ycor() > 300):
        return True
colors = ["red", "green","yellow","blue","purple","pink"]
points = 1
while True:
    player.sety(player.ycor()-gravity)
    xresetpos = random.choice(range(230,300))
    yresetpos = random.choice(range(140,190))

    for obstacle in obstacles:
        obstacle.setx(obstacle.xcor()-obsspd)
        if (obstacle.xcor()-obsspd) < -270:
            obstacle.hideturtle()
            obstacle.setx(xresetpos)
            obstacle.sety(yresetpos)
            obstacle.showturtle()
            obsspd+=1
            points += 1
            display = points
            scoreboard.clear()
            scoreboard.write(display)
            player.color(random.choice(colors))
            obstacle.color(random.choice(colors))


    for obstacle2 in obstacles2:
        obstacle2.setx(obstacle2.xcor()-(obsspd))
        if (obstacle2.xcor()-obsspd) < -270:
            obstacle2.hideturtle()                   
            obstacle2.setx(xresetpos)
            obstacle2.sety(-(int(yresetpos))-15)
            obstacle2.showturtle()
            player.color(random.choice(colors))
            obstacle2.color(random.choice(colors))
        if hit(player, obstacle):
            player.hideturtle()
            player.setpos(400,0)
            gameover.color("red")
            gameover.setpos(-150,-20)
            gameover.write("Game over",False,"left",("Arial",50,))
            gameover.setpos(-160,-200)
            gameover.write("Press x to play again",False,"left",("Arial",30,))
            break
        if hit(player, obstacle2):
            player.hideturtle()
            player.setpos(400,0)
            gameover.setpos(-150,-20)
            gameover.write("Game over",False,"left",("Arial",50,))
            gameover.setpos(-160,-200)
            gameover.write("Press x to play again",False,"left",("Arial",30,))
            break

    if fall():
        player.hideturtle()
        player.setpos(400,0)
        gameover.setpos(-150,-20)
        gameover.write("Game over",False,"left",("Arial",50,))
        gameover.setpos(-160,-200)
        gameover.write("Press x to play again",False,"left",("Arial",30,))
        break
    if ceiling():
        player.setycor(280)
    #if score(player,obstacle1):
     #   points += 1
     #   display = points
     #   scoreboard.clear()
      #  scoreboard.write(display)
    turtle.onkeypress(playerup, "space")
    #turtle.onkeypress(playerdown, "Down")
    #if player.xcor() is obstacle1.xcor():
     #   points += 1
     #   scoreboard.clear()
      #  scoreboard.write(points)

#balken stoppen niet als jij beweegt

Solution

  • One problem is that your horizontal motion is controlled, out of sync, by a while True: loop but your vertical motion is controlled, in sync, by a keyboard event. We need to get both motions in sync using events via replacing your while True: with an ontimer() event. Here's my complete rework of your code along these lines with a few simplifications for example purposes:

    from turtle import Screen, Turtle
    from random import choice, randrange
    
    COLORS = ["red", "green", "yellow", "blue", "purple", "pink"]
    
    PLAYER_SPEED = 50
    
    GRAVITY = 3
    
    NUMBER_OBSTACLES_UPPER = 2
    NUMBER_OBSTACLES_LOWER = 2
    
    # movement
    def playerup():
        screen.onkeypress(None, 'space')  # disable handler inside handler
    
        player.sety(player.ycor() + PLAYER_SPEED)
    
        if player.ycor() > 287:
            player.speed('fastest')
            player.sety(287)
            player.speed('slowest')
    
        screen.onkeypress(playerup, 'space')
    
    # collision
    def hit(t1, t2):
        xdistance = abs(t1.xcor() - t2.xcor())
    
        if xdistance >= 20:
            return False
    
        ydistance = abs(t1.ycor() - t2.ycor())
    
        return ydistance < 130
    
    # border
    def fall():
        return player.ycor() < -300
    
    def ceiling():
        return player.ycor() > 300
    
    # main program loop
    def move():
        global points, obstacle_speed_upper, obstacle_speed_lower
    
        player.sety(player.ycor() - GRAVITY)
    
        for obstacle in obstacles_upper:
            obstacle.setx(obstacle.xcor() - obstacle_speed_upper)
    
            if obstacle.xcor() < -270:
                obstacle.hideturtle()
                obstacle.setposition(randrange(230, 300), randrange(140, 190))
                obstacle.showturtle()
                obstacle_speed_upper += 1
    
                points += 1
                scoreboard.clear()
                scoreboard.write(points, font=('Arial', 30,))
    
            if hit(player, obstacle):
                player.hideturtle()
                gameover.write("Game Over", align='center', font=('Arial', 50,))
                return
    
        for obstacle in obstacles_lower:
            obstacle.setx(obstacle.xcor() - obstacle_speed_lower)
    
            if obstacle.xcor() < -270:
                obstacle.hideturtle()
                obstacle.setposition(randrange(230, 300), - randrange(160, 190))
                obstacle.showturtle()
                obstacle_speed_lower += 1
    
                points += 1
                scoreboard.clear()
                scoreboard.write(points, font=('Arial', 30,))
    
            if hit(player, obstacle):
                player.hideturtle()
                gameover.write("Game Over", align='center', font=('Arial', 50,))
                return
    
        if ceiling() or fall():
            player.hideturtle()
            gameover.write("Game Over", align='center', font=('Arial', 50,))
            return
    
        screen.ontimer(move, 100)
    
    # starting conditions
    screen = Screen()
    screen.setup(750, 750)
    screen.bgcolor('black')
    screen.title("Game Screen")
    
    # borders
    box = Turtle()
    box.hideturtle()
    box.color('blue')
    box.speed('fastest')
    box.pensize(3)
    
    box.penup()
    box.setpos(-300, -300)
    box.pendown()
    
    for _ in range(4):
        box.forward(600)
        box.left(90)
    
    gameover = Turtle()
    gameover.hideturtle()
    gameover.color('red')
    gameover.penup()
    gameover.sety(-25)
    
    points = 0
    
    scoreboard = Turtle()
    scoreboard.hideturtle()
    scoreboard.color('blue')
    scoreboard.penup()
    scoreboard.setpos(-300, 320)
    scoreboard.write(points, font=('Arial', 30,))
    
    player = Turtle()
    player.hideturtle()
    player.shape('turtle')
    player.speed('slowest')
    player.color('yellow')
    player.setheading(90)
    player.penup()
    player.setx(-200)
    player.showturtle()
    
    # obstacle list
    obstacle_speed_upper = 3
    obstacles_upper = []
    
    for _ in range(NUMBER_OBSTACLES_UPPER):
        obstacle = Turtle()
        obstacle.hideturtle()
        obstacle.shape('square')
        obstacle.turtlesize(12, 3)
        obstacle.speed('fastest')
        obstacle.color(choice(COLORS))
    
        obstacle.penup()
        xobs = randrange(-100, 280)
        yobs = randrange(145, 190)
        obstacle.setposition(xobs, yobs)
    
        obstacle.showturtle()
    
        obstacles_upper.append(obstacle)
    
    # lower obstacles list
    obstacle_speed_lower = 3
    obstacles_lower = []
    
    for _ in range(NUMBER_OBSTACLES_LOWER):
        obstacle = Turtle()
        obstacle.hideturtle()
        obstacle.shape('square')
        obstacle.turtlesize(12, 3)
        obstacle.speed('fastest')
        obstacle.color(choice(COLORS))
    
        obstacle.penup()
        xobs = randrange(-100, 280)
        yobs = randrange(160, 190)
        obstacle.setposition(xobs, -yobs)
    
        obstacle.showturtle()
    
        obstacles_lower.append(obstacle)
    
    screen.onkeypress(playerup, 'space')
    screen.listen()
    
    move()
    
    screen.mainloop()