海龟图形乒乓球游戏每次重新启动后屏幕中央出现小黑色方块

问题描述 投票:0回答:2

我尝试在Python上的turtle扩展上制作一个乒乓球游戏,一切都很顺利。

我想在玩家达到一定分数时重新开始游戏。 游戏正常重新启动,窗口会自行清除,除了中心的黑色方块在接下来的游戏中仍然存在。 我怎样才能摆脱那个方块?

这是我重新启动游戏的代码:

import turtle

def run_game():
    wn = turtle.Screen()
    wn.title("Ping Pong Pour le Nuls")
    wn.bgcolor("green")
    wn.setup(width=800, height=600)
    wn.tracer(0)

    Player_1 = wn.textinput("Player 1", "Name of the player: ")
    Player_2 = wn.textinput("Player 2", "Name of the player: ")

    # Score
    score_a = 0
    score_b = 0
    # Paddle A
    paddle_a = turtle.Turtle()
    paddle_a.speed(0)
    paddle_a.shape("square")
    paddle_a.color("white")
    paddle_a.shapesize(stretch_wid=5, stretch_len=1)
    paddle_a.penup()
    paddle_a.goto(-350, 0)

    # Paddle B
    paddle_b = turtle.Turtle()
    paddle_b.speed(0)
    paddle_b.shape("square")
    paddle_b.color("white")
    paddle_b.shapesize(stretch_wid=5, stretch_len=1)
    paddle_b.penup()
    paddle_b.goto(350, 0)

    # Ball
    ball = turtle.Turtle()
    ball.speed(0)
    ball.shape("square")
    ball.color("white")
    ball.penup()
    ball.goto(0, 0)
    ball.dx = 0.4
    ball.dy = -0.4

    # Pen
    pen = turtle.Turtle()
    pen.speed(0)
    pen.color("white")
    pen.penup()
    pen.hideturtle()
    pen.goto(0, 260)
    pen.write(str(Player_1) + " : 0    " + str(Player_2) + " : 0    ", align="center", font=("Courier", 14, "normal"))


    # Funtion

    def paddle_a_up():
        y = paddle_a.ycor()
        y += 20
        paddle_a.sety(y)

    def paddle_a_down():
        y = paddle_a.ycor()
        y += -20
        paddle_a.sety(y)

    def paddle_b_up():
        y = paddle_b.ycor()
        y += 20
        paddle_b.sety(y)

    def paddle_b_down():
        y = paddle_b.ycor()
        y += -20
        paddle_b.sety(y)


    def pen_2():
        pen_2 = turtle.Turtle()
        pen_2.speed(0)
        pen_2.color("white")
        pen_2.penup()
        pen_2.hideturtle()
        pen_2.goto(0, 0)
        pen_2.write("Player 2 Wins", align="center", font=("Courier", 24, "normal"))

    # Keyboard binding

    wn.listen()
    wn.onkeypress(paddle_a_up, "w")
    wn.onkeypress(paddle_a_down, "x")
    wn.onkeypress(paddle_b_up, "Up")
    wn.onkeypress(paddle_b_down, "Down")

    # Main Game Loop
    while True:
        wn.update()

        # Move the ball
        ball.setx(ball.xcor() + ball.dx)
        ball.sety(ball.ycor() + ball.dy)


        # Border checking
        if ball.ycor() > 290:
            ball.sety(290)
            ball.dy *= -1

        if ball.ycor() < -290:
            ball.sety(-290)
            ball.dy *= -1

        if ball.xcor() > 390:
            ball.goto(0, 0)
            ball.dx *= -1
            score_a += 1
            pen.clear()
            pen.write(str(Player_1) + " : {}    ".format(score_a) + str(Player_2) + " : {}    ".format(score_b),
                      align="center", font=("Courier", 14, "normal"))


        if ball.xcor() < -390:
            ball.goto(0, 0)
            ball.dx *= -1
            score_b += 1
            pen.clear()
            pen.write(str(Player_1) + " : {}    ".format(score_a) + str(Player_2) + " : {}    ".format(score_b),
                      align="center", font=("Courier", 14, "normal"))



        # Paddle and ball collisions

        if (ball.xcor() > 340 and ball.xcor() < 350) and (ball.ycor() < paddle_b.ycor() + 40 and ball.ycor() > paddle_b.ycor() -40):
            ball.setx(340)
            ball.dx *= -1
        if (ball.xcor() < -340 and ball.xcor() > -350) and (ball.ycor() < paddle_a.ycor() + 40 and ball.ycor() > paddle_a.ycor() -40):
            ball.setx(-340)
            ball.dx *= -1

        # Paddles can't go beyond screen
        if paddle_a.ycor() >= 260:
            paddle_a_down()
        if paddle_a.ycor() <= -260:
            paddle_a_up()
        if paddle_b.ycor() >= 260:
            paddle_b_down()
        if paddle_b.ycor() <= -260:
            paddle_b_up()

        if score_a >= 3:
            restart = wn.textinput("Game result", "Well done " + Player_1 + ", you won ! \nDo you want to restart ? (y/n)")
            if restart == "y":
                wn.reset()
                run_game()
            else:
                break
        if score_b >= 3:
            restart = wn.textinput("Game result", "Well done " + Player_2 + ", you won ! \nDo you want to restart ? (y/n)")
            if restart == "y":
                wn.reset()
                run_game()
            else:
                break


run_game()

非常感谢您的帮助,祝您有美好的一天。 Game Output

python turtle-graphics restart python-turtle pong
2个回答
0
投票

这里。我没有使用

wn.reset()
,而是使用
wn.clearscreen()
。它成功了!!

代码:

import turtle

def run_game():

    wn = turtle.Screen()
    wn.title("Ping Pong Pour le Nuls")
    wn.bgcolor("green")
    wn.setup(width=800, height=600)
    wn.tracer(0)

    Player_1 = wn.textinput("Player 1", "Name of the player: ")
    Player_2 = wn.textinput("Player 2", "Name of the player: ")

    # Score
    score_a = 0
    score_b = 0
    # Paddle A
    paddle_a = turtle.Turtle()
    paddle_a.speed(0)
    paddle_a.shape("square")
    paddle_a.color("white")
    paddle_a.shapesize(stretch_wid=5, stretch_len=1)
    paddle_a.penup()
    paddle_a.goto(-350, 0)

    # Paddle B
    paddle_b = turtle.Turtle()
    paddle_b.speed(0)
    paddle_b.shape("square")
    paddle_b.color("white")
    paddle_b.shapesize(stretch_wid=5, stretch_len=1)
    paddle_b.penup()
    paddle_b.goto(350, 0)

    # Ball
    ball = turtle.Turtle()
    ball.speed(0)
    ball.color("black")
    ball.shape("circle")
    ball.penup()
    ball.goto(0, 0)
    ball.dx = 0.4
    ball.dy = -0.4

    # Pen
    pen = turtle.Turtle()
    pen.speed(0)
    pen.color("white")
    pen.penup()
    pen.hideturtle()
    pen.goto(0, 260)
    pen.write(str(Player_1) + " : 0    " + str(Player_2) + " : 0    ", align="center", font=("Courier", 14, "normal"))


    # Funtion

    def paddle_a_up():
        y = paddle_a.ycor()
        y += 20
        paddle_a.sety(y)

    def paddle_a_down():
        y = paddle_a.ycor()
        y += -20
        paddle_a.sety(y)

    def paddle_b_up():
        y = paddle_b.ycor()
        y += 20
        paddle_b.sety(y)

    def paddle_b_down():
        y = paddle_b.ycor()
        y += -20
        paddle_b.sety(y)


    def pen_2():
        pen_2 = turtle.Turtle()
        pen_2.speed(0)
        pen_2.color("white")
        pen_2.penup()
        pen_2.hideturtle()
        pen_2.goto(0, 0)
        pen_2.write("Player 2 Wins", align="center", font=("Courier", 24, "normal"))

    # Keyboard binding

    wn.listen()
    wn.onkeypress(paddle_a_up, "w")
    wn.onkeypress(paddle_a_down, "x")
    wn.onkeypress(paddle_b_up, "Up")
    wn.onkeypress(paddle_b_down, "Down")

    # Main Game Loop
    while True:
        wn.update()

        # Move the ball
        ball.setx(ball.xcor() + ball.dx)
        ball.sety(ball.ycor() + ball.dy)


        # Border checking
        if ball.ycor() > 290:
            ball.sety(290)
            ball.dy *= -1

        if ball.ycor() < -290:
            ball.sety(-290)
            ball.dy *= -1

        if ball.xcor() > 390:
            ball.goto(0, 0)
            ball.dx *= -1
            score_a += 1
            pen.clear()
            pen.write(str(Player_1) + " : {}    ".format(score_a) + str(Player_2) + " : {}    ".format(score_b),
                      align="center", font=("Courier", 14, "normal"))


        if ball.xcor() < -390:
            ball.goto(0, 0)
            ball.dx *= -1
            score_b += 1
            pen.clear()
            pen.write(str(Player_1) + " : {}    ".format(score_a) + str(Player_2) + " : {}    ".format(score_b),
                      align="center", font=("Courier", 14, "normal"))



        # Paddle and ball collisions

        if (ball.xcor() > 340 and ball.xcor() < 350) and (ball.ycor() < paddle_b.ycor() + 40 and ball.ycor() > paddle_b.ycor() -40):
            ball.setx(340)
            ball.dx *= -1
        if (ball.xcor() < -340 and ball.xcor() > -350) and (ball.ycor() < paddle_a.ycor() + 40 and ball.ycor() > paddle_a.ycor() -40):
            ball.setx(-340)
            ball.dx *= -1

        # Paddles can't go beyond screen
        if paddle_a.ycor() >= 260:
            paddle_a_down()
        if paddle_a.ycor() <= -260:
            paddle_a_up()
        if paddle_b.ycor() >= 260:
            paddle_b_down()
        if paddle_b.ycor() <= -260:
            paddle_b_up()

        if score_a >= 3:
            restart = wn.textinput("Game result", "Well done " + Player_1 + ", you won ! \nDo you want to restart ? (y/n)")
            if restart == "y":
                wn.clearscreen()
                run_game()
            else:
                break
        if score_b >= 3:
            restart = wn.textinput("Game result", "Well done " + Player_2 + ", you won ! \nDo you want to restart ? (y/n)")
            if restart == "y":
                wn.clearscreen()
                run_game()
            else:
                break


run_game()

希望这有帮助!


0
投票

现有答案解决了wn.clearscreen()

的主要问题,但没有解释原因。问题归结为这个最小的例子:

from random import randint import turtle def run_game(): wn = turtle.Screen() wn.setup(width=800, height=600) # Paddle A paddle_a = turtle.Turtle() paddle_a.shape("square") paddle_a.color("red") paddle_a.penup() paddle_a.goto(randint(-200, 200), randint(-200, 200)) paddle_a.reset() print(f"there are {len(turtle.turtles())} turtles on the screen") run_game() run_game()
如果你运行这个程序,你会发现每次通过“游戏”都会创建越来越多的海龟:

there are 1 turtles on the screen there are 2 turtles on the screen there are 3 turtles on the screen there are 4 turtles on the screen there are 5 turtles on the screen ...
对海龟调用 

reset()

 会将其移回中心并去除颜色等属性,但海龟仍然存在。

wn.clearscreen()

 实际上会从屏幕上删除所有海龟,而不仅仅是将它们重置到中间:

def run_game(): wn = turtle.Screen() wn.clearscreen() # <-- added wn.setup(width=800, height=600) ...
现在输出正确了:

there are 1 turtles on the screen there are 1 turtles on the screen there are 1 turtles on the screen there are 1 turtles on the screen there are 1 turtles on the screen ...
另一种方法是在游戏重新启动循环之外声明你的海龟,每场游戏初始化一次:

from random import randint import turtle def run_game(): wn = turtle.Screen() wn.setup(width=800, height=600) paddle_a.penup() paddle_a.goto(randint(-200, 200), randint(-200, 200)) paddle_a.reset() print(f"there are {len(turtle.turtles())} turtles on the screen") run_game() # Paddle A paddle_a = turtle.Turtle() paddle_a.shape("square") paddle_a.color("red") run_game()
即使在 

clearscreen()

 修复之后,如果你运行上面的代码足够长的时间,你会看到:

RecursionError: maximum recursion depth exceeded in __instancecheck__
不要使用递归来做某事,除非你能保证它会很好地低于 CPython 调用堆栈 1000 的限制。由于这个程序需要用户输入,如果有人真的对游戏充满热情,理论上他们可以达到 1000 次重玩,导致游戏崩溃。

而是使用迭代或

ontimer

:

from random import randint import turtle def run_game(): wn = turtle.Screen() wn.setup(width=800, height=600) paddle_a.penup() paddle_a.goto(randint(-200, 200), randint(-200, 200)) paddle_a.reset() print(f"there are {len(turtle.turtles())} turtles on the screen") # run_game() # remove this--no recursion # Paddle A paddle_a = turtle.Turtle() paddle_a.shape("square") paddle_a.color("red") while True: run_game()


另一个问题是你的游戏在我的机器上以闪电般的速度运行,导致无法玩。原因是

while True: wn.update()

,它使 CPU 尽可能快地运行,而没有建立一致的帧速率。相反,请使用 
ontimer
 来运行事件循环。


请参阅有关“幽灵海龟”的相关问题,这是Python海龟中的常见问题:

  • 为什么屏幕中间有一个小箭头?
  • 为什么会有第二只乌龟?
  • 海龟的第三个克隆
© www.soinside.com 2019 - 2024. All rights reserved.