Блог онлайн школы Пиксель

Бесплатный курс программирования для детей: создание игры в Python Ping-Pong

Дети обожают разные игры как онлайн, так и офлайн. А что если соединить два формата и сделать классное развлечение на компьютере по мотивам настольного тенниса? Думаем, что это будет по нраву многим. Сегодня школа программирования для детей «Пиксель» расскажет, юным разработчикам, как создать игру на Python с помощью специального модуля Pygame. Это можно легко сделать на курсах по Python для ребят или, прочитав наш гайд. Предлагаем после изучения теории посмотреть видео урок в конце статьи. Попробуйте самостоятельно создать игру на Python. Давайте начнём!

Этап 1. Как скачать и установить модули в Python


Модуль Pygame изначально не встроен в python, если у вас он не установлен, то проще всего это сделать в консоли командой pip install pygame:


Установив модуль Pygame, мы можем начать программировать. Импортируем модуль pygame для создания игры и модуль random для выбора рандомного направления мячика. Теперь зададим параметры экрана — выбираем 1000 на 500. И зададим несколько значений, которые пригодятся нам в игре — а именно ширину ракетки, высоту ракетки и скорость ее передвижения. В переменной fps укажем скорость игры в целом.

Теперь можем активировать дисплей, т.е. создать окно программы. Сразу же создадим две сущности для рисования будущих ракеток. Они также нужны, чтобы отслеживать местоположения и столкновения по имени данных сущностей.

Отдельно напишем параметры цвета в переменную. Они задаются по принципу RGB (red, green, blue) — красный, зеленый, синий, — из смешения которых создаются новые цвета. Далее мы указываем в скобках tuple или по-русски «кортеже», три цифры — выраженности каждого цвета.

Класс Clock() поможет нам работать с обновлением кадров нашей игры для детей на языке Python и также зададим название окну нашего тенниса.
Запускать игру будем через цикл с булевой переменной. Внутри напишем заливку экрана нужным нам цветом, создадим событие закрытия окна, чтобы программа адекватно реагировала на нажатие на крестик. Нарисуем наши ракетки с помощью команды draw.rect — это прямоугольник. С помощью команды flip запустим обновление кадров в нашей игре, а с помощью классового метода tick укажем скорость обновления кадров. Давайте проверим. У нас получилось поле с двумя ракетками.

Этап 2. Управление ракетками в игре на Python


Теперь давайте сделаем так, чтобы ракетками можно было управлять. Для этого в наш цикл добавим считывание клавиш с клавиатуры. Если клавиша «стрелка вверх» нажата, то мы двигаем нашу правую платформу вверх (так как ось Y направлена вниз, то пишем «- speed»), аналогично делаем для кнопки вниз. Опять проверяем. Все работает, но наша платформа может заходить за границы экрана. Чтобы это исправить, добавим еще по одному условию — нужно, чтобы координата верхней части платформы была ниже верхнего края и координата нижней части была выше нижнего. Проверяем, как все работает. Чтобы настроить управление для левой платформы, просто копируем эти два условия, меняем кнопки и проверяем  управление для двух кнопок еще раз.

Вот так мы нарисовали две платформы c управлением:

import pygame
import random

pygame.init()

screen_x = 1000
screen_y = 500

p_width = 15
p_height = 100
p_speed = 15

fps = 60

screen = pygame.display.set_mode((screen_x, screen_y))
platform_right = pygame.Rect(screen_x - p_width - 5, screen_y/2 - p_height/2, p_width, p_height )
platform_left = pygame.Rect(5, screen_y/2 - p_height/2, p_width, p_height )

green = (0, 133, 35)

clock = pygame.time.Clock()

pygame.display.set_caption("Ping-Pong Pixel Game")
game = True
while game:
    screen.fill(green)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    key = pygame.key.get_pressed()
    if (key[pygame.K_UP] and platform_right.top >0):
        platform_right.top -= p_speed
    elif (key[pygame.K_DOWN] and platform_right.bottom < screen_y):
        platform_right.bottom += p_speed
    elif (key[pygame.K_w] and platform_left.top > 0):
        platform_left.top -= p_speed
    elif (key[pygame.K_s] and platform_left.bottom < screen_y):
        platform_left.bottom += p_speed

    pygame.draw.rect(screen, pygame.Color("White"), platform_right)
    pygame.draw.rect(screen, pygame.Color("White"), platform_left)

    pygame.display.flip()
    clock.tick(fps)
pygame.quit()

Этап 3. Добавление переменных  и движения в игру на Python


Переходим к следующему шагу создания игры на Python. Теперь добавим в нашу игру шарик. Также запишем его сущность в переменную. В две переменные dx и dy зададим направления его движения. После нарисуем его внутри нашего цикла, используя команду draw.circle и запишем алгоритм его передвижения — т.е. к его координатам просто будет прибавляться скорость, умноженная на направление. Проверим, летает ли шарик.

Чтобы добавить отскоки шарика, мы напишем два условия:
  • если он сталкивается с верхней или нижней стенкой, то мы меняем направление по Y, т.е. если он летел вверх, то будет лететь вниз, и наоборот, если летел вниз, будет лететь вверх;
  • если он сталкивается с одной из платформ, то меняем направление по X; летел влево — полетел направо, летел вправо — полетит налево.

Проверяем, все ли работает. Но если наш мяч улетает за границы, а не возвращается в центр для продолжения игры, то нужно это настроить.

import random

pygame.init()

screen_x = 1000
screen_y = 500

p_width = 15
p_height = 100
p_speed = 15

ball_r = 10
ball_speed = 6
ball_d = ball_r * 2
ball_start_x = screen_x / 2 - ball_r
ball_start_y = screen_y / 2 - ball_r
fps = 60

screen = pygame.display.set_mode((screen_x, screen_y))
platform_right = pygame.Rect(screen_x - p_width - 5, screen_y/2 - p_height/2, p_width, p_height )
platform_left = pygame.Rect(5, screen_y/2 - p_height/2, p_width, p_height )
ball = pygame.Rect(ball_start_x, ball_start_y, ball_d, ball_d)
dx = 1
dy = -1 

green = (0, 133, 35)

clock = pygame.time.Clock()

pygame.display.set_caption("Ping-Pong Pixel Game")
game = True
while game:
    screen.fill(green)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    key = pygame.key.get_pressed()
    if (key[pygame.K_UP] and platform_right.top >0):
        platform_right.top -= p_speed
    elif (key[pygame.K_DOWN] and platform_right.bottom < screen_y):
        platform_right.bottom += p_speed
    elif (key[pygame.K_w] and platform_left.top > 0):
        platform_left.top -= p_speed
    elif (key[pygame.K_s] and platform_left.bottom < screen_y):
        platform_left.bottom += p_speed

    pygame.draw.rect(screen, pygame.Color("White"), platform_right)
    pygame.draw.rect(screen, pygame.Color("White"), platform_left)

    pygame.draw.circle(screen, pygame.Color("White"), ball.center, ball_r)
    ball.x += ball_speed * dx
    ball.y += ball_speed * dy

    if ball.centery < ball_r or ball.centery > screen_y - ball_r:
        dy = -dy
    elif ball.colliderect(platform_left) or ball.colliderect(platform_right):
        dx = -dx


    pygame.display.flip()
    clock.tick(fps)
pygame.quit()

Для этого просто добавим два условия:
  • если координаты шарика больше координат правой границы экрана, то один поинт начисляется игроку слева;
  • если координаты шарика меньше левой границы — то игроку справа.

Также координаты мяча ставятся на начальные.

Респавн мяча:

import pygame
import random

pygame.init()

screen_x = 1000
screen_y = 500

points_left = 0
points_right=  0

p_width = 15
p_height = 100
p_speed = 15

ball_r = 10
ball_speed = 6
ball_d = ball_r * 2

ball_start_x = screen_x/2 - ball_r
ball_start_y = screen_y/2 - ball_r

fps = 60

screen = pygame.display.set_mode((screen_x, screen_y))

platform_right = pygame.Rect(screen_x - p_width - 5, screen_y/2 - p_height/2, p_width, p_height )
platform_left = pygame.Rect(5, screen_y/2 - p_height/2, p_width, p_height )
ball = pygame.Rect(ball_start_x, ball_start_y, ball_d, ball_d)
dx = 1
dy = -1 

green = (0, 133, 35)

clock = pygame.time.Clock()

pygame.display.set_caption("Ping-Pong Pixel Game")
game = True
while game:
    screen.fill(green)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    key = pygame.key.get_pressed()
    if (key[pygame.K_UP] and platform_right.top >0):
        platform_right.top -= p_speed
    elif (key[pygame.K_DOWN] and platform_right.bottom < screen_y):
        platform_right.bottom += p_speed
    elif (key[pygame.K_w] and platform_left.top > 0):
        platform_left.top -= p_speed
    elif (key[pygame.K_s] and platform_left.bottom < screen_y):
        platform_left.bottom += p_speed

    pygame.draw.rect(screen, pygame.Color("White"), platform_right)
    pygame.draw.rect(screen, pygame.Color("White"), platform_left)

    pygame.draw.circle(screen, pygame.Color("White"), ball.center, ball_r)
    ball.x += ball_speed * dx
    ball.y += ball_speed * dy

    if ball.centery < ball_r or ball.centery > screen_y - ball_r:
        dy = -dy
    elif ball.colliderect(platform_left) or ball.colliderect(platform_right):
        dx = -dx

    if ball.centerx > screen_x:
        points_left += 1
        ball.x = ball_start_x
        ball.y = ball_start_y
    elif ball.centerx < 0:
        points_right += 1
        ball.x = ball_start_x
        ball.y = ball_start_y

    pygame.display.flip()
    clock.tick(fps)
pygame.quit()

Этап 4. Добавление счета и пауз в Пинг-Понг на Python


Можно сказать, что наша игра по уроку программирования для детей уже готова, но давайте улучшим ее, добавив счет и паузу между поинтами и звуком отскоков шарика.

Чтобы написать счет, мы введем класс Font, шрифт можно не указывать, а размер задать равным 50. И в цикле указываем рендеринг нашего текста — т.е. создаем его, а после с помощью метода blit выводим его на экран в нужные нам координаты. Запустим игру, чтобы проверить, что счет меняется и все работает корректно.
Счет:

import pygame
import random

pygame.init()

screen_x = 1000
screen_y = 500

points_left = 0
points_right = 0

p_width = 15
p_height = 100
p_speed = 15

ball_r = 10
ball_speed = 6
ball_d = ball_r * 2

ball_start_x = screen_x / 2 - ball_r
ball_start_y = screen_y / 2 - ball_r

fps = 60

screen = pygame.display.set_mode((screen_x, screen_y))

platform_right = pygame.Rect(
    screen_x - p_width - 5, screen_y / 2 - p_height / 2, p_width, p_height
)
platform_left = pygame.Rect(5, screen_y / 2 - p_height / 2, p_width, p_height)
ball = pygame.Rect(ball_start_x, ball_start_y, ball_d, ball_d)

font = pygame.font.Font(None, 50)

dx = 1
dy = -1

green = (0, 133, 35)

clock = pygame.time.Clock()

pygame.display.set_caption("Ping-Pong Pixel Game")
game = True
while game:
    screen.fill(green)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    key = pygame.key.get_pressed()
    if key[pygame.K_UP] and platform_right.top > 0:
        platform_right.top -= p_speed
    elif key[pygame.K_DOWN] and platform_right.bottom < screen_y:
        platform_right.bottom += p_speed
    elif key[pygame.K_w] and platform_left.top > 0:
        platform_left.top -= p_speed
    elif key[pygame.K_s] and platform_left.bottom < screen_y:
        platform_left.bottom += p_speed

    pygame.draw.rect(screen, pygame.Color("White"), platform_right)
    pygame.draw.rect(screen, pygame.Color("White"), platform_left)

    pygame.draw.circle(screen, pygame.Color("White"), ball.center, ball_r)

    ball.x += ball_speed * dx
    ball.y += ball_speed * dy

    if ball.centery < ball_r or ball.centery > screen_y - ball_r:
        dy = -dy
    elif ball.colliderect(platform_left) or ball.colliderect(platform_right):
        dx = -dx

    if ball.centerx > screen_x:
        points_right += 1
        ball.x = ball_start_x
        ball.y = ball_start_y
    elif ball.centerx < 0:
        points_left += 1
        ball.x = ball_start_x
        ball.y = ball_start_y

    right_text = font.render(f"{points_left}", True, pygame.Color("White"))
    screen.blit(right_text, (screen_x - 40, 20))

    left_text = font.render(f"{points_right}", True, pygame.Color("White"))
    screen.blit(left_text, (20, 20))

    pygame.display.flip()
    clock.tick(fps)
pygame.quit()

Для добавления паузы в игре ping pong на Python после гола отключаем движение — т.е. задаем нулевые направления. После этого включаем подсчет миллисекунд с момента, когда засчитан point и добавляем условие: если включена пауза, то мы должны записывать, сколько времени прошло с ее времени поинта. Если это время превысит 3000 миллисекунд, снова задаем рандомные направления и отключаем паузу, заменив значение в переменной pause на true. Проверяем, все ли работает.
С паузой:

import pygame
import random

pygame.init()

screen_x = 1000
screen_y = 500

points_left = 0
points_right = 0

p_width = 15
p_height = 100
p_speed = 15

ball_r = 10
ball_speed = 6
ball_d = ball_r * 2

ball_start_x = screen_x / 2 - ball_r
ball_start_y = screen_y / 2 - ball_r

fps = 60

screen = pygame.display.set_mode((screen_x, screen_y))

platform_right = pygame.Rect(
    screen_x - p_width - 5, screen_y / 2 - p_height / 2, p_width, p_height
)
platform_left = pygame.Rect(5, screen_y / 2 - p_height / 2, p_width, p_height)
ball = pygame.Rect(ball_start_x, ball_start_y, ball_d, ball_d)

font = pygame.font.Font(None, 50)

dx = 1
dy = -1

green = (0, 133, 35)

clock = pygame.time.Clock()

pause = False
pygame.display.set_caption("Ping-Pong Pixel Game")
game = True
while game:
    screen.fill(green)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    key = pygame.key.get_pressed()
    if key[pygame.K_UP] and platform_right.top > 0:
        platform_right.top -= p_speed
    elif key[pygame.K_DOWN] and platform_right.bottom < screen_y:
        platform_right.bottom += p_speed
    elif key[pygame.K_w] and platform_left.top > 0:
        platform_left.top -= p_speed
    elif key[pygame.K_s] and platform_left.bottom < screen_y:
        platform_left.bottom += p_speed

    pygame.draw.rect(screen, pygame.Color("White"), platform_right)
    pygame.draw.rect(screen, pygame.Color("White"), platform_left)

    pygame.draw.circle(screen, pygame.Color("White"), ball.center, ball_r)

    ball.x += ball_speed * dx
    ball.y += ball_speed * dy

    if ball.centery < ball_r or ball.centery > screen_y - ball_r:
        dy = -dy
    elif ball.colliderect(platform_left) or ball.colliderect(platform_right):
        dx = -dx

    if ball.centerx > screen_x:
        points_right += 1
        ball.x = ball_start_x
        ball.y = ball_start_y
        dx = 0
        dy = 0
        goal_time = pygame.time.get_ticks()
        pause = True
    elif ball.centerx < 0:
        points_left += 1
        ball.x = ball_start_x
        ball.y = ball_start_y
        dx = 0
        dy = 0
        goal_time = pygame.time.get_ticks()
        pause = True
    if pause:
        #milliseconds
        current_time = pygame.time.get_ticks()
        if current_time - goal_time > 3000:
            dx = random.choice((1, -1))
            dy = random.choice((1, -1))
            pause = False


    right_text = font.render(f"{points_left}", False, pygame.Color("White"))
    screen.blit(right_text, (screen_x - 40, 20))

    left_text = font.render(f"{points_right}", False, pygame.Color("White"))
    screen.blit(left_text, (20, 20))

    pygame.display.flip()
    clock.tick(fps)
pygame.quit()

Этап 5. Добавление звука в игру на Python


Финальным штрихом в нашей игре на языке Python для детей будет добавление звука. Для этого с помощью команды pong_sound = pygame.mixer.Sound (“pong.ogg”) загружаем звук, и с помощью команды pygame.mixer.Sound.play (pong_sound) мы его проигрываем в моменты столкновения шарика со стенками или ракетками.
Вот такой финал со звуком:

import pygame
import random

pygame.init()

screen_x = 1000
screen_y = 500

points_left = 0
points_right = 0

p_width = 15
p_height = 100
p_speed = 15

ball_r = 10
ball_speed = 6
ball_d = ball_r * 2

ball_start_x = screen_x / 2 - ball_r
ball_start_y = screen_y / 2 - ball_r

fps = 60

screen = pygame.display.set_mode((screen_x, screen_y))

platform_right = pygame.Rect(
    screen_x - p_width - 5, screen_y / 2 - p_height / 2, p_width, p_height
)
platform_left = pygame.Rect(5, screen_y / 2 - p_height / 2, p_width, p_height)
ball = pygame.Rect(ball_start_x, ball_start_y, ball_d, ball_d)

font = pygame.font.Font(None, 50)

dx = 1
dy = -1

green = (0, 133, 35)

clock = pygame.time.Clock()
pong_sound = pygame.mixer.Sound("pong.ogg")
pause = False
pygame.display.set_caption("Ping-Pong Pixel Game")
game = True
while game:
    screen.fill(green)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    key = pygame.key.get_pressed()
    if key[pygame.K_UP] and platform_right.top > 0:
        platform_right.top -= p_speed
    elif key[pygame.K_DOWN] and platform_right.bottom < screen_y:
        platform_right.bottom += p_speed
    elif key[pygame.K_w] and platform_left.top > 0:
        platform_left.top -= p_speed
    elif key[pygame.K_s] and platform_left.bottom < screen_y:
        platform_left.bottom += p_speed

    pygame.draw.rect(screen, pygame.Color("White"), platform_right)
    pygame.draw.rect(screen, pygame.Color("White"), platform_left)

    pygame.draw.circle(screen, pygame.Color("White"), ball.center, ball_r)

    ball.x += ball_speed * dx
    ball.y += ball_speed * dy

    if ball.centery < ball_r or ball.centery > screen_y - ball_r:
        dy = -dy
        pygame.mixer.Sound.play(pong_sound)
    elif ball.colliderect(platform_left) or ball.colliderect(platform_right):
        dx = -dx
        pygame.mixer.Sound.play(pong_sound)

    if ball.centerx > screen_x:
        points_right += 1
        ball.x = ball_start_x
        ball.y = ball_start_y
        dx = 0
        dy = 0
        goal_time = pygame.time.get_ticks()
        pause = True
    elif ball.centerx < 0:
        points_left += 1
        ball.x = ball_start_x
        ball.y = ball_start_y
        dx = 0
        dy = 0
        goal_time = pygame.time.get_ticks()
        pause = True
    if pause:
        #milliseconds
        current_time = pygame.time.get_ticks()
        if current_time - goal_time > 3000:
            dx = random.choice((1, -1))
            dy = random.choice((1, -1))
            pause = False


    right_text = font.render(f"{points_left}", False, pygame.Color("White"))
    screen.blit(right_text, (screen_x - 40, 20))

    left_text = font.render(f"{points_right}", False, pygame.Color("White"))
    screen.blit(left_text, (20, 20))

    pygame.display.flip()
    clock.tick(fps)
pygame.quit()

На этом бесплатный урок программирования для детей окончен, наша игра отлично работает и вы можете поменять её по своему вкусу, задав свои настройки. Надеемся, вы научились чему-то новому и сами попробовали написать код. Чтобы проверить себя или уточнить какие-то моменты, смотрите полное видео по созданию игры на Python по ссылке.

Другие бесплатные уроки программирования для детей смотрите на нашем YouTube-канале (плейлисты “Создание игр на Python” и “Уроки Python для детей”.

А чтобы глубже разобраться в Python, записывайтесь на курсы программирования для детей в школу «Пиксель». У нас есть бесплатный пробный урок, на котором ребенок сможет получше познакомиться с преподавателями и найти направление по душе.






Python для детей Бесплатные видеоуроки