Files
UltraChat/GigaPong/pong.py
sShemet ade2833df7 init
2025-12-22 14:03:10 +05:00

192 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pygame
import sys
# Инициализация pygame
pygame.init()
# Константы
WIDTH, HEIGHT = 800, 600
PADDLE_WIDTH, PADDLE_HEIGHT = 10, 100
BALL_SIZE = 15
WHITE = (255, 255, 255)
FPS = 60
WINNING_SCORE = 10 # Основной счёт для победы
TIE_BREAK_REQUIRED_DIFFERENCE = 2 # Разница для победы в тай-брейке
AI_SPEED = 0.7 # Уровень "умения" ИИ (0.5 - очень медленный, 1.0 - идеальный)
# Создание экрана
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pong с ИИ")
clock = pygame.time.Clock()
# Функция для сброса игры
def reset_game():
return {
"player_paddle": pygame.Rect(20, HEIGHT//2 - PADDLE_HEIGHT//2, PADDLE_WIDTH, PADDLE_HEIGHT),
"ai_paddle": pygame.Rect(WIDTH - 30, HEIGHT//2 - PADDLE_HEIGHT//2, PADDLE_WIDTH, PADDLE_HEIGHT),
"ball": pygame.Rect(WIDTH//2 - BALL_SIZE//2, HEIGHT//2 - BALL_SIZE//2, BALL_SIZE, BALL_SIZE),
"ball_speed_x": 5,
"ball_speed_y": 5,
"player_score": 0,
"ai_score": 0,
"game_over": False,
"tie_break_active": False,
"win_message": None,
"show_win_screen": False,
"restart_timer": 0
}
# Состояние игры
game_state = reset_game()
# Шрифты
score_font = pygame.font.Font(None, 74)
win_font = pygame.font.Font(None, 100)
def move_ai_paddle(paddle, ball):
"""Логика ИИ: ракетка следует за мячом с задержкой"""
if ball.centerx > WIDTH/2: # Реагируем только на мяч, приближающийся к ИИ
if paddle.centery < ball.centery:
paddle.y += min(7 * AI_SPEED, ball.centery - paddle.centery)
elif paddle.centery > ball.centery:
paddle.y -= min(7 * AI_SPEED, paddle.centery - ball.centery)
# Ограничение границ экрана
paddle.y = max(0, min(HEIGHT - PADDLE_HEIGHT, paddle.y))
def calculate_ball_angle(contact_point, paddle_center):
"""Рассчитывает угол отскока мяча в зависимости от точки контакта"""
contact_diff = contact_point - paddle_center
angle_factor = contact_diff / (PADDLE_HEIGHT/2) # От -1 до +1
# Более резкий угол для ударов по краям ракетки
return angle_factor * 0.5 # 0.5 - коэффициент максимального изменения угла
# Основной цикл игры
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if not game_state["show_win_screen"]:
# Обработка управления
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and game_state["player_paddle"].top > 0:
game_state["player_paddle"].y -= 7
if keys[pygame.K_s] and game_state["player_paddle"].bottom < HEIGHT:
game_state["player_paddle"].y += 7
# Движение мяча
game_state["ball"].x += game_state["ball_speed_x"]
game_state["ball"].y += game_state["ball_speed_y"]
# Отскок от стен
if game_state["ball"].top <= 0 or game_state["ball"].bottom >= HEIGHT:
game_state["ball_speed_y"] *= -1
# Проверка на гол
if game_state["ball"].left <= 0:
game_state["ai_score"] += 1
# Проверка условий победы после гола
if game_state["ai_score"] == WINNING_SCORE:
if game_state["player_score"] == WINNING_SCORE - 1:
game_state["tie_break_active"] = True
elif game_state["player_score"] <= WINNING_SCORE - 2:
game_state["win_message"] = "КОМПЬЮТЕР ПОБЕДИЛ!"
game_state["show_win_screen"] = True
game_state["game_over"] = True
game_state["restart_timer"] = pygame.time.get_ticks() + 1000
# Проверка условий победы в тай-брейке
if game_state["tie_break_active"] and abs(game_state["ai_score"] - game_state["player_score"]) >= TIE_BREAK_REQUIRED_DIFFERENCE:
game_state["win_message"] = "КОМПЬЮТЕР ПОБЕДИЛ!"
game_state["show_win_screen"] = True
game_state["game_over"] = True
game_state["restart_timer"] = pygame.time.get_ticks() + 1000
game_state["ball"].center = (WIDTH//2, HEIGHT//2)
game_state["ball_speed_x"] = 5
game_state["ball_speed_y"] = 5 * random.choice([-1, 1])
pygame.time.delay(500)
elif game_state["ball"].right >= WIDTH:
game_state["player_score"] += 1
# Проверка условий победы после гола
if game_state["player_score"] == WINNING_SCORE:
if game_state["ai_score"] == WINNING_SCORE - 1:
game_state["tie_break_active"] = True
elif game_state["ai_score"] <= WINNING_SCORE - 2:
game_state["win_message"] = "ТЫ ПОБЕДИЛ!"
game_state["show_win_screen"] = True
game_state["game_over"] = True
game_state["restart_timer"] = pygame.time.get_ticks() + 1000
# Проверка условий победы в тай-брейке
if game_state["tie_break_active"] and abs(game_state["player_score"] - game_state["ai_score"]) >= TIE_BREAK_REQUIRED_DIFFERENCE:
game_state["win_message"] = "ТЫ ПОБЕДИЛ!"
game_state["show_win_screen"] = True
game_state["game_over"] = True
game_state["restart_timer"] = pygame.time.get_ticks() + 1000
game_state["ball"].center = (WIDTH//2, HEIGHT//2)
game_state["ball_speed_x"] = -5
game_state["ball_speed_y"] = 5 * random.choice([-1, 1])
pygame.time.delay(500)
# Отскок от ракеток с учётом угла
if game_state["ball"].colliderect(game_state["player_paddle"]):
contact_point = game_state["ball"].centery
paddle_center = game_state["player_paddle"].centery
angle_change = calculate_ball_angle(contact_point, paddle_center)
game_state["ball_speed_y"] += angle_change
game_state["ball_speed_x"] *= -1.1
elif game_state["ball"].colliderect(game_state["ai_paddle"]):
contact_point = game_state["ball"].centery
paddle_center = game_state["ai_paddle"].centery
angle_change = calculate_ball_angle(contact_point, paddle_center)
game_state["ball_speed_y"] += angle_change
game_state["ball_speed_x"] *= -1.1
# Обновление позиции ИИ
if not game_state["game_over"]:
move_ai_paddle(game_state["ai_paddle"], game_state["ball"])
# Обработка события нажатия клавиши для перезапуска
if game_state["show_win_screen"]:
keys = pygame.key.get_pressed()
if any(keys): # Любая клавиша
game_state = reset_game()
# Отрисовка
screen.fill((0, 0, 0))
if not game_state["show_win_screen"]:
# Отображение счета
score_text = score_font.render(f"{game_state['player_score']} {game_state['ai_score']}", True, WHITE)
screen.blit(score_text, (WIDTH//2 - 50, 10))
# Текст тай-брейка
if game_state["tie_break_active"]:
tie_text = score_font.render("TIE BREAK!", True, WHITE)
screen.blit(tie_text, (WIDTH//2 - 100, HEIGHT//2))
# Основные элементы игры
pygame.draw.rect(screen, WHITE, game_state["player_paddle"])
pygame.draw.rect(screen, WHITE, game_state["ai_paddle"])
pygame.draw.ellipse(screen, WHITE, game_state["ball"])
pygame.draw.aaline(screen, WHITE, (WIDTH//2, 0), (WIDTH//2, HEIGHT))
else:
# Экран победы
win_text = win_font.render(game_state["win_message"], True, WHITE)
text_rect = win_text.get_rect(center=(WIDTH//2, HEIGHT//2))
screen.blit(win_text, text_rect)
pygame.display.flip()
clock.tick(FPS)