| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- import pygame
- import random
- # --- Константы ---
- WIDTH, HEIGHT = 1000, 750
- WHITE = (240, 240, 240)
- BLACK = (20, 20, 20)
- PANEL_COLOR = (44, 62, 80)
- ACCENT = (52, 152, 219)
- DISABLED = (127, 140, 141)
- DANGER = (231, 76, 60)
- SUCCESS = (46, 204, 113)
- GOLD = (241, 196, 15)
- PURPLE = (155, 89, 182)
- class FloatingText:
- def __init__(self, text, x, y, color):
- self.text = text
- self.x = x
- self.y = y
- self.color = color
- self.alpha = 255
- self.life = 60
- def update(self):
- self.y -= 1
- self.alpha -= 4
- self.life -= 1
- def draw(self, screen, font):
- if self.life > 0:
- surf = font.render(self.text, True, self.color)
- surf.set_alpha(max(0, self.alpha))
- screen.blit(surf, (self.x, self.y))
- class UltimateAdminGame:
- def __init__(self):
- pygame.init()
- self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
- pygame.display.set_caption("Администратор: Высшая Лига 2.0")
- self.clock = pygame.time.Clock()
-
- # Шрифты
- self.font_main = pygame.font.SysFont('Segoe UI', 19)
- self.font_bold = pygame.font.SysFont('Segoe UI', 24, bold=True)
- self.font_title = pygame.font.SysFont('Segoe UI', 32, bold=True)
-
- # Состояние игры
- self.reset_game()
- def reset_game(self):
- """Полный сброс всех параметров (для кнопки R)"""
- self.day = 1
- self.hour = 9
- self.week = 1
- self.stats = {"Репутация": 70, "Бюджет": 200, "Стресс": 0}
- self.display_stats = {k: float(v) for k, v in self.stats.items()}
-
- # Новинка: Система навыков (случайный бонус при старте)
- self.perk = random.choice(["Экономный", "Стрессоустойчивый", "Любимчик"])
- if self.perk == "Экономный": self.stats["Бюджет"] += 50
- if self.perk == "Любимчик": self.stats["Репутация"] += 30
- self.logs = [f"Старт: Ваша особенность — '{self.perk}'", "Понедельник. Пора разгребать завалы."]
- self.floating_texts = []
- self.current_event = None
- self.game_over = False
- self.victory = False
-
- # Расширенный пул событий
- self.events_pool = [
- {"title": "Кофемашина взорвалась", "desc": ["Весь пол в липком латте.", "Сотрудники в панике без кофеина."], "options": [{"text": "Вызвать мастера (-25 Бюджет, -1ч)", "cost": 25, "mod": (5, -25, -5), "time": 1}, {"text": "Купить растворимый кофе (-5 Бюджет, -1ч)", "cost": 5, "mod": (-10, -5, 5), "time": 1}, {"text": "Заставить всех работать так (-2ч)", "cost": 0, "mod": (-15, 0, 20), "time": 2}]},
- {"title": "Вирусная атака", "desc": ["Бухгалтерия открыла письмо 'Ваш выигрыш'.", "Шифровальщик заблокировал сеть!"], "options": [{"text": "Заплатить хакерам (-60 Бюджет, -1ч)", "cost": 60, "mod": (0, -60, 15), "time": 1}, {"text": "Откатить систему (-4ч)", "cost": 0, "mod": (25, 0, 35), "time": 4}, {"text": "Изолировать сервер (-2ч)", "cost": 0, "mod": (-10, 0, 20), "time": 2}]},
- {"title": "Визит инвестора", "desc": ["Важный гость приехал без предупреждения.", "Нужно произвести впечатление."], "options": [{"text": "Устроить фуршет (-40 Бюджет, -2ч)", "cost": 40, "mod": (35, -40, 10), "time": 2}, {"text": "Провести презентацию (-3ч)", "cost": 0, "mod": (20, 0, 45), "time": 3}, {"text": "Делегировать помощнику (-1ч)", "cost": 0, "mod": (5, 0, -5), "time": 1}]},
- {"title": "Налоговая проверка", "desc": ["Инспектор требует документы за прошлый год.", "Кажется, мы что-то потеряли."], "options": [{"text": "Договориться на месте (-50 Бюджет)", "cost": 50, "mod": (-10, -50, 15), "time": 1}, {"text": "Искать архивы всю ночь (+40 Стресс)", "cost": 0, "mod": (30, 0, 40), "time": 4}, {"text": "Свалить на бухгалтера (-20 Репутация)", "cost": 0, "mod": (-20, 0, 10), "time": 2}]},
- {"title": "Корпоратив", "desc": ["Пятница! Команда хочет расслабиться.", "От этого зависит климат в офисе."], "options": [{"text": "Заказать пиццу (-15 Бюджет)", "cost": 15, "mod": (10, -15, -10), "time": 1}, {"text": "Снять караоке-бар (-45 Бюджет)", "cost": 45, "mod": (35, -45, -30), "time": 3}, {"text": "Работать сверхурочно (+30 Стресс)", "cost": 0, "mod": (-20, 10, 30), "time": 2}]},
- {"title": "Протечка крыши", "desc": ["Вода капает прямо на серверную стойку!", "Срочно нужны тазы или ремонт."], "options": [{"text": "Вызвать кровельщиков (-35 Бюджет)", "cost": 35, "mod": (10, -35, 5), "time": 1}, {"text": "Героически спасать железо (-4ч)", "cost": 0, "mod": (20, 0, 45), "time": 4}, {"text": "Ничего не делать (Риск!)", "cost": 0, "mod": (-40, -50, 20), "time": 2}]}
- ]
- self.pick_event()
- def pick_event(self):
- if not self.game_over and not self.victory:
- self.current_event = random.choice(self.events_pool)
- def create_floating(self, mod):
- r, b, s = mod
- pos_y = [180, 260, 340]
- changes = [r, b, s]
- for i, val in enumerate(changes):
- if val != 0:
- color = SUCCESS if val > 0 else DANGER
- if i == 2: color = DANGER if val > 0 else SUCCESS # Для стресса наоборот
- sign = "+" if val > 0 else ""
- self.floating_texts.append(FloatingText(f"{sign}{val}", 220, pos_y[i], color))
- def handle_choice(self, option):
- if self.stats["Бюджет"] >= option["cost"]:
- # Применение перков
- s_mod = option["mod"][2]
- if self.perk == "Стрессоустойчивый" and s_mod > 0: s_mod = int(s_mod * 0.7)
-
- self.create_floating((option["mod"][0], option["mod"][1], s_mod))
-
- self.stats["Репутация"] += option["mod"][0]
- self.stats["Бюджет"] += option["mod"][1]
- self.stats["Стресс"] += s_mod
- self.hour += option["time"]
-
- self.logs.append(f"{self.hour-option['time']}:00 - {option['text'].split(' (')[0]}")
-
- if self.hour >= 18:
- self.day += 1
- self.hour = 9
- self.stats["Стресс"] = max(0, self.stats["Стресс"] - 30)
- self.logs.append(f"--- День {self.day}. Ночной отдых -30 Стресс ---")
-
- if self.day > 5: # Конец рабочей недели
- self.day = 1
- self.week += 1
- self.stats["Бюджет"] += 150
- self.logs.append(f"*** Неделя {self.week}! Получен бюджет +150 ***")
-
- if self.week > 4: self.victory = True
- self.pick_event()
- self.check_game_over()
- def check_game_over(self):
- if self.stats["Репутация"] <= 0 or self.stats["Бюджет"] <= 0 or self.stats["Стресс"] >= 180:
- self.game_over = True
- def update_animations(self):
- for key in self.stats:
- diff = self.stats[key] - self.display_stats[key]
- self.display_stats[key] += diff * 0.1
- for ft in self.floating_texts[:]:
- ft.update()
- if ft.life <= 0: self.floating_texts.remove(ft)
- def draw_ui(self):
- self.screen.fill(WHITE)
- # Боковая панель
- pygame.draw.rect(self.screen, PANEL_COLOR, (0, 0, 260, HEIGHT))
- self.draw_text(f"НЕДЕЛЯ {self.week}", 130, 45, GOLD, True, self.font_bold)
- self.draw_text(f"ДЕНЬ {self.day} | {self.hour}:00", 130, 90, WHITE, True, self.font_main)
- self.draw_text(f"Перк: {self.perk}", 130, 130, PURPLE, True, self.font_main)
-
- y = 200
- for key in ["Репутация", "Бюджет", "Стресс"]:
- val = self.display_stats[key]
- real_val = self.stats[key]
- color = SUCCESS if (key != "Стресс" and real_val > 40) or (key == "Стресс" and real_val < 100) else DANGER
- self.draw_text(f"{key}: {int(real_val)}", 35, y, WHITE, False, self.font_main)
- pygame.draw.rect(self.screen, (60, 80, 100), (35, y + 30, 190, 10), border_radius=5)
- pygame.draw.rect(self.screen, color, (35, y + 30, max(0, min(val, 190)), 10), border_radius=5)
- y += 80
- for ft in self.floating_texts: ft.draw(self.screen, self.font_bold)
- # Логи
- pygame.draw.rect(self.screen, (230, 230, 230), (280, 560, 700, 170), border_radius=15)
- for i, log in enumerate(self.logs[-5:]):
- self.draw_text(log, 300, 575 + (i*30), (100, 100, 100) if i < 4 else BLACK)
- # Событие
- if not self.game_over and not self.victory:
- pygame.draw.rect(self.screen, (255, 255, 255), (280, 20, 700, 520), border_radius=15)
- self.draw_text(self.current_event["title"], 630, 70, PANEL_COLOR, True, self.font_title)
- for i, line in enumerate(self.current_event["desc"]):
- self.draw_text(line, 630, 140 + (i*30), (80, 80, 80), True)
- for i, opt in enumerate(self.current_event["options"]):
- self.button(opt, 300 + (i*80))
- elif self.game_over: self.overlay("ВЫ УВОЛЕНЫ", DANGER)
- elif self.victory: self.overlay("ВЫ - ГЕНИЙ УПРАВЛЕНИЯ", SUCCESS)
- def overlay(self, txt, color):
- pygame.draw.rect(self.screen, WHITE, (350, 250, 550, 250), border_radius=20)
- self.draw_text(txt, 625, 330, color, True, self.font_title)
- self.draw_text("R - Начать заново | ESC - Выход", 625, 400, BLACK, True, self.font_main)
- def draw_text(self, text, x, y, color=BLACK, center=False, font=None):
- f = font if font else self.font_main
- surf = f.render(str(text), True, color)
- rect = surf.get_rect(center=(x, y) if center else (x, y))
- if not center: rect.topleft = (x, y)
- self.screen.blit(surf, rect)
- def button(self, option, y):
- mouse = pygame.mouse.get_pos()
- click = pygame.mouse.get_pressed()
- rect = pygame.Rect(355, y, 550, 65)
- afford = self.stats["Бюджет"] >= option["cost"]
- hover = rect.collidepoint(mouse) and afford
-
- color = ACCENT if hover else (DISABLED if not afford else (100, 110, 120))
- pygame.draw.rect(self.screen, color, rect, border_radius=12)
- self.draw_text(option["text"], rect.centerx, rect.centery, WHITE, True, self.font_bold)
-
- if hover and click[0]:
- pygame.time.delay(200)
- self.handle_choice(option)
- def run(self):
- running = True
- while running:
- for event in pygame.event.get():
- if event.type == pygame.QUIT: running = False
- if event.type == pygame.KEYDOWN:
- if event.key == pygame.K_ESCAPE: running = False
- if event.key == pygame.K_r: self.reset_game()
- self.update_animations()
- self.draw_ui()
- pygame.display.flip()
- self.clock.tick(60)
- pygame.quit()
- if __name__ == "__main__":
- UltimateAdminGame().run()
|