https://pastein.ru/t/lAt

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

Загрузка данных


- Валерка же -

Сайт:https://trinket.io/pygame
Код:

import pygame
import random
import math
import time
import json  # Для сохранения счета и инвентаря

# Инициализация Pygame
pygame.init()

# Константы
WIDTH, HEIGHT = 800, 600
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
ORANGE = (255, 165, 0)
GREEN = (0, 255, 0)
GRAY = (128, 128, 128)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
BROWN = (139, 69, 19)
PINK = (255, 0, 255)  # Настоящий розовый!

# Размеры мяча и кольца
BALL_RADIUS = 25
HOOP_WIDTH = 20
HOOP_HEIGHT = 60
HOOP_STAND_HEIGHT = 20

# Параметры броска
POWER_SCALE = 20

# Сообщения после попадания
POSITIVE_MESSAGES = ["Хорошо!", "Отлично!", "Прекрасно!", "Точно в цель!", "Браво!"]
show_message = False
current_message = ""
message_start_time = 0
message_alpha = 0
message_y_offset = 0

# Скины мяча
DEFAULT_SKIN = ORANGE
BLACK_SKIN = BLACK
PINK_SKIN = PINK
SKIN_PRICES = {BLACK_SKIN: 10, PINK_SKIN: 20}

# Магазин
current_skin = DEFAULT_SKIN
inventory = {DEFAULT_SKIN: True, BLACK_SKIN: False, PINK_SKIN: False}

# Переменные для состояния игры
GAME_STATE_MENU = 0
GAME_STATE_PLAYING = 1
GAME_STATE_SHOP = 2
game_state = GAME_STATE_MENU

# Имя файла для сохранения данных
SAVE_FILE = "save_data.json"

# Загрузка сохраненных данных
try:
    with open(SAVE_FILE, "r") as f:
        save_data = json.load(f)
        score = save_data["score"]
        inventory = save_data["inventory"]
        current_skin = save_data["current_skin"]  # загружаем текущий скин
except (FileNotFoundError, json.JSONDecodeError):
    score = 0
    print("Сохраненные данные не найдены или повреждены. Начинаем новую игру.")

# Классы
class Ball(pygame.sprite.Sprite):
    def __init__(self, x, y, skin_color):
        super().__init__()
        self.radius = BALL_RADIUS
        self.skin_color = skin_color
        self.update_image()
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)
        self.x = x
        self.y = y
        self.x_speed = 0
        self.y_speed = 0
        self.gravity = 0.5
        self.bouncing = -0.7
        self.trail = []
        self.rotation = 0
        self.rotation_speed = 2

    def update_image(self):
        self.image = pygame.Surface([self.radius * 2, self.radius * 2], pygame.SRCALPHA)
        pygame.draw.circle(self.image, self.skin_color, (self.radius, self.radius), self.radius)
        line_color = RED
        line_width = 3
        rect_top = (0, 0, self.radius * 2, self.radius * 2)
        pygame.draw.arc(self.image, line_color, rect_top, math.radians(0), math.radians(180), line_width)
        pygame.draw.arc(self.image, line_color, rect_top, math.radians(180), math.radians(360), line_width)
        pygame.draw.line(self.image, line_color, (0, self.radius), (self.radius * 2, self.radius), line_width)

    def update(self):
        self.y_speed += self.gravity
        self.x += self.x_speed
        self.y += self.y_speed
        self.rect.center = (int(self.x), int(self.y))

        if self.rect.bottom >= HEIGHT:
            self.y_speed *= self.bouncing
            self.rect.bottom = HEIGHT
            self.y = self.rect.center[1]

        if self.rect.left < 0:
            self.rect.left = 0
            self.x = self.rect.center[0]
            self.x_speed *= -0.5

        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
            self.x = self.rect.center[0]
            self.x_speed *= -0.5

        if self.rect.top < 0:
            self.rect.top = 0
            self.y = self.rect.center[1]
            self.y_speed *= -0.5

        self.trail.append(self.rect.center)
        if len(self.trail) > 50:
            self.trail.pop(0)

        self.rotation = (self.rotation + self.rotation_speed) % 360

    def shoot(self, x_speed, y_speed):
        self.x_speed = x_speed
        self.y_speed = y_speed
        self.trail = []

    def draw_trail(self, surface):
        if len(self.trail) > 1:
            pygame.draw.lines(surface, WHITE, False, self.trail, 2)

    def set_skin(self, skin_color):
        self.skin_color = skin_color
        self.update_image()
        self.rect = self.image.get_rect(center=self.rect.center)

    def draw(self, surface):
        rotated_image = pygame.transform.rotate(self.image, self.rotation)
        new_rect = rotated_image.get_rect(center=self.rect.center)
        surface.blit(rotated_image, new_rect.topleft)

class Hoop(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.width = HOOP_WIDTH
        self.height = HOOP_HEIGHT
        self.stand_height = HOOP_STAND_HEIGHT

        self.image = pygame.Surface([self.width, self.height + self.stand_height], pygame.SRCALPHA)
        pygame.draw.rect(self.image, RED, (0, 0, self.width, self.height), 3)
        pygame.draw.rect(self.image, WHITE, (0, self.height, self.width, self.stand_height))

        self.rect = self.image.get_rect()
        self.rect.center = (x, y)

class Particle(pygame.sprite.Sprite):
    def __init__(self, x, y, color):
        super().__init__()
        self.radius = random.randint(2, 5)
        self.image = pygame.Surface([self.radius * 2, self.radius * 2], pygame.SRCALPHA)
        pygame.draw.circle(self.image, color, (self.radius, self.radius), self.radius)
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)
        self.x = x
        self.y = y
        self.x_speed = random.uniform(-3, 3)
        self.y_speed = random.uniform(-3, 3)
        self.gravity = 0.1
        self.lifetime = random.randint(30, 60)

    def update(self):
        self.y_speed += self.gravity
        self.x += self.x_speed
        self.y += self.y_speed
        self.rect.center = (int(self.x), int(self.y))
        self.lifetime -= 1
        if self.lifetime <= 0:
            self.kill()

# Создание окна
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Basketball Game")

# Создаем шрифт
font = pygame.font.Font(None, 36)
title_font = pygame.font.SysFont("Arial", 72)
button_font = pygame.font.SysFont("Verdana", 48)
small_font = pygame.font.SysFont("Tahoma", 24)

# Рисуем баскетбольную площадку
def draw_court(surface):
    surface.fill(BROWN)
    pygame.draw.rect(surface, WHITE, (50, 50, WIDTH - 100, HEIGHT - 100), 2)
    pygame.draw.line(surface, WHITE, (WIDTH // 2, 50), (WIDTH // 2, HEIGHT - 50), 2)
    pygame.draw.circle(surface, WHITE, (WIDTH // 2, HEIGHT // 2), 50, 2)
    pygame.draw.rect(surface, RED, (50, HEIGHT // 3, 150, HEIGHT // 3), 2)
    pygame.draw.rect(surface, RED, (WIDTH - 200, HEIGHT // 3, 150, HEIGHT // 3), 2)

# Создаем баскетбольную площадку как поверхность
court_surface = pygame.Surface((WIDTH, HEIGHT))
draw_court(court_surface)

# Создание спрайтов (инициализация будет зависеть от состояния игры)
ball = None
hoop = None
all_sprites = pygame.sprite.Group()

# Линия прицеливания
aim_line = []
drawing_aim = False

# Фейерверки
fireworks = pygame.sprite.Group()
show_fireworks = False
fireworks_start_time = 0

# Кнопки главного меню
button_width = 250
button_height = 60
play_button_rect = pygame.Rect(WIDTH // 2 - button_width // 2, HEIGHT // 3, button_width, button_height)
shop_button_rect = pygame.Rect(WIDTH // 2 - button_width // 2, HEIGHT // 3 + button_height + 30, button_width, button_height)
quit_button_rect = pygame.Rect(WIDTH // 2 - button_width // 2, HEIGHT // 3 + 2 * (button_height + 30), button_width, button_height)

# Кнопка "В меню" во время игры
menu_button_rect = pygame.Rect(WIDTH - 160, 10, 150, 40)

def draw_text(surface, text, color, x, y, font_obj=font, alpha=255, shadow=False):
    if shadow:
        shadow_color = BLACK
        shadow_offset = 2
        shadow_surface = font_obj.render(text, True, shadow_color)
        shadow_rect = shadow_surface.get_rect(center=(x + shadow_offset, y + shadow_offset))
        surface.blit(shadow_surface, shadow_rect)

    text_surface = font_obj.render(text, True, color)
    text_surface.set_alpha(alpha)
    text_rect = text_surface.get_rect()
    text_rect.center = (x, y)
    surface.blit(text_surface, text_rect)

def calculate_aim_line(start_pos, end_pos, steps=20):
    x0, y0 = start_pos
    x1, y1 = end_pos
    dx = (x1 - x0) / steps
    dy = (y1 - y0) / steps
    points = []
    x, y = x0, y0
    x_speed = (x1 - x0) / POWER_SCALE
    y_speed = (y1 - y0) / POWER_SCALE

    for _ in range(steps):
        y_speed += ball.gravity

        x += x_speed
        y += y_speed

        if y > HEIGHT:
            y_speed *= ball.bouncing
            y = HEIGHT
        if x < 0:
            x_speed *= -1
            x = 0
        if x > WIDTH:
            x_speed *= -1
            x = WIDTH
        points.append((x, y))

    return points

def create_fireworks(x, y):
    num_particles = 50
    for _ in range(num_particles):
        color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        particle = Particle(x, y, color)
        fireworks.add(particle)
        all_sprites.add(particle)

def draw_menu(surface):
    surface.fill(BLACK)
    draw_text(surface, "Basketball Game", WHITE, WIDTH // 2, HEIGHT // 4 - 50, title_font, shadow=True)
    button_color = (50, 50, 50)
    button_hover_color = (100, 100, 100)

    for rect, text, color in [(play_button_rect, "Играть", GREEN), (shop_button_rect, "Магазин", BLUE), (quit_button_rect, "Выход", RED)]:
        if rect.collidepoint(pygame.mouse.get_pos()):
            current_color = button_hover_color
        else:
            current_color = button_color

        pygame.draw.rect(surface, current_color, rect)
        pygame.draw.rect(surface, color, rect, 3)
        draw_text(surface, text, WHITE, rect.centerx, rect.centery, button_font, shadow=True)
    draw_text(surface, "Сделано с любовью", WHITE, WIDTH // 2, HEIGHT - 30, small_font, shadow=True)

def draw_shop(surface):
    shop_rect = pygame.Rect(WIDTH // 4, HEIGHT // 4, WIDTH // 2, HEIGHT // 2)
    pygame.draw.rect(surface, GRAY, shop_rect)

    skin_button_width = 50
    skin_button_height = 50
    buy_button_width = 80
    buy_button_height = 30
    button_spacing = 20

    start_x = WIDTH // 4 + button_spacing
    start_y = HEIGHT // 4 + button_spacing

    skin1_rect = pygame.Rect(start_x, start_y, skin_button_width, skin_button_height)
    pygame.draw.rect(surface, ORANGE, skin1_rect)

    skin2_rect = pygame.Rect(start_x + skin_button_width + button_spacing, start_y, skin_button_width, skin_button_height)
    pygame.draw.rect(surface, BLACK, skin2_rect)

    skin3_rect = pygame.Rect(start_x + 2 * (skin_button_width + button_spacing), start_y, skin_button_width, skin_button_height)
    pygame.draw.rect(surface, PINK, skin3_rect)

    buy_button1_rect = pygame.Rect(start_x + skin_button_width + button_spacing, start_y + skin_button_height + 10, buy_button_width, buy_button_height)
    price_black = SKIN_PRICES[BLACK_SKIN]
    draw_text(surface, f"{price_black} очков", WHITE, start_x + skin_button_width + button_spacing + skin_button_width // 2, start_y - 20)
    if not inventory[BLACK_SKIN]:
        pygame.draw.rect(surface, GREEN, buy_button1_rect)
        draw_text(surface, "Купить", WHITE, start_x + skin_button_width + button_spacing + buy_button_width // 2, start_y + skin_button_height + 10 + buy_button_height // 2, font)
    else:
        draw_text(surface, "Куплено", GREEN, start_x + skin_button_width + button_spacing + buy_button_width // 2, start_y + skin_button_height + 10 + buy_button_height // 2, font)

    buy_button2_rect = pygame.Rect(start_x + 2 * (skin_button_width + button_spacing), start_y + skin_button_height + 10, buy_button_width, buy_button_height)
    price_pink = SKIN_PRICES[PINK_SKIN]
    draw_text(surface, f"{price_pink} очков", WHITE, start_x + 2 * (skin_button_width + button_spacing) + skin_button_width // 2, start_y - 20)
    if not inventory[PINK_SKIN]:
        pygame.draw.rect(surface, GREEN, buy_button2_rect)
        draw_text(surface, "Купить", WHITE, start_x + 2 * (skin_button_width + button_spacing) + buy_button_width // 2, start_y + skin_button_height + 10 + buy_button_height // 2, font)
    else:
        draw_text(surface, "Куплено", GREEN, start_x + 2 * (skin_button_width + button_spacing) + buy_button_width // 2, start_y + skin_button_height + 10 + buy_button_height // 2, font)

    back_button_rect = pygame.Rect(WIDTH // 2 - 75, HEIGHT - 80, 150, 40)
    pygame.draw.rect(surface, BLUE, back_button_rect)
    draw_text(surface, "Назад в меню", WHITE, WIDTH // 2, HEIGHT - 60, font)

    return {
        BLACK_SKIN: buy_button1_rect,
        PINK_SKIN: buy_button2_rect,
        "back": back_button_rect
    }

def save_game_data():
    save_data = {
        "score": score,
        "inventory": inventory,
        "current_skin": current_skin
    }
    with open(SAVE_FILE, "w") as f:
        json.dump(save_data, f)
    print("Игра сохранена")

# Игровой цикл
running = True
clock = pygame.time.Clock()

while running:
    clock.tick(FPS)

    mouse_pos = pygame.mouse.get_pos()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            save_game_data()
        if event.type == pygame.MOUSEBUTTONDOWN:
            if game_state == GAME_STATE_MENU:
                if play_button_rect.collidepoint(mouse_pos):
                    game_state = GAME_STATE_PLAYING
                    ball = Ball(WIDTH // 4, HEIGHT - 50, current_skin)
                    hoop = Hoop(WIDTH * 3 // 4, HEIGHT * 0.6)
                    all_sprites = pygame.sprite.Group()
                    all_sprites.add(ball)
                    all_sprites.add(hoop)
                    aim_line = []
                    drawing_aim = False
                    fireworks = pygame.sprite.Group()
                    show_fireworks = False
                    fireworks_start_time = 0
                    show_message = False
                    current_message = ""
                    message_start_time = 0
                    message_alpha = 0
                    message_y_offset = 0
                if shop_button_rect.collidepoint(mouse_pos):
                    game_state = GAME_STATE_SHOP
                if quit_button_rect.collidepoint(mouse_pos):
                    running = False
                    save_game_data()
            elif game_state == GAME_STATE_SHOP:
                shop_buttons = draw_shop(screen)
                for skin, rect in shop_buttons.items():
                    if skin == "back":
                        if rect.collidepoint(mouse_pos):
                            game_state = GAME_STATE_MENU
                            break
                    elif rect.collidepoint(mouse_pos):
                        price = SKIN_PRICES[skin]
                        if score >= price and not inventory[skin]:
                            score -= price
                            inventory[skin] = True
                            current_skin = skin
                            if ball:
                                ball.set_skin(current_skin)
                            break
            elif game_state == GAME_STATE_PLAYING:
                if menu_button_rect.collidepoint(mouse_pos):
                    game_state = GAME_STATE_MENU
                    ball = None
                    hoop = None
                    all_sprites = pygame.sprite.Group()
                if event.button == 1:
                    drawing_aim = True
                    start_x, start_y = event.pos

        if event.type == pygame.MOUSEBUTTONUP:
            if game_state == GAME_STATE_PLAYING:
                if drawing_aim:
                    drawing_aim = False
                    end_x, end_y = pygame.mouse.get_pos()
                    dx = end_x - ball.rect.centerx
                    dy = end_y - ball.rect.centery
                    x_speed = dx / POWER_SCALE
                    y_speed = dy / POWER_SCALE
                    ball.shoot(x_speed, y_speed * -1)

    # Обновление
    if game_state == GAME_STATE_PLAYING:
        all_sprites.update()
        fireworks.update()

        if drawing_aim:
            end_x, end_y = pygame.mouse.get_pos()
            aim_line = calculate_aim_line(ball.rect.center, (end_x, end_y))
        else:
            aim_line = []

        hoop_rect_top = pygame.Rect(hoop.rect.left, hoop.rect.top, hoop.rect.width, HOOP_HEIGHT)
        if pygame.sprite.collide_rect(ball, hoop):
            if ball.rect.centery < hoop_rect_top.bottom:
                score += 1
                create_fireworks(hoop.rect.centerx, hoop.rect.top)
                show_fireworks = True
                fireworks_start_time = time.time()
                current_message = random.choice(POSITIVE_MESSAGES)
                show_message = True
                message_start_time = time.time()
                message_alpha = 0
                message_y_offset = 0
                hoop.rect.center = (random.randint(100, WIDTH - 100), random.randint(HEIGHT // 4, HEIGHT // 2))

        if show_message:
            if message_alpha < 255:
                message_alpha += 5
            message_y_offset -= 1
            if time.time() - message_start_time > 2:
                show_message = False

        if show_fireworks and time.time() - fireworks_start_time > 3:
            show_fireworks = False
            fireworks = pygame.sprite.Group()

    # Рендеринг
    if game_state == GAME_STATE_MENU:
        draw_menu(screen)
    elif game_state == GAME_STATE_SHOP:
        draw_shop(screen)
    elif game_state == GAME_STATE_PLAYING:
        screen.blit(court_surface, (0, 0))
        if aim_line:
            pygame.draw.lines(screen, GRAY, False, aim_line, 2)

        if ball:
            ball.draw(screen)

        ball.draw_trail(screen)
        all_sprites.draw(screen)

        pygame.draw.rect(screen, GRAY, menu_button_rect)
        draw_text(screen, "В меню", WHITE, menu_button_rect.centerx, menu_button_rect.centery, font)

        if show_message:
            draw_text(screen, current_message, GREEN, WIDTH // 2, HEIGHT // 4 + message_y_offset, font)
        draw_text(screen, f"Score: {score}", WHITE, 100, 30, font)

    pygame.display.flip()

pygame.quit()