首页 > 解决方案 > 用 pygame 制作蛇。当蛇接触到饼干时,难以使蛇变长

问题描述

我正在尝试在pygame中制作蛇游戏,但是一旦蛇接触到点,我就无法使蛇变长。当我触摸点时,游戏有时会冻结,并且在极少数情况下它会给我一个记忆错误。

另外,当我成功吃掉点后,蛇就不再长了。

任何帮助,将不胜感激。谢谢!

我的代码:

import pygame
import sys
import random

pygame.init()

width = 800
height = 800
snake_pos = [width/2, height/2]
snake_list = []
color_red = (255, 0, 0)
snake_size = 20
game_over = False
screen = pygame.display.set_mode((width, height))
cookie_pos = [random.randint(0, width), random.randint(0, height)]
cookie_size = 10
color_white = (255, 255, 255)
cookie = []
direction = ''

game_over = False

def draw_snake():
    for snake in snake_list:
        pygame.draw.rect(screen, color_red, (snake[0], snake[1], snake_size, snake_size))

    if not snake_list:
        snake_list.append([snake_pos[0], snake_pos[1]])

def create_snake(direction):
    length = len(snake_list)
    for snake in snake_list:
        if direction == 'left':
            snake_list.append([snake[0] + (length * snake_size), snake[1]])
        elif direction == 'right':
            snake_list.append([snake[0] - (length * snake_size), snake[1]])
        elif direction == 'top':
            snake_list.append([snake[0], snake[1] + (length * snake_size)])
        elif direction == 'bottom':
            snake_list.append([snake[0], snake[1] - (length * snake_size)])

def create_cookie():
    cookie.append([random.randint(0, width), random.randint(0, height)])
    draw_cookie()

def draw_cookie():
    for cookie_pos in cookie:
        pygame.draw.rect(screen, color_white, (cookie_pos[0], cookie_pos[1], cookie_size, cookie_size))

def check_cookie(direction):
    for snake_pos in snake_list:
        for cookie_pos in cookie:
            p_x = snake_pos[0]
            p_y = snake_pos[1]

            e_x = cookie_pos[0]
            e_y = cookie_pos[1]

            if e_x >= p_x and e_x < (p_x + snake_size) or p_x >= e_x and p_x < (e_x + cookie_size):
                if e_y >= p_y and e_y < (p_y + snake_size) or p_y >= e_y and p_y < (e_y + cookie_size):
                    cookie.pop(0)
                    create_cookie()
                    create_snake(direction)

    if not cookie:
        cookie.append([random.randint(0, width), random.randint(0, height)])

def update_snake():
    pass

def move_snake(direction):
    keys = pygame.key.get_pressed()
    for snake_pos in snake_list:
        if keys[pygame.K_LEFT]:
            direction = 'left'
            snake_pos[0] -= 0.2
        if keys[pygame.K_RIGHT]:
            direction = 'right'
            snake_pos[0] += 0.2
        if keys[pygame.K_UP]:
            direction = 'up'
            snake_pos[1] -= 0.2
        if keys[pygame.K_DOWN]:
            direction = 'down'
            snake_pos[1] += 0.2
    screen.fill((0,0,0))
    return direction

def main_game(direction):

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        draw_snake()
        check_cookie(direction)
        draw_cookie()
        pygame.display.update()
        direction = move_snake(direction)

main_game(direction)

标签: pythonpygame

解决方案


如果要写入全局变量,则必须使用global语句
在事件循环中使用它来设置 game_over. 进一步注意,清除显示应该在主循环中完成:

def main_game(direction):
    global game_over
    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True

        # update snake and cookies
        direction = move_snake(direction)
        check_cookie(direction)

        # draw the scene
        screen.fill(0)
        draw_snake()
        draw_cookie()
        pygame.display.update()

教蛇的部分有一个大小snake_size = 20。但蛇0.2每帧移动。所以不可能在前一帧的位置上绘制蛇的第二部分,因为到前一位置的距离是0.2。这几乎是相同的位置,并且会导致几乎完全自覆盖的部件。
蛇的第二部分的正确位置是头部在 100 (=20/0.2) 帧前的位置。

跟踪列表中蛇的所有位置:

def move_snake(direction):
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        direction = 'left'
    if keys[pygame.K_RIGHT]:
        direction = 'right'
    if keys[pygame.K_UP]:
        direction = 'up'
    if keys[pygame.K_DOWN]:
        direction = 'down'

    if snake_list:
        new_pos = snake_list[0][:]
        if direction == 'left':
            new_pos[0] -= 0.2
        if direction == 'right':
            new_pos[0] += 0.2
        if direction == 'up':
            new_pos[1] -= 0.2
        if direction == 'down':
            new_pos[1] += 0.2
        if direction != '':
            snake_list.insert(0, new_pos)
    return direction

创建一个全局变量,它存储蛇snake_lenpygame.Rect部分.colliderect()数(

snake_len = 1

def check_cookie(direction):
    global snake_len, cookie

    if snake_list:
        for i, cookie_pos in enumerate(cookie):
            cookie_rect = pygame.Rect(*cookie_pos, cookie_size, cookie_size)
            snake_rect = pygame.Rect(*snake_list[0], snake_size, snake_size)
            if snake_rect.colliderect(cookie_rect):
                snake_len += 1
                del cookie[i]
                break

    if not cookie:
        cookie.append([random.randint(0, width), random.randint(0, height)])

蛇由snake_len部分组成。蛇的每一部分都有一个索引。该索引必须与存储在的位置相关联snake_list

pos_i = round(snake_size * i / 0.2)
pos = snake_list[pos_i]

在存储的适当位置绘制蛇上的零件snake_list并删除列表的尾部,不再需要:

def draw_snake():
    global snake_list

    if not snake_list:
        snake_list.append(snake_pos[:])

    for i in range(snake_len):
        pos_i = round(snake_size * i / 0.2)
        if pos_i < len(snake_list):
            pygame.draw.rect(screen, color_red, (*snake_list[pos_i], snake_size, snake_size))
    max_len = round(snake_size * snake_len / 0.2)
    del snake_list[max_len:]


推荐阅读