Практика разработки игр на Python: примеры и инструкции
Примеры игр на Python: от простых к сложным
В этой статье рассматриваются разные подходы к созданию игр на Python. Приводятся примеры кода, пояснения и типичные ошибки для каждого варианта.
Наиболее эффективное решение: игра «Змейка» на Pygame
Pygame - популярная библиотека для создания 2D-игр. Она предоставляет инструменты для работы с графикой, звуком и событиями. Рассмотрим создание классической змейки.
import pygame, random
pygame.init()
W, H = 600, 400
CELL = 20
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
snake = [(W//2, H//2)]
dx, dy = CELL, 0
food = (random.randrange(0, W, CELL), random.randrange(0, H, CELL))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and dy == 0: dx, dy = 0, -CELL
elif event.key == pygame.K_DOWN and dy == 0: dx, dy = 0, CELL
elif event.key == pygame.K_LEFT and dx == 0: dx, dy = -CELL, 0
elif event.key == pygame.K_RIGHT and dx == 0: dx, dy = CELL, 0
head = (snake[0][0] + dx, snake[0][1] + dy)
if head in snake or head[0] < 0 or head[0] >= W or head[1] < 0 or head[1] >= H:
running = False
snake.insert(0, head)
if head == food:
food = (random.randrange(0, W, CELL), random.randrange(0, H, CELL))
else:
snake.pop()
screen.fill((0,0,0))
for seg in snake:
pygame.draw.rect(screen, (0,255,0), (seg[0], seg[1], CELL, CELL))
pygame.draw.rect(screen, (255,0,0), (food[0], food[1], CELL, CELL))
pygame.display.flip()
clock.tick(10)
pygame.quit()игры на python примеры (примеры игр на python)
Этот код инициализирует окно, создаёт змейку, управление стрелками, еду и проверку столкновений. Основной цикл обрабатывает события и обновляет экран.
Типичные ошибки:
- Забыть
pygame.display.flip()- экран не обновляется. - Неправильное управление: разрешён поворот на 180 градусов (змейка врезается в себя). В примере проверяется, что направление не противоположное.
- Мерцание - решается постоянной перерисовкой и ограничением FPS через
clock.tick().
Цель: освоить базовые концепции игрового цикла, обработки пользовательского ввода и коллизий. Подходит для первого графического проекта.
Как реализовать консольную игру «Угадай число»?
Простой вариант для начинающих, не требующий внешних библиотек.
import random
number = random.randint(1, 100)
attempts = 0
print('Угадайте число от 1 до 100')
while True:
guess = input('Ваше предположение: ')
if not guess.isdigit():
print('Введите целое число')
continue
guess = int(guess)
attempts += 1
if guess < number:
print('Больше')
elif guess > number:
print('Меньше')
else:
print(f'Поздравляю! Вы угадали за {attempts} попыток')
breakPython game codes (коды для игр на python)
Ошибки:
- Не проверяется ввод нечисловых данных - программа крашится. Используется
isdigit(). - Бесконечный цикл при некорректном вводе - добавлено
continue.
Цель: отработать циклы, условные операторы и обработку ввода. Хорошая отправная точка.
Как создать крестики-нолики с графическим интерфейсом?
Используем Pygame для отрисовки и обработки кликов.
import pygame
pygame.init()
SIZE = 300
screen = pygame.display.set_mode((SIZE, SIZE))
board = [[None]*3 for _ in range(3)]
player = 'X'
def draw_board():
screen.fill((255,255,255))
for i in range(1,3):
pygame.draw.line(screen, (0,0,0), (i*100,0), (i*100,SIZE), 2)
pygame.draw.line(screen, (0,0,0), (0,i*100), (SIZE,i*100), 2)
for r in range(3):
for c in range(3):
if board[r][c] == 'X':
pygame.draw.line(screen, (255,0,0), (c*100+10,r*100+10), (c*100+90,r*100+90), 2)
pygame.draw.line(screen, (255,0,0), (c*100+90,r*100+10), (c*100+10,r*100+90), 2)
elif board[r][c] == 'O':
pygame.draw.circle(screen, (0,0,255), (c*100+50,r*100+50), 40, 2)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = event.pos
r, c = y//100, x//100
if board[r][c] is None:
board[r][c] = player
player = 'O' if player == 'X' else 'X'
draw_board()
pygame.display.flip()
pygame.quit()создание игры на python (создание игры на python)
Проблемы:
- Нет проверки на победу или ничью - игра бесконечна. Можно добавить функцию проверки линий.
- Координаты мыши не масштабируются при изменении размера окна. В примере окно фиксировано.
Цель: изучить работу с мышью, сеточную логику и чередование ходов.
Как написать текстовый квест с выбором действий?
Интерактивная история без графики - развивает логику ветвлений.
def start():
print('Вы просыпаетесь в лесу. Рядом тропинка.')
choice = input('1 - пойти по тропинке, 2 - остаться: ')
if choice == '1':
path()
elif choice == '2':
print('Вы сидите и ждёте. Ничего не происходит. Конец.')
else:
print('Некорректный ввод')
start()
def path():
print('На тропинке вы видите сундук.')
choice = input('1 - открыть, 2 - обойти: ')
if choice == '1':
print('В сундуке золото! Вы победили.')
elif choice == '2':
print('Вы обошли сундук и вышли к деревне. Конец.')
else:
print('Некорректный ввод')
path()
start()Ошибки:
- Рекурсия может привести к переполнению стека при частых неправильных вводах. Лучше использовать цикл.
- Отсутствие сохранения состояния - для больших квестов нужна структура данных.
Цель: понять ветвление и пользовательский ввод. Подходит для прототипирования сюжетных историй.
Как создать простую аркаду на библиотеке Arcade?
Arcade - современная альтернатива Pygame, проще в использовании.
import arcade
SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
class Game(arcade.Window):
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT)
self.player_x = 100
self.player_y = 100
def on_draw(self):
arcade.start_render()
arcade.draw_circle_filled(self.player_x, self.player_y, 20, arcade.color.BLUE)
def on_key_press(self, key, modifiers):
if key == arcade.key.LEFT:
self.player_x -= 10
elif key == arcade.key.RIGHT:
self.player_x += 10
if __name__ == '__main__':
Game()
arcade.run()Проблемы:
- Объект нереагирующий на границы - уходит за экран. Нужно добавить проверки.
- Нет обработки столкновений с другими объектами.
Цель: познакомиться с объектно-ориентированным подходом в игровом программировании и библиотекой Arcade.
Расширенные примеры с кодом и результатами
Полный код игры «Змейка» с улучшениями
Добавлены счёт, рестарт по пробелу и фиксация FPS.
import pygame, random
pygame.init()
W, H = 600, 400
CELL = 20
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
font = pygame.font.SysFont('arial', 24)
def game_loop():
snake = [(W//2, H//2)]
dx, dy = CELL, 0
food = (random.randrange(0, W, CELL), random.randrange(0, H, CELL))
score = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
return True
elif event.key == pygame.K_UP and dy == 0:
dx, dy = 0, -CELL
elif event.key == pygame.K_DOWN and dy == 0:
dx, dy = 0, CELL
elif event.key == pygame.K_LEFT and dx == 0:
dx, dy = -CELL, 0
elif event.key == pygame.K_RIGHT and dx == 0:
dx, dy = CELL, 0
head = (snake[0][0] + dx, snake[0][1] + dy)
if head in snake or head[0] < 0 or head[0] >= W or head[1] < 0 or head[1] >= H:
break
snake.insert(0, head)
if head == food:
food = (random.randrange(0, W, CELL), random.randrange(0, H, CELL))
score += 1
else:
snake.pop()
screen.fill((0,0,0))
for seg in snake:
pygame.draw.rect(screen, (0,255,0), (seg[0], seg[1], CELL, CELL))
pygame.draw.rect(screen, (255,0,0), (food[0], food[1], CELL, CELL))
text = font.render(f'Score: {score}', True, (255,255,255))
screen.blit(text, (10,10))
pygame.display.flip()
clock.tick(10)
return True # restart flag
while game_loop():
pass
pygame.quit()Результат: запускается окно с игрой. При столкновении или нажатии пробела игра перезапускается. Счёт отображается вверху слева.
Тетрис на Pygame (упрощённая версия)
Реализуется поворот фигур и удаление заполненных линий.
import pygame, random
pygame.init()
W, H = 300, 600
CELL = 30
screen = pygame.display.set_mode((W, H))
board = [[0]*10 for _ in range(20)]
figures = [
[[1,1,1,1]], # I
[[1,1],[1,1]], # O
[[0,1,0],[1,1,1]], # T
[[1,0,0],[1,1,1]], # L
[[0,0,1],[1,1,1]] # J
]
def draw_board():
for r in range(20):
for c in range(10):
if board[r][c]:
pygame.draw.rect(screen, (0,255,0), (c*CELL, r*CELL, CELL, CELL))
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 500
current = {'shape': random.choice(figures), 'x': 3, 'y': 0}
def collision(shape, x, y):
for r, row in enumerate(shape):
for c, val in enumerate(row):
if val and (y+r >= 20 or x+c < 0 or x+c >= 10 or board[y+r][x+c]):
return True
return False
def merge():
for r, row in enumerate(current['shape']):
for c, val in enumerate(row):
if val:
board[current['y']+r][current['x']+c] = 1
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and not collision(current['shape'], current['x']-1, current['y']):
current['x'] -= 1
elif event.key == pygame.K_RIGHT and not collision(current['shape'], current['x']+1, current['y']):
current['x'] += 1
elif event.key == pygame.K_UP:
rotated = list(zip(*current['shape'][::-1]))
if not collision(rotated, current['x'], current['y']):
current['shape'] = rotated
elif event.key == pygame.K_DOWN:
if not collision(current['shape'], current['x'], current['y']+1):
current['y'] += 1
fall_time += clock.get_rawtime()
if fall_time >= fall_speed:
fall_time = 0
if not collision(current['shape'], current['x'], current['y']+1):
current['y'] += 1
else:
merge()
for r in range(19, -1, -1):
if all(board[r]):
del board[r]
board.insert(0, [0]*10)
current = {'shape': random.choice(figures), 'x': 3, 'y': 0}
if collision(current['shape'], current['x'], current['y']):
running = False
draw_board()
for r, row in enumerate(current['shape']):
for c, val in enumerate(row):
if val:
pygame.draw.rect(screen, (255,255,0), ((current['x']+c)*CELL, (current['y']+r)*CELL, CELL, CELL))
pygame.display.flip()
clock.tick(30)
pygame.quit()Результат: игра Тетрис с базовыми фигурами, автоматическим падением и удалением заполненных линий. Управление стрелками, поворот - вверх.
Игра на выживание с библиотекой Arcade
Летающие объекты, которые нужно избегать.
import arcade, random
SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
class Enemy(arcade.SpriteCircle):
def __init__(self):
super().__init__(20, arcade.color.RED)
self.center_x = random.randrange(SCREEN_WIDTH)
self.center_y = SCREEN_HEIGHT
self.change_y = -random.uniform(2,5)
def update(self):
self.center_y += self.change_y
if self.top < 0:
self.center_y = SCREEN_HEIGHT + 20
self.center_x = random.randrange(SCREEN_WIDTH)
class Game(arcade.Window):
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT)
self.player = arcade.SpriteCircle(30, arcade.color.BLUE)
self.player.center_x = SCREEN_WIDTH//2
self.player.center_y = 50
self.enemies = arcade.SpriteList()
for _ in range(5):
self.enemies.append(Enemy())
def on_draw(self):
arcade.start_render()
self.player.draw()
self.enemies.draw()
def on_key_press(self, key, modifiers):
if key == arcade.key.LEFT and self.player.left > 0:
self.player.center_x -= 20
elif key == arcade.key.RIGHT and self.player.right < SCREEN_WIDTH:
self.player.center_x += 20
def update(self, delta_time):
self.enemies.update()
if arcade.check_for_collision_with_list(self.player, self.enemies):
arcade.close_window()
if __name__ == '__main__':
Game()
arcade.run()Результат: игрок управляет синим кругом, уклоняясь от падающих красных. При столкновении окно закрывается.