使 python 基于海龟的游戏在点击时重置

Making python turtle based game reset on click

我试图让我的游戏在用户点击屏幕后重新启动。我试过将整个事情包装在一个 while 循环中,但这给了我关于未定义变量的错误。

我也试过将代码包装在一个函数中,但这也给我带来了变量错误。

这是代码。

import turtle
import math
import random
import pygame

pygame.init()
pygame.mixer.init()

# MUSIC AND SOUND SETUP
pygame.mixer.music.load("Sounds/music.mp3")
pygame.mixer.music.play(loops=-1)

我使用 pygame 只是为了将音乐添加到我的游戏中。

bubblefiredsound = pygame.mixer.Sound("Sounds/bubblefired.mp3")
enemyhitsound = pygame.mixer.Sound("Sounds/enemyhit.mp3")

# SCREEN SETUP
screen = turtle.Screen()
screen.bgcolor("black")
screen.title("Space Invaders")
screen.bgpic("TurtleInvadersBackground.png")

# CUSTOM SHAPES
turtle.register_shape("Enemy.gif")
turtle.register_shape("Turtle.gif")
turtle.register_shape("Bubble.gif")

# BORDERS
border_pen = turtle.Turtle()
border_pen.speed(0)
border_pen.color("white")
border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()
border_pen.pensize(3)
for side in range(4):
    border_pen.fd(600)
    border_pen.lt(90)
border_pen.hideturtle()

# SCORE
score = 0

score_pen = turtle.Turtle()
score_pen.speed(0)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 270)
scorestring = "Score: %s" % score
score_pen.write(scorestring, False, align="left", font=("Bubble3D", 20, "normal"))
score_pen.hideturtle()

# MAIN TURTLE
MajorTom = turtle.Turtle()
MajorTom.color("blue")
MajorTom.shape("Turtle.gif")
MajorTom.penup()
MajorTom.speed(0)
MajorTom.setposition(0, -250)
MajorTom.setheading(90)

playerspeed = 0

# NUMBER OF ENEMIES
number_of_enemies = 5
# PLACEHOLDER FOR ENEMIES
enemies = []

# ADD ENEMIES TO THE PLACEHOLDER
for i in range(number_of_enemies):
    # CREATE ENEMIES
    enemies.append(turtle.Turtle())

for enemy in enemies:
    enemy.color("red")
    enemy.shape("Enemy.gif")
    enemy.penup()
    enemy.speed(0)
    x = random.randint(-200, 200)
    y = random.randint(100, 250)
    enemy.setposition(x, y)

enemyspeed = 5

# CREATE THE PROJECTILE BUBBLE
bubble = turtle.Turtle()
bubble.color("blue")
bubble.shape("Bubble.gif")
bubble.penup()
bubble.speed(0)
bubble.setheading(90)
bubble.hideturtle()
bubble.setpos(0, -300)

bubblespeed = 20

# BUBBLE STATE, READY = READY TO FIRE, FIRE = FIRING
bubblestate = "ready"


# MOVEMENT (LEFT AND RIGHT)
def move_left():
    global playerspeed
    playerspeed = -7

def move_right():
    global playerspeed
    playerspeed = 7

def stop_player():
    global playerspeed
    playerspeed = 0

def fire_bubble():
    global bubblestate
    if bubblestate == "ready":
        bubblestate = "fire"
        # MOVE BUBBLE TO MAJOR TOM
        x = MajorTom.xcor()
        y = MajorTom.ycor() + 10
        bubble.setposition(x, y)
        bubble.showturtle()
    if bubblestate == "fire":
        bubblefiredsound.play()


def CollisionDetection(t1, t2):
    distance = math.sqrt(math.pow(t1.xcor() - t2.xcor(), 2) + math.pow(t1.ycor() - t2.ycor(), 2))
    if distance < 32:
        return True
    else:
        return False


# KEYBINDINGS
screen.listen()
screen.onkeypress(move_left, "a")
screen.onkeypress(move_right, "d")
screen.onkeyrelease(stop_player, "a")
screen.onkeyrelease(stop_player, "d")
screen.onkey(fire_bubble, "space")

这是主循环,大部分代码都放在了这里。

# GAME LOOP
while True:

    # MOVE PLAYER
    MajorTom.setx(MajorTom.xcor() + playerspeed)

    # BORDER CONTROL
    if MajorTom.xcor() > 285:
        MajorTom.setx(285)
        playerspeed = 0

    elif MajorTom.xcor() < -285:
        MajorTom.setx(-285)
        playerspeed = 0

    for enemy in enemies:
        # ENEMY MOVEMENT
        x = enemy.xcor()
        x += enemyspeed
        enemy.setx(x)

        # MOVE THE ENEMY BACK AND DOWN
        if enemy.xcor() > 280 or enemy.xcor() < -280:
            # MOVE ALL ENEMIES DOWN
            for e in enemies:
                y = e.ycor()
                y -= 40
                e.sety(y)
            # CHANGE ENEMY DIRECTION
            enemyspeed *= -1

        # BUBBLE HITS ENEMY
        if CollisionDetection(bubble, enemy):
            # PLAY BUBBLE BURST SOUND
            enemyhitsound.play()
            # RESET BUBBLE POSITION
            bubble.hideturtle()
            bubblestate = "ready"
            bubble.setposition(0, -400)
            # RESET ENEMY POSITION "SPAWN NEW ENEMY"
            x = random.randint(-200, 200)
            y = random.randint(100, 250)
            enemy.setposition(x, y)
            # ADD SCORE IF PLAYER HITS BUBBLE
            score += 10
            scorestring = "Score: %s" % score
            score_pen.clear()
            score_pen.write(scorestring, False, align="left", font=("Bubble3D", 20, "normal"))

        if CollisionDetection(MajorTom, enemy) or enemy.ycor() < -300:
            MajorTom.hideturtle()
            enemy.hideturtle()
            print("Game Over")
            GameOverPen = turtle.Turtle()
            GameOverPen.hideturtle()
            GameOverPen.penup()
            GameOverPen.goto(0,0)
            GameOverPen.speed(0)
            GameOverPen.color("pink")
            GameOverPen.write("GAME OVER!", align="center", font=("Bubble3D", 90, "normal"))
            GameOverPen.goto(0, -20)
            GameOverPen.write("\nClick to try again!", align="center", font=("Arial", 20, "normal"))
            break

    # BUBBLE MOVEMENT
    if bubblestate == "fire":
        y = bubble.ycor()

        y += bubblespeed
        bubble.sety(y)
    
    # CHECK TO SEE IF BUBBLE HAS HIT THE CEILING
    if bubble.ycor() > 275:
        bubble.hideturtle()
        bubblestate = "ready"

您正在寻找 turtle.onscreenclick 函数。
单击屏幕时使用鼠标的当前 x 和 y 坐标调用此函数。

def reset(x_pos, y_pos):
    # reset the game

turtle.onscreenclick(reset)