Pygame - 蛇随机缩小

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

我正在 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)

预先感谢您的帮助

python pygame
1个回答
0
投票

当蛇的头部与身体碰撞时,就会出现该错误。

这个问题的根源在于使用了

self.body.remove(self.head)
中的
Snake.update()
语句。
游戏逻辑中,为了方便蛇的运动处理,暂时将头部添加到身体列表中。
然而,问题的核心在于如何确定两个
pygame.Rect
对象之间的相等性;如果它们具有相同的位置和大小,则它们被视为相等。
因此,如果头部与蛇身体的任何部分占据相同的空间,则它们被认为是相同的。
remove
函数的行为是从列表中消除匹配值的第一个实例,这加剧了问题。
由于头部位于数组的末尾,因此该函数无意中删除了蛇身体的一部分而不是头部,从而导致了该错误。

您可以使用

self.body.pop()
删除
self.body
中的最后一个元素,即
self.head

© www.soinside.com 2019 - 2024. All rights reserved.