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()