【问题标题】:When press a key to move the turtle up, my other turtles freeze当按键向上移动乌龟时,我的其他乌龟冻结
【发布时间】:2020-03-03 12:05:12
【问题描述】:

当我运行我的代码并用空格键向上移动乌龟时,所有应该移动的障碍物都停止移动。是什么导致了这个问题,我该如何解决这个问题?

我不知道是什么导致了这个问题,我试过谷歌搜索但找不到任何东西。由于这是我尝试 Python 或一般编程的第一周,我不知道我做错了什么。

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

【问题讨论】:

  • 我也只是在学习 python,所以我没有答案,但是当我在我的 pong 克隆中播放 .wav 文件时确实遇到了类似的问题。 github.com/WilcoxJ/Pong 修复是让它们异步播放,这样它们就不会在播放时暂停所有其他操作。
  • 我该怎么做呢?我试着用谷歌搜索了一下,但我并没有真正理解。
  • 似乎 turtle 可能不是用于此的理想库,但我认为您需要更改循环障碍物,以便玩家和障碍物龟移动发生在同一个块中。我发现这可能会对您有所帮助:*.com/questions/53199459/…
  • mmm 非常感谢你,我会试着从中找出答案,如果我不能继续我的下一个项目,或者可能在 pygame 中创建 flappybird。如果我现在无法弄清楚,我可能会稍后再谈。还是非常感谢。
  • np!如果你得到一个修复贴在这里,所以我也可以学习! :D

标签: python python-3.x turtle-graphics flappy-bird-clone


【解决方案1】:

一个问题是您的水平运动不同步地由while True: 循环控制,但您的垂直运动由键盘事件同步控制。我们需要通过将您的while True: 替换为ontimer() 事件来使用事件同步两个动作。以下是我对您的代码的完整修改,并出于示例目的进行了一些简化:

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()

【讨论】:

  • 哇非常感谢!因为我的学校有一些考试,所以我现在没有很多时间在手上。所以这周晚些时候再看看这个。非常感谢!
最近更新 更多