我正在 Python3 和 Pygame 的帮助下创建自己的贪吃蛇游戏克隆。在编码过程中,我遇到了一个奇怪的问题。
蛇按照预期移动和生长,但有时会随机减少到其初始长度(两个单位)。我一点也不知道发生了什么事。 我的代码在这里:
#main.py
import sys
import random
import pygame
from apple import Apple
from settings import Settings
from snake import Snake
settings = Settings()
snake = Snake(settings)
apple = Apple(settings)
pygame.init()
screen = pygame.display.set_mode((settings.SW, settings.SH))
pygame.display.set_caption(settings.title)
clock = pygame.time.Clock()
def draw_grid():
"""Draw a gird on the screen."""
for x in range(0, settings.SW, settings.BLOCK_SIZE):
for y in range(0, settings.SH, settings.BLOCK_SIZE):
rect = pygame.Rect(x, y, settings.BLOCK_SIZE,
settings.BLOCK_SIZE)
pygame.draw.rect(screen, (255, 255, 255), rect, 1)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
snake.change_direction(event)
snake.update()
screen.fill(settings.BLACK)
draw_grid()
apple.draw_apple(screen)
snake.draw_snake(screen)
pygame.display.update()
snake.eat(apple)
clock.tick(10)
#snake.py
import pygame
class Snake:
"""A simple moveable snake"""
def __init__(self, settings):
self.settings = settings
self.x = self.settings.BLOCK_SIZE
self.y =self.settings.BLOCK_SIZE
self.xdir = 1
self.ydir = 0
self.head = pygame.Rect(self.x, self.y,
self.settings.BLOCK_SIZE, self.settings.BLOCK_SIZE)
self.body = [pygame.Rect(self.x-self.settings.BLOCK_SIZE,
self.y, self.settings.BLOCK_SIZE, self.settings.BLOCK_SIZE)]
self.collided = False
self.excess_border = False
def draw_snake(self, screen):
"""Draw a snake on the screen."""
pygame.draw.rect(screen, (30, 180,15), self.head)
for square in self.body:
pygame.draw.rect(screen, (30, 180, 15), square)
def update(self):
"""Make a snake move"""
self.body.append(self.head)
for i in range(len(self.body)-1):
self.body[i].x = self.body[i+1].x
self.body[i].y = self.body[i+1].y
self.head.x += self.xdir * self.settings.BLOCK_SIZE
self.head.y += self.ydir * self.settings.BLOCK_SIZE
self.body.remove(self.head)
def change_direction(self, event):
"""React to an user's input."""
if event.key == pygame.K_DOWN:
self.xdir = 0
self.ydir = 1
if event.key == pygame.K_UP:
self.xdir = 0
self.ydir = -1
if event.key == pygame.K_LEFT:
self.xdir = -1
self.ydir = 0
if event.key == pygame.K_RIGHT:
self.xdir = 1
self.ydir = 0
def grow(self):
"""Make the snake grow."""
self.body.append(pygame.Rect(self.head.x, self.head.y,
self.settings.BLOCK_SIZE, self.settings.BLOCK_SIZE))
def eat(self, apple):
""""Make a snake eat."""
if (self.head.x == apple.x) and (self.head.y == apple.y):
self.grow()
apple.create_apple()
#settings.py
class Settings:
"""A class storing the game's essential settings."""
def __init__(self):
self.title = 'Snake!'
self.SW = 800
self.SH = 800
self.BLACK = (0, 0, 0)
self.RED = (170, 20, 30)
self.BLOCK_SIZE = 50
#apple.py
import random
import pygame
class Apple:
"""A class to represent an apple."""
def __init__(self, settings):
self.settings = settings
self.create_apple()
def create_apple(self):
"""Create a new apple."""
self.x = (int(random.randint(0, self.settings.SW)/
self.settings.BLOCK_SIZE)
* self.settings.BLOCK_SIZE)
self.y = (int(random.randint(0, self.settings.SW)
/ self.settings.BLOCK_SIZE)
* self.settings.BLOCK_SIZE)
self.apple = pygame.Rect(self.x, self.y,
self.settings.BLOCK_SIZE,
self.settings.BLOCK_SIZE)
def draw_apple(self, screen):
""""Draw an apple on the screen."""
pygame.draw.rect(screen, self.settings.RED, self.apple)
预先感谢您的帮助
当蛇的头部与身体碰撞时,就会出现该错误。
这个问题的根源在于使用了
self.body.remove(self.head)
中的Snake.update()
语句。pygame.Rect
对象之间的相等性;如果它们具有相同的位置和大小,则它们被视为相等。remove
函数的行为是从列表中消除匹配值的第一个实例,这加剧了问题。您可以使用
self.body.pop()
删除 self.body
中的最后一个元素,即 self.head
。