Пишем игру Питон на Python ;). Часть 1
В рамках компании по попытке обучения одного товарища программированию начал писать классическую игру Питон. С правилами: питон двигается по полю, если он что-то ест, то растёт. Если натыкается на стену или на самого себя — игрок проигрывает.
В этой части обучающей статьи, мы научимся вырисовывать питона и управлять им с клавиатуры. Результатом будет что-то вроде:
Для отрисовки графики и получения событий нажатия клавиш будем использовать библиотеку pygame
Итак начнем. Сначала зададим настроечные переменные для игры, как то размер поля, цвета и т.п.:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# объявляем переменные 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 |
Затем создадим окно с указанными размерами , закрасим его чёрным цветом, и нарисуем сетку:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# Расчерчиваем поле 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) |
Далее нам нужно создать бесконечный цикл, внутри которого будем ловить события нажатия стрелочек клавиатуры, и задавать вектор движения головы питона:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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("нормально вышли") |
Если мы сейчас в этот цикл вставим событие отрисовки самого питона, то он будет двигаться с дикой скоростью. Ограничим её одной клеткой в секунду, используя измерение времени. В начале цикла замерим время начала игры, и внутри цикла, если видим, что прошла секунда — отрисовываем питона, для этого чуть изменим код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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) пока нет. Создадим её.. В начале функции посчитаем радиус кружка тела. Потом если вектор направления задан, то голову передвинем на вектор, а жопу питона удалим. Таким образом создадим видимость движения питона:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# рисуем питона 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) |