bodyakurbanov
@bodyakurbanov
Учусь программировать на python

Баг с змейкой она умирает раньше чем коснулась края экрана?

Всем привет я писал змейку для курсовой работы, не могу понять где я ошибся и почему змейка иногда умирает не доходя до края игрового поля а гдетто за 1см до его, так же бывает что яблоки появляются не в зоне досигания.
Вот мой код:
import pygame
from random import randrange

RES = 800
SIZE = 80

x, y = randrange(0, RES, SIZE), randrange(0, RES, SIZE)
apple = randrange(0, RES, SIZE), randrange(0, RES, SIZE)
dirs = {'W': True, 'S': True, 'A': True, 'D': True, }
length = 1
snake = [(x, y)]
dx, dy = 0, 0
score = 0
fps = 5

pygame.init()
sc = pygame.display.set_mode([RES, RES])
clock = pygame.time.Clock()
font_score = pygame.font.SysFont('Arial', 26, bold=True)
font_end = pygame.font.SysFont('Arial', 66, bold=True)

while True:
    sc.fill(pygame.Color('black'))
    # отрисовка
    [(pygame.draw.rect(sc, pygame.Color('green'), (i, j, SIZE - 2, SIZE - 2))) for i, j in snake]
    pygame.draw.rect(sc, pygame.Color('red'), (*apple, SIZE, SIZE))
    # Счёт
    render_score = font_score.render(f'SCORE: {score}', 1, pygame.Color('orange'))
    sc.blit(render_score, (5, 5))
    # Движение змейки
    x += dx * SIZE
    y += dy * SIZE
    snake.append((x, y))
    snake = snake[-length:]
    # Скушать яблочко
    if snake[-1] == apple:
        apple = randrange(0, RES, SIZE), randrange(0, RES, SIZE)
        length += 1
        fps += 0.5
        score += 1

    # game over
    if x < 0 or x > RES - SIZE or y < 0 or y > RES - SIZE or len(snake) != len(set(snake)):
        while True:
            render_end = font_end.render('GAME OVER', 1, pygame.Color('orange'))
            sc.blit(render_end, (RES // 2 - 180, RES // 2.5))
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    exit()

    pygame.display.flip()
    clock.tick(fps)
# закрытие приложения

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    # Управление
    key = pygame.key.get_pressed()
    if key[pygame.K_w] and dirs['W']:
        dx, dy = 0, -1
        dirs = {'W': True, 'S': False, 'A': True, 'D': True, }
    if key[pygame.K_s] and dirs['S']:
        dx, dy = 0, 1
        dirs = {'W': False, 'S': True, 'A': True, 'D': True, }
    if key[pygame.K_a] and dirs['A']:
        dx, dy = -1, 0
        dirs = {'W': True, 'S': True, 'A': True, 'D': False, }
    if key[pygame.K_d] and dirs['D']:
        dx, dy = 1, 0
        dirs = {'W': True, 'S': True, 'A': False, 'D': True, }
  • Вопрос задан
  • 97 просмотров
Решения вопроса 1
@Bright144
Вот рабочий код
Змейка

import pygame
from random import randrange
import keyboard

class Control:
    def __init__(self, dirs: dict, x_y: list, key: str) -> None:
        self.dirs = dirs
        self.x_y = x_y
        self.key = key

    def __call__(self, _):
        if self.key == 'W' and self.dirs['W']:
            self.x_y[:] = [0, -1]
            self.dirs.update({'W': True, 'S': False, 'A': True, 'D': True, })
        if self.key == 'S' and self.dirs['S']:
            self.x_y[:] = [0, 1]
            self.dirs.update({'W': False, 'S': True, 'A': True, 'D': True, })
        if self.key == 'A' and self.dirs['A']:
            self.x_y[:] = [-1, 0]
            self.dirs.update({'W': True, 'S': True, 'A': True, 'D': False, })
        if self.key == 'D' and self.dirs['D']:
            self.x_y[:] = [1, 0]
            self.dirs.update({'W': True, 'S': True, 'A': False, 'D': True, })
        print(self.dirs)


def run_ctrl():
    up = Control(dirs, x_y, 'W')
    down = Control(dirs, x_y, 'S')
    left = Control(dirs, x_y, 'A')
    right = Control(dirs, x_y, 'D')
    keyboard.on_press_key('W', up)
    keyboard.on_press_key('S', down)
    keyboard.on_press_key('A', left)
    keyboard.on_press_key('D', right)


RES = 800
SIZE = 80

x, y = randrange(0, RES, SIZE), randrange(0, RES, SIZE)
apple = randrange(0, RES, SIZE), randrange(0, RES, SIZE)
dirs = {'W': True, 'S': True, 'A': True, 'D': True, }
length = 1
snake = [(x, y)]
x_y = [0, 0]
dx, dy = 0, 0
score = 0
fps = 1

pygame.init()
sc = pygame.display.set_mode([RES, RES])
clock = pygame.time.Clock()
font_score = pygame.font.SysFont('Arial', 26, bold=True)
font_end = pygame.font.SysFont('Arial', 66, bold=True)

run_ctrl() #управление

while True:
    dx, dy = x_y    #передача значение управление
    sc.fill(pygame.Color('black'))

    # Счёт
    render_score = font_score.render(f'SCORE: {score}', 1, pygame.Color('orange'))
    sc.blit(render_score, (5, 5))
    # Движение змейки
    x += dx * SIZE
    y += dy * SIZE
    snake.append((x, y))
    snake = snake[-length:]
    # отрисовка
    [(pygame.draw.rect(sc, pygame.Color('green'), (i, j, SIZE - 2, SIZE - 2))) for i, j in snake]
    pygame.draw.rect(sc, pygame.Color('red'), (*apple, SIZE, SIZE))
    # Скушать яблочко
    if snake[-1] == apple:
        apple = randrange(0, RES, SIZE), randrange(0, RES, SIZE)
        length += 1
        fps += 0.1
        score += 1

    # game over
    if x < 0 or x > RES - SIZE or y < 0 or y > RES - SIZE or len(snake) != len(set(snake)):
        while True:
            render_end = font_end.render('GAME OVER', 1, pygame.Color('orange'))
            sc.blit(render_end, (RES // 2 - 180, RES // 2.5))
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    exit()

    pygame.display.flip()
    clock.tick(fps)
# закрытие приложения

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()


я не знакомый с pygame, но у тебя с управлением не все гладко по этому использовал модуль keyboard. У тебя змейка слушает команду после 1 клеток, то есть оно реагирует на команду позже. Это видно если заданный fps понизить на 1. Эту проблему можно решить если отрисовку поставить после движении. Но у тебя еще одна проблема, яблоки появляются прямо из тело змея.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы