(Python Змея игра) Для L oop не рисует змею - PullRequest
3 голосов
/ 29 января 2020

Это небольшая проблема, работа над игрой со змеями в python, она еще не завершена, и есть только одна вещь, которую я хотел бы знать. У меня изначально был код pygame.draw.rect(SCREEN, GREEN, (x_pos[i], y_pos[i], WIDTH, HEIGHT)) в функции move_snake. Код рисовал змею очень хорошо, пока она у меня была такой, однако сейчас я пытаюсь вырастить змею, поэтому я переместил ее в for l oop в функции grow_snake. Он больше не будет рисовать змею, однако он все еще существует, очевидно, как будто я нажимаю на клавиши, в конечном итоге он попадает на границу и заканчивает игру. Просто хочу знать, почему это больше не привлечет змею. Спасибо. Я новичок в программировании, поэтому, если вы хотите просмотреть код и дать мне советы о том, как его улучшить, это будет очень цениться. Имейте в виду, что эта работа еще не завершена, поэтому в игре отсутствует множество очевидных сегментов, которые я добавлю позже.

# Snake game

import pygame
import random


pygame.init()
pygame.display.set_caption("Snake Game and AI")

WIDTH = 24
HEIGHT = 24
SCREEN = pygame.display.set_mode((500, 500))
RED = (255, 0, 0)
BLACK = (0, 0, 0)
GREEN = (0, 128, 0)
WHITE = (255, 255, 255)
SPEED = 25
x_head = 251
y_head = 251
direction = None
apple_x = random.randrange(26, 476, 25)
apple_y = random.randrange(26, 476, 25)
length = 0
x_pos = [x_head]
y_pos = [y_head]


def grid():
    for x in range(25, 500, 25):
        pygame.draw.rect(SCREEN, WHITE, (x, 25, 1, 450))

    for y in range(25, 500, 25):
        pygame.draw.rect(SCREEN, WHITE, (25, y, 450, 1))


def press_key():
    global direction
    global keys
    if keys[pygame.K_RIGHT] and direction != 'left':
        direction = 'right'
    if keys[pygame.K_LEFT] and direction != 'right':
        direction = 'left'
    if keys[pygame.K_UP] and direction != 'down':
        direction = 'up'
    if keys[pygame.K_DOWN] and direction != 'up':
        direction = 'down'


def move_snake():
    global x_head
    global y_head
    global SCREEN
    global WIDTH
    global HEIGHT
    if direction == 'right':
        x_head += SPEED
    if direction == 'left':
        x_head -= SPEED
    if direction == 'up':
        y_head -= SPEED
    if direction == 'down':
        y_head += SPEED


def eat_apple():
    global apple_x
    global apple_y
    global length
    if x_head == apple_x and y_head == apple_y:
        apple_x = random.randrange(26, 476, 25)
        apple_y = random.randrange(26, 476, 25)
        if direction == 'right':
            pass
        if direction == 'left':
            pass
        if direction == 'up':
            pass
        if direction == 'down':
            pass
        length += 1
    pygame.draw.rect(SCREEN, RED, (apple_x, apple_y, WIDTH, HEIGHT))


def grow_snake():
    move_snake()
    global x_pos
    global y_pos
    for i in range(length):
        pygame.draw.rect(SCREEN, GREEN, (x_pos[i], y_pos[i], WIDTH, HEIGHT))


def game_over():
    global is_running
    if x_head < 26 or x_head > 456 or y_head < 26 or y_head > 456:
        is_running = False


is_running = True
while is_running:
    pygame.time.delay(150)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False

    keys = pygame.key.get_pressed()
    press_key()
    move_snake()
    SCREEN.fill(BLACK)
    grid()
    grow_snake()
    eat_apple()
    game_over()
    pygame.display.update()


pygame.quit()

Ответы [ 2 ]

1 голос
/ 29 января 2020

Вам вообще не нужны x_head, y_head и length. Положение змеи хранится в списках x_pos и y_pos, используйте ее:
(zip() агрегирует элементы списка)

def grow_snake():
    for x, y in zip(x_pos, y_pos):
        pygame.draw.rect(SCREEN, GREEN, (x, y, WIDTH, HEIGHT))

Если вы хотите узнать длину змеи, вы можете получить ее по длине списков (например, len(x_pos).

Чтобы переместить змею, вычислите новую позицию головы, добавьте новую поместите в начало списков и уберите хвост списка

def move_snake():
    global SCREEN, WIDTH, HEIGHT, x_pos, y_pos

    # compute new head
    x_head, y_head = x_pos[0], y_pos[0]
    if direction == 'right':
        x_head += SPEED
    if direction == 'left':
        x_head -= SPEED
    if direction == 'up':
        y_head -= SPEED
    if direction == 'down':
        y_head += SPEED

    # add new head at head of lists
    x_pos = [x_head] + x_pos
    y_pos = [y_head] + y_pos

    # delete tail of snake
    del x_pos[-1]
    del y_pos[-1]

Если вы едите яблоко, добавьте новый элемент в хвост змеи:

def eat_apple():
    global apple_x, apple_y, x_pos, y_pos
    if x_pos[0] == apple_x and y_pos[0] == apple_y:
        apple_x = random.randrange(26, 476, 25)
        apple_y = random.randrange(26, 476, 25)
        x_pos.append(x_pos[-1])
        y_pos.append(y_pos[-1])
    pygame.draw.rect(SCREEN, RED, (apple_x, apple_y, WIDTH, HEIGHT))

Код без x_head, y_head и length:

# Snake game

import pygame
import random


pygame.init()
pygame.display.set_caption("Snake Game and AI")

WIDTH = 24
HEIGHT = 24
SCREEN = pygame.display.set_mode((500, 500))
RED = (255, 0, 0)
BLACK = (0, 0, 0)
GREEN = (0, 128, 0)
WHITE = (255, 255, 255)
SPEED = 25
direction = None
apple_x = random.randrange(26, 476, 25)
apple_y = random.randrange(26, 476, 25)
x_pos = [251]
y_pos = [251]


def grid():
    for x in range(25, 500, 25):
        pygame.draw.rect(SCREEN, WHITE, (x, 25, 1, 450))

    for y in range(25, 500, 25):
        pygame.draw.rect(SCREEN, WHITE, (25, y, 450, 1))


def press_key():
    global direction
    global keys
    if keys[pygame.K_RIGHT] and direction != 'left':
        direction = 'right'
    if keys[pygame.K_LEFT] and direction != 'right':
        direction = 'left'
    if keys[pygame.K_UP] and direction != 'down':
        direction = 'up'
    if keys[pygame.K_DOWN] and direction != 'up':
        direction = 'down'


def move_snake():
    global SCREEN, WIDTH, HEIGHT, x_pos, y_pos
    x_head, y_head = x_pos[0], y_pos[0]
    if direction == 'right':
        x_head += SPEED
    if direction == 'left':
        x_head -= SPEED
    if direction == 'up':
        y_head -= SPEED
    if direction == 'down':
        y_head += SPEED
    x_pos = [x_head] + x_pos
    y_pos = [y_head] + y_pos
    del x_pos[-1]
    del y_pos[-1]


def eat_apple():
    global apple_x, apple_y, x_pos, y_pos
    if x_pos[0] == apple_x and y_pos[0] == apple_y:
        apple_x = random.randrange(26, 476, 25)
        apple_y = random.randrange(26, 476, 25)
        x_pos.append(x_pos[-1])
        y_pos.append(y_pos[-1])
    pygame.draw.rect(SCREEN, RED, (apple_x, apple_y, WIDTH, HEIGHT))


def grow_snake():
    for x, y in zip(x_pos, y_pos):
        pygame.draw.rect(SCREEN, GREEN, (x, y, WIDTH, HEIGHT))


def game_over():
    global is_running
    if x_pos[0] < 26 or x_pos[0] > 456 or y_pos[0] < 26 or y_pos[0] > 456:
        is_running = False


is_running = True
while is_running:
    pygame.time.delay(150)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False

    keys = pygame.key.get_pressed()
    press_key()
    move_snake()
    SCREEN.fill(BLACK)
    grid()
    grow_snake()
    eat_apple()
    game_over()
    pygame.display.update()


pygame.quit()
0 голосов
/ 29 января 2020

В вашем коде вы инициализируете length до 0. Возьмем, к примеру, этот упрощенный код, который ясно показывает вашу проблему.

length = 0
for i in range(length):
    print(i)

Этот фрагмент не производит вывода, так как range дает все целые числа до, но не включая stop параметр.

Чтобы устранить проблему, измените свой range на range(length+1).

Сайт Code Review является подходящим местом для получения предложений по улучшению на рабочем коде. Вы получите советы по таким вопросам, как производительность, комментирование, удобочитаемость и стиль.

Имейте в виду, что вы можете получить предложение о реорганизации вашего кода и инициализации length до 1. Хотя 0 может быть удобно для индексации списка, оно не совсем точно отражает длину змеи и иногда приводит к проблемам, подобным той, которая возникает в этом вопросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...