首页 > 解决方案 > 让游戏中的蛇一点一点移动而不是整体移动

问题描述

我的游戏是一个蛇游戏,你必须得到水果。这是代码:

#Importing random and turtle module 
import random
import turtle as t #Shortening the turtle module to t

#Adding a orange background
t.bgcolor("orange")

#Creating a turtle to become the snake
snake = t.Turtle() # Creates a new turtle for the snake
snake.shape("square") # Making the snake square shaped
snake.color("green") # Making the snake green
snake.speed(0) # Making the snake not move before the game starts
snake.penup() # Disables the turtles pen allowing the turtle to move around the screen without drawing a line along the way
snake.hideturtle() #This command hides the turtle

#Creating a turtle to draw the leaves
fruit = t.Turtle() # Creates a new turtle for the fruit
fruit.shape("circle") # Making the fruit circular
fruit.color("red") # Making the fruit red
fruit.penup() # Disables the turtles pen allowing the turtle to move around the screen without drawing a line along the way
fruit.hideturtle() #This command hides the turtle
fruit.speed(0) # Making the fruit not move

#Adding more turtles to display the text for the game and the score
gamestarted = False #To know if the game has started
writeturtle = t.Turtle()# Creates a new turtle for the text
writeturtle.write("Press SPACE to play!", align="center", font=("Calibri", 16, "bold")) #This line draws text on the screen
writeturtle.hideturtle() # Hides the turtle but not the text
#Adding a score turtle
scoreturtledude = t.Turtle()# Creates a new turtle for the score
scoreturtledude.hideturtle()#This command hides the turtle
scoreturtledude.speed(0)#Make sure the turtle stays where it is so it can update the score

def outsidewindow(): #Defining the outside window function
    leftwall = -t.window_width() / 2 #Calculates the left wall
    rightwall = t.window_width() / 2 #Calculates the right wall
    topwall = t.window_height() / 2 #Calculates the top wall
    bottomwall = -t.window_height() / 2 #Calculates the bottom wall
    (x, y) = snake.pos() #Then it asks the snake for its current position
    outside = x< leftwall or x> rightwall or y< bottomwall or y> topwall #Comparing the snakes coordinates with the wall position
    return outside #If any of the four conditions above is true then outside is true
def gameover(): #Defining gameover
    snake.color("orange")#CHANGES THE COLOR OF THE SNAKE TO ORANGE(the same color as the background) so it can't be seen
    fruit.color("orange")#CHANGES THE COLOR OF THE SNAKE TO ORANGE(the same color as the background) so it can't be seen
    t.penup() # this disables the turtles pen
    t.hideturtle() #This hides the turtle
    t.write("YOUR SNAKE CRAWLED INTO THE GARDEN. GAME OVER!", align="center", font=("Calibri", 20, "normal"))#This line writes a text for when the game is over
def showscore(currentscore):
    scoreturtledude.clear()# This clears the score
    scoreturtledude.penup()# Disables turtle pen
    x = (t.window_width() / 2) -75 # 75 pixels from the right
    y = (t.window_height() / 2) -75 # And 75 pixels from the top
    scoreturtledude.setpos(x, y)#Sets the turtles position
    scoreturtledude.write(str(currentscore) , align="right", font=("Calibri", 40, "bold"))# WRITES THE SCOre in calibri font
def placefruit():
    fruit.hideturtle()
    fruit.setposition(random.randint(-200, 200), random.randint(-200, 200))
    fruit.showturtle()
def startgame():
    global gamestarted
    if gamestarted: #If the game has already started, the return command makes the function quit so it doesn't run a second time
        return
    gamestarted = True

    score = 0 #Sets the score to 0
    writeturtle.clear() # Clears the text from the screen

    snakespeed = 2
    snakelength = 3
    snake.shapesize(1, snakelength, 1)#This makes the snake turtle stretch from a square shape into a snake shape
    snake.showturtle() #This shows the snake
    showscore(score) #This uses the showscore function we defined earlier
    placefruit()
    while True: #This puts it in a forever loop
        snake.forward(snakespeed)
        if snake.distance(fruit) < 20:# Makes the snake eat the leaf when it is less than 20 pixels away
            placefruit() #This line places another fruit on the screen
            snakelength = snakelength + 1 #This line line and the next line together will make the snake grow longer
            snake.shapesize(1, snakelength, 1)
            snakespeed = snakespeed + 1 #This increases the speed of the snake
            score = score + 100 #This increases the score
            showscore(score) #This shows the score
        if outsidewindow():
               gameover()
               break
def up():
    if snake.heading() == 0 or snake.heading() == 180: #checks if the snake is heading left or right
        snake.setheading(90)#Heads the snake straight up
def down():
    if snake.heading() == 0 or snake.heading() == 180:#checks if the snake is heading left or right
        snake.setheading(270)#Heads the snake straight down
def left():
    if snake.heading() == 90 or snake.heading() == 270:#checks if the snake is heading  up or down
        snake.setheading(180)#Heads the snake straight right
def right():
    if snake.heading() == 90 or snake.heading() == 270:#checks if the snake is heading up or down
        snake.setheading(0)#Heads the snake straight left


t.onkey(startgame, "space") # The onkey() function binds yhe space bar to the startgame () so the game will not start until the player presses space
t.onkey(up, "Up") #The onkey() function binds the up key to the startgame 
t.onkey(down, "Down")#The onkey() function binds the down key to the startgame 
t.onkey(right, "Right")#The onkey() function binds the right key to the startgame 
t.onkey(left, "Left")#The onkey() function binds the left key to the startgame 
t.listen() # The listen function allows the program to recieve signals from the key board
t.mainloop()

这段代码制作了一个蛇完全转动的游戏,但我希望蛇一点一点地转动。你可以帮帮我吗?

标签: pythonturtle-graphics

解决方案


下面我将您的游戏与我之前编写的如何在屏幕上移动分段蛇的简短示例合并- 我很惊讶您对 SO 的搜索没有出现这种情况。

我还进行了一些其他更改以适应这一动议。您的蛇从乌龟变成乌龟列表,列表中的最后一个乌龟是蛇的头部。键盘箭头处理程序不再直接改变蛇的方向,它们只是为下一次海龟移动时设置一个新的方向变量——这可以防止调整海龟时发生冲突。

while True:在像turtle这样的事件驱动的世界中没有位置,所以它被一个ontimer()事件取代——否则你可能会锁定事件:

from random import randint
from turtle import Turtle, Screen  # force object-oriented turtle

SCORE_FONT = ("Calibri", 40, "bold")
MESSAGE_FONT = ("Calibri", 24, "bold")

SEGMENT_SIZE = 20

def outsidewindow():
    (x, y) = snake[-1].pos()  # Ask the snake head for its current position
    return not (leftwall < x < rightwall and bottomwall < y < topwall)

def gameover():
    for segment in snake:
        segment.hideturtle()
    fruit.hideturtle()
    writeturtle.write("Your snake crawled into the garden! Game over!", align="center", font=MESSAGE_FONT)

def showscore(currentscore):
    scoreturtledude.undo() # Clear the previous score
    scoreturtledude.write(currentscore, align="right", font=SCORE_FONT)

def placefruit():
    fruit.hideturtle()
    fruit.setposition(randint(-200, 200), randint(-200, 200))
    fruit.showturtle()

def startgame():
    screen.onkey(None, "space")  # So this doesn't run a second time

    writeturtle.clear() # Clear the text from the screen

    showscore(score)

    for segment in snake: # Show the snake
        segment.showturtle()

    placefruit()

    rungame()

def rungame():
    global score, snakelength

    segment = snake[-1].clone() if len(snake) < snakelength else snake.pop(0)

    screen.tracer(False)  # segment.hideturtle()
    segment.setposition(snake[-1].position())
    segment.setheading(snake[-1].heading())
    segment.setheading(direction)
    segment.forward(SEGMENT_SIZE)

    if outsidewindow():
        gameover()
        return

    screen.tracer(True)  # segment.showturtle()
    snake.append(segment)

    if snake[-1].distance(fruit) < SEGMENT_SIZE:  # Make the snake eat the fruit when it is nearby
        placefruit()  # Place another fruit on the screen
        snakelength += 1
        score += 100
        showscore(score)

    screen.ontimer(rungame, max(50, 150 - 10 * len(snake)))  # Speed up slightly as snake grows

def up():
    global direction

    current = snake[-1].heading()

    if current == 0 or current == 180:  # Check if the snake is heading left or right
        direction = 90  # Head the snake up

def down():
    global direction

    current = snake[-1].heading()

    if current == 0 or current == 180:  # Check if the snake is heading left or right
        direction = 270  # Head the snake down

def left():
    global direction

    current = snake[-1].heading()

    if current == 90 or current == 270:  # Check if the snake is heading up or down
        direction = 180  # Head the snake left

def right():
    global direction

    current = snake[-1].heading()

    if current == 90 or current == 270:  # Check if the snake is heading up or down
        direction = 0  # Head the snake right

screen = Screen()
screen.bgcolor("orange")

leftwall = -screen.window_width() / 2  # Calculate the left wall
rightwall = screen.window_width() / 2  # Calculate the right wall
topwall = screen.window_height() / 2  # Calculate the top wall
bottomwall = -screen.window_height() / 2  # Calculate the bottom wall

# Creating a turtle to become the snake
head = Turtle("square", visible=False) # Create a new turtle for the snake
head.color("green") # Make the snake green
head.penup() # Disable the turtle's pen, allowing the turtle to move around the screen without leaving a trail

snake = [head]
snakelength = 3
score = 0
direction = 0

# Creating a turtle to draw the leaves
fruit = Turtle("circle", visible=False) # Create a turtle for the fruit
fruit.penup() # Raise the turtle's pen, allowing turtle to move around screen without leaving a trail
fruit.color("red")

# Add more turtles to display the text for the game and the score
writeturtle = Turtle(visible=False)  # Create a new turtle for the text
writeturtle.write("Press SPACE to play!", align="center", font=MESSAGE_FONT)

# Add a score turtle
scoreturtledude = Turtle(visible=False)  # Create a new turtle for the score
scoreturtledude.penup()  # Disable turtle pen
x = screen.window_width() / 2 - 75  # 75 pixels from the right
y = screen.window_height() / 2 - 75  # And 75 pixels from the top
scoreturtledude.setpos(x, y) # Set the turtle's position
scoreturtledude.write('', align="right", font=SCORE_FONT)

screen.onkey(startgame, "space")  # Bind space bar to startgame() so game will start when player presses space
screen.onkey(up, "Up")  # Bind the up key to up()
screen.onkey(down, "Down")  # Bind the down key to down()
screen.onkey(right, "Right")  # Bind the right key to right()
screen.onkey(left, "Left")  # Bind the left key to left()
screen.listen()  # Allow the window to receive signals from the keyboard

screen.mainloop()

在此处输入图像描述

您的代码中有许多问题,例如小乌龟gameover()指的是什么时候t.hideturtle()?但主要有两个:

  • 重读什么speed(0)- 你误解了它。

  • 你需要学习写出更好的评论。这很愚蠢:

    fruit.color("red") # 让水果变成红色

    这很不错:

    t.listen() #listen函数允许程序接收来自键盘的信号


推荐阅读