用pygame制作蛇。接触蛇时使蛇变长的麻烦

时间:2019-07-08 02:21:34

标签: python 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)

2 个答案:

答案 0 :(得分:1)

如果要写入全局变量,则必须使用global statement
在事件循环中使用它来设置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_len,并通过1对其进行初始化。使用pygame.Rect对象和.colliderect()检查蛇是否吃掉了蛇。 Cookie并增加零件数:

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:]

答案 1 :(得分:0)

您的create_snake有两个问题:

def create_snake(direction):
    length = len(snake_list)
    for snake in snake_list:
        if direction == 'left':
            new_snake = [snake[0] + (length * snake_size), snake[1]]
        elif direction == 'right':
            new_snake = [snake[0] - (length * snake_size), snake[1]]
        elif direction == 'up':
            new_snake = [snake[0], snake[1] + (length * snake_size)]
        elif direction == 'down':
            new_snake = [snake[0], snake[1] - (length * snake_size)]

    snake_list.append(new_snake)

您的方向检查存在缺陷:您将方向设置为左/右/上/下,但是然后检查方向是否为左/右/上/下。

更重要的是,您要在遍历列表时追加到列表,这将创建无限循环。通过创建tmp变量new_snake,然后附加它可以解决此问题。 (这可能仍然不是您想要的-您尝试渲染蛇的方式似乎有问题,我鼓励您重新考虑它。)

祝你好运!

相关问题