Пишем игру Питон на Python ;). Часть 1

В рамках компании по попытке обучения одного товарища программированию начал писать классическую игру Питон. С правилами: питон двигается по полю, если он что-то ест, то растёт. Если натыкается на стену или на самого себя — игрок проигрывает.

В этой части обучающей статьи, мы научимся вырисовывать питона и управлять им с клавиатуры. Результатом будет что-то вроде:

Для отрисовки графики и получения событий нажатия клавиш будем использовать библиотеку pygame

Итак начнем. Сначала зададим настроечные переменные для игры, как то размер поля, цвета и т.п.:

# объявляем переменные
FPS = 60
width_field=800 # размер поля по ширине
height_field=600 # размер поля по высоте
size_x=20   # количество клеток по ширине
size_y=20   # количество клеток по высоте
color_grid=(0,200,100)  # цвет линий ячеек
fill_grid=(0,0,0)       # цвет игровогого поля
color_python=(50,200,100) # цвет тела питона
step_x=round(width_field/size_x,0)  # шаг клетки по ширине
step_y=round(height_field/size_y,0) # шаг клетки по высоте
python_body=[[round(size_x/2,0),round(size_y/2,0)],[round((size_x-2)/2,0),round(size_y/2,0)],[round((size_x-4)/2,0),round(size_y/2,0)]] # массив тела питона
moved_direction_x=0 # текущее направление движения питона по оси x
moved_direction_y=0 # текущее направление движения питона по оси y

Затем создадим окно с указанными размерами , закрасим его чёрным цветом, и нарисуем сетку:

# Расчерчиваем поле
def Draw_grid_field(screen):
 xx=0;
 for x in range(size_x):
   pygame.draw.line(screen,color_grid,(xx,0),(xx,height_field))
   xx=xx+step_x;
 yy=0;
 for y in range(size_y):
   pygame.draw.line(screen,color_grid,(0,yy),(width_field,yy))
   yy=yy+step_y;

# Да начнётся игра..
pygame.init()
screen = pygame.display.set_mode((width_field, height_field))
screen.fill(fill_grid)
Draw_grid_field(screen)

Далее нам нужно создать бесконечный цикл, внутри которого будем ловить события нажатия стрелочек клавиатуры, и задавать вектор движения головы питона:

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                moved_direction_x=-1
                moved_direction_y=0
            if event.key == pygame.K_RIGHT:
                moved_direction_x = 1
                moved_direction_y = 0
            if event.key == pygame.K_UP:
                moved_direction_y = -1
                moved_direction_x=0
            if event.key == pygame.K_DOWN:
                moved_direction_x=0
                moved_direction_y = 1
        if event.type == pygame.QUIT:
           running = False
    pygame.display.flip()
    pygame.display.update()
    clock.tick(FPS)
pygame.quit()
print("нормально вышли")

Если мы сейчас в этот цикл вставим событие отрисовки самого питона, то он будет двигаться с дикой скоростью. Ограничим её одной клеткой в секунду, используя измерение времени. В начале цикла замерим время начала игры, и внутри цикла, если видим, что прошла секунда — отрисовываем питона, для этого чуть изменим код:

start_time=time.time()
running = True
while running:
    if (time.time()-start_time)>1:
        start_time=time.time()
        Draw_python(screen)
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                moved_direction_x=-1
                moved_direction_y=0
            if event.key == pygame.K_RIGHT:
                moved_direction_x = 1
                moved_direction_y = 0
            if event.key == pygame.K_UP:
                moved_direction_y = -1
                moved_direction_x=0
            if event.key == pygame.K_DOWN:
                moved_direction_x=0
                moved_direction_y = 1
        if event.type == pygame.QUIT:
           running = False
    pygame.display.flip()
    pygame.display.update()
    clock.tick(FPS)
pygame.quit()
print("нормально вышли")

Функции отрисовки питона (Draw_python) пока нет. Создадим её.. В начале функции посчитаем радиус кружка тела. Потом если вектор направления задан, то голову передвинем на вектор, а жопу питона удалим. Таким образом создадим видимость движения питона:

# рисуем питона
def Draw_python(screen):
    radius = (round(step_x / 2)-1) if round(step_x / 2) < round(step_y / 2) else (round(step_y / 2)-1)  # выбираем радиус по ширине или высоте шага, смотря что меньше, чтоб вписаться в прямоугольник
    if moved_direction_x!=0 or moved_direction_y!=0:
        print(f"Пришли:{python_body}")
        head_coor = python_body[0].copy()
        head_coor[0] = head_coor[0] + moved_direction_x;
        head_coor[1] = head_coor[1] + moved_direction_y;
        print(f"-тело{python_body},голова: {head_coor}");
        python_body.insert(0, head_coor) # передвигаю голову
        print(f"Передвинули голову:{python_body}")

        # удаляю жопу
        element=python_body[len(python_body) - 1]
        coors=[element[0]*step_x-step_x/2,element[1]*step_y-step_y/2]
        pygame.draw.circle(screen,(0,0,0),coors,radius)

        python_body.pop(-1)  # удаляю последний элемент хвоста
        print(f"удалили жопу:{python_body}")

    # рисую тушку
    for element in python_body:
        coors=[element[0]*step_x-step_x/2,element[1]*step_y-step_y/2]
        pygame.draw.circle(screen,color_python,coors,radius)

Скачать результат

Один комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.