import pygame import sys import json import os import random pygame.init() # Screen setup WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("2D Fallout Adventure") # Clock clock = pygame.time.Clock() FPS = 60 # Game state current_area = "safe_zone" dialogue_index = 0 current_npc = None player_xp = 0 player_level = 1 player_hp = 100 player_perks = [] caps = 0 quest_log = {} # Load images def load_image(name): return pygame.image.load(os.path.join("assets", name)).convert_alpha() backgrounds = { "safe_zone": pygame.transform.scale(load_image("bg_easteland.jpg"), (WIDTH, HEIGHT)), "wasteland": pygame.transform.scale(load_image("bg_wasteland.jpg"), (WIDTH, HEIGHT)), "city": pygame.transform.scale(load_image("bg_easteland.jpg"), (WIDTH, HEIGHT)), "ruins": pygame.transform.scale(load_image("bg_ruins.jpg"), (WIDTH, HEIGHT)), "vault": pygame.transform.scale(load_image("bg_vault.jpg"), (WIDTH, HEIGHT)), "highway": pygame.transform.scale(load_image("bg_highway.jpg"), (WIDTH, HEIGHT)) } player_img = load_image("player.png") enemy_img = load_image("enemy.png") mutant_img = load_image("mutant.png") robot_img = load_image("robot.png") bullet_img = load_image("bullet.png") elder_img = load_image("elder.png") # Save/load functions def save_game(): with open("save.json", "w") as f: json.dump({ "area": current_area, "xp": player_xp, "level": player_level, "hp": player_hp, "perks": player_perks, "caps": caps, "quests": quest_log }, f) def load_game(): global current_area, player_xp, player_level, player_hp, player_perks, caps, quest_log try: with open("save.json", "r") as f: data = json.load(f) current_area = data.get("area", "safe_zone") player_xp = data.get("xp", 0) player_level = data.get("level", 1) player_hp = data.get("hp", 100) player_perks = data.get("perks", []) caps = data.get("caps", 0) quest_log = data.get("quests", {}) except: pass player = pygame.Rect(100, 300, 50, 60) bullets = [] enemies = { "wasteland": {"rect": pygame.Rect(600, 300, 50, 60), "hp": 30, "image": enemy_img}, "ruins": {"rect": pygame.Rect(600, 300, 50, 60), "hp": 50, "image": mutant_img}, "vault": {"rect": pygame.Rect(600, 300, 50, 60), "hp": 70, "image": robot_img}, "highway": {"rect": pygame.Rect(600, 300, 50, 60), "hp": 40, "image": enemy_img} } npcs = { "safe_zone": { "elder": { "rect": pygame.Rect(200, 400, 50, 60), "image": elder_img, "dialogue": [ "You're finally awake. The world has changed...", "The city holds the key to rebuilding civilization.", "Seek allies, defeat raiders, and rebuild." ] }, "trader": { "rect": pygame.Rect(400, 200, 50, 60), "image": elder_img, "dialogue": [ "I've got supplies and tips. Invest wisely!", "Sharpshooter helps with combat. Medic helps with healing." ] } }, "wasteland": { "scavenger": { "rect": pygame.Rect(500, 150, 50, 60), "image": elder_img, "dialogue": [ "I found tech ruins to the east.", "Maybe they hide something important..." ] } } } areas = ["safe_zone", "wasteland", "city", "ruins", "vault", "highway"] area_index = areas.index(current_area) def switch_area(direction): global area_index, current_area, player if direction == "left" and area_index > 0: area_index -= 1 elif direction == "right" and area_index < len(areas) - 1: area_index += 1 current_area = areas[area_index] player.x = 100 if direction == "right" else WIDTH - 100 def grant_perk(): if player_level == 2 and "Sharpshooter" not in player_perks: player_perks.append("Sharpshooter") elif player_level == 3 and "Medic" not in player_perks: player_perks.append("Medic") load_game() running = True while running: clock.tick(FPS) screen.blit(backgrounds[current_area], (0, 0)) keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player.x -= 5 if keys[pygame.K_RIGHT]: player.x += 5 if player.x <= 0: switch_area("left") elif player.x + player.width >= WIDTH: switch_area("right") for event in pygame.event.get(): if event.type == pygame.QUIT: save_game() running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE and not current_npc: bullets.append(pygame.Rect(player.centerx, player.top, 10, 10)) if event.key == pygame.K_e and current_npc: dialogue_index += 1 if dialogue_index >= len(npcs[current_area][current_npc]["dialogue"]): dialogue_index = 0 current_npc = None for bullet in bullets[:]: bullet.x += 10 if current_area in enemies and bullet.colliderect(enemies[current_area]["rect"]): bullets.remove(bullet) damage = 15 if "Sharpshooter" in player_perks else 10 enemies[current_area]["hp"] -= damage if enemies[current_area]["hp"] <= 0: enemies[current_area]["hp"] = 30 enemies[current_area]["rect"].x = random.randint(500, 750) player_xp += 20 caps += random.randint(5, 15) if player_xp >= 100: player_level += 1 player_xp = 0 grant_perk() elif bullet.x > WIDTH: bullets.remove(bullet) screen.blit(player_img, player.topleft) if current_area in enemies: screen.blit(enemies[current_area]["image"], enemies[current_area]["rect"].topleft) for bullet in bullets: screen.blit(bullet_img, bullet.topleft) current_npc = None if current_area in npcs: for name, npc in npcs[current_area].items(): screen.blit(npc["image"], npc["rect"].topleft) if player.colliderect(npc["rect"]): current_npc = name if current_npc: font = pygame.font.SysFont(None, 24) dialogue_text = font.render(npcs[current_area][current_npc]["dialogue"][dialogue_index], True, (255, 255, 255)) screen.blit(dialogue_text, (player.x, player.y - 30)) font = pygame.font.SysFont(None, 24) hud = font.render(f"HP: {player_hp} XP: {player_xp}/100 LVL: {player_level} Perks: {', '.join(player_perks)} Caps: {caps}", True, (255, 255, 0)) screen.blit(hud, (10, 10)) pygame.display.flip() pygame.quit() sys.exit()