import pygame import sys import os import random # Initialize Pygame pygame.init() pygame.mixer.init() # Constants WHITE, BLACK, GRAY = (255, 255, 255), (0, 0, 0), (200, 200, 200) CLICK_SIZE = 450 FPS = 60 # Get screen size and set display WIDTH, HEIGHT = pygame.display.Info().current_w, pygame.display.Info().current_h screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.FULLSCREEN) pygame.display.set_caption("Clicker") # Get script directory script_dir = os.path.dirname(os.path.abspath(__file__)) # Asset loading helpers def get_asset_path(folder, filename): return os.path.join(script_dir, folder, filename) def load_image(folder, filename, scale=None): path = get_asset_path(folder, filename) if not os.path.isfile(path): sys.exit(f"Missing image: {path}") img = pygame.image.load(path) return pygame.transform.scale(img, scale) if scale else img def load_sound(folder, filename): path = get_asset_path(folder, filename) if not os.path.isfile(path): sys.exit(f"Missing sound: {path}") return pygame.mixer.Sound(path) def load_font(folder, filename, size): path = get_asset_path(folder, filename) if not os.path.isfile(path): sys.exit(f"Missing font: {path}") return pygame.font.Font(path, size) # Load assets click_sound = load_sound("sounds", "click_sound.mp3") title_font = load_font("fonts", "retro.ttf", 72) font = load_font("fonts", "retro.ttf", 36) game_font = load_font("fonts", "retro.ttf", 64) click_skins = ["cookie.png", "diamond.png", "star.png", "dvd.png"] click_images = [load_image("skins", skin, (CLICK_SIZE, CLICK_SIZE)) for skin in click_skins] current_skin_index = 0 click_image = click_images[current_skin_index] # Game state variables clicks = 0.0 clicks_per_click = 1 click_upgrade_cost = 10 clicks_per_second = 0 cps_upgrade_cost = 50 last_click_time = pygame.time.get_ticks() scale_factor = 1.0 # Upgrade settings CLICK_UPGRADE_COST_INCREMENT = 10 CLICK_BENEFIT_INCREMENT = 1 CPS_UPGRADE_COST_INCREMENT = 50 CPS_BENEFIT_INCREMENT = 1 # UI Elements click_rect = pygame.Rect(WIDTH // 2 - CLICK_SIZE // 2, HEIGHT // 2 - CLICK_SIZE // 2, CLICK_SIZE, CLICK_SIZE) submenu_text = game_font.render("Options", True, BLACK) submenu_rect = submenu_text.get_rect(topright=(WIDTH - 10, 10)) shop_text = game_font.render("Shop", True, BLACK) shop_rect = shop_text.get_rect(bottomleft=(10, HEIGHT - 10)) gamble_button = pygame.Rect(WIDTH - 210, HEIGHT - 100, 200, 50) # Save/load functionality def save_game(): with open(os.path.join(script_dir, "save.txt"), "w") as file: file.writelines([f"{val}\n" for val in [clicks, clicks_per_click, click_upgrade_cost, clicks_per_second, cps_upgrade_cost]]) def load_game(): global clicks, clicks_per_click, click_upgrade_cost, clicks_per_second, cps_upgrade_cost try: with open(os.path.join(script_dir, "save.txt"), "r") as file: values = [float(file.readline()) if i == 0 else int(file.readline()) for i in range(5)] clicks, clicks_per_click, click_upgrade_cost, clicks_per_second, cps_upgrade_cost = values except FileNotFoundError: pass # Background draw def draw_background(name="game_background.jpg"): bg = load_image("backgrounds", name, (WIDTH, HEIGHT)) screen.blit(bg, (0, 0)) # Menu systems def menu(title, buttons): while True: screen.fill(WHITE) draw_background("main_menu_background.jpg") screen.blit(title_font.render(title, True, BLACK), title_font.render(title, True, BLACK).get_rect(center=(WIDTH // 2, HEIGHT // 5))) for rect, text in buttons: pygame.draw.rect(screen, GRAY, rect) screen.blit(font.render(text, True, BLACK), font.render(text, True, BLACK).get_rect(center=rect.center)) pygame.display.flip() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); sys.exit() if event.type == pygame.MOUSEBUTTONDOWN: for rect, action in buttons: if rect.collidepoint(event.pos): return action def main_menu(): return menu("Clicker", [ (pygame.Rect(WIDTH//2-100, HEIGHT//2, 200, 50), "play"), (pygame.Rect(WIDTH//2-100, HEIGHT//2+100, 200, 50), "quit") ]) def options_menu(): draw_background("options_menu_background.jpg") return menu("Options", [ (pygame.Rect(WIDTH//2-100, HEIGHT//2, 200, 50), "back"), (pygame.Rect(WIDTH//2-100, HEIGHT//2+100, 200, 50), "quit") ]) def shop_menu(): global current_skin_index, click_image while True: draw_background("shop_menu_background.jpg") screen.blit(title_font.render("Shop", True, BLACK), title_font.render("Shop", True, BLACK).get_rect(center=(WIDTH // 2, HEIGHT // 5))) for i, skin in enumerate(click_images): rect = skin.get_rect(center=((i+1)*WIDTH//(len(click_images)+1), HEIGHT//2)) screen.blit(skin, rect) if i != current_skin_index: screen.blit(font.render(f"{click_upgrade_cost} clicks", True, BLACK), (rect.centerx - 60, rect.bottom + 10)) back_rect = pygame.Rect(WIDTH//2-100, HEIGHT - 100, 200, 50) pygame.draw.rect(screen, GRAY, back_rect) screen.blit(font.render("Back", True, BLACK), font.render("Back", True, BLACK).get_rect(center=back_rect.center)) pygame.display.flip() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); sys.exit() if event.type == pygame.MOUSEBUTTONDOWN: if back_rect.collidepoint(event.pos): return for i, skin in enumerate(click_images): if skin.get_rect(center=((i+1)*WIDTH//(len(click_images)+1), HEIGHT//2)).collidepoint(event.pos): current_skin_index = i click_image = click_images[i] def draw_upgrades(): upgrade_text = font.render(f"Upgrade Click {click_upgrade_cost}", True, BLACK) cps_text = font.render(f"Upgrade CPS {cps_upgrade_cost}", True, BLACK) gamble_text = font.render("Gamble", True, BLACK) rect1 = upgrade_text.get_rect(midbottom=(WIDTH//2, HEIGHT-10)) rect2 = cps_text.get_rect(midbottom=(WIDTH//2, HEIGHT-60)) pygame.draw.rect(screen, GRAY, gamble_button) screen.blit(gamble_text, gamble_button.center) screen.blit(upgrade_text, rect1) screen.blit(cps_text, rect2) return rect1, rect2 def handle_upgrades(up1, up2): global clicks, clicks_per_click, click_upgrade_cost, clicks_per_second, cps_upgrade_cost if up1.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0] and clicks >= click_upgrade_cost: clicks -= click_upgrade_cost clicks_per_click += CLICK_BENEFIT_INCREMENT click_upgrade_cost += CLICK_UPGRADE_COST_INCREMENT if up2.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0] and clicks >= cps_upgrade_cost: clicks -= cps_upgrade_cost clicks_per_second += CPS_BENEFIT_INCREMENT cps_upgrade_cost *= 2 if gamble_button.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0] and clicks >= 10: gamble() def gamble(): global clicks cost = 10 win = random.random() < 0.5 if win: reward = random.randint(15, 50) clicks += reward else: clicks -= cost # Load game load_game() if main_menu() == "quit": pygame.quit(); sys.exit() # Main loop running = True clicked = False click_angle = 0 clock = pygame.time.Clock() while running: screen.fill(WHITE) draw_background() for event in pygame.event.get(): if event.type == pygame.QUIT: save_game(); running = False elif event.type == pygame.MOUSEBUTTONDOWN: if click_rect.collidepoint(event.pos): clicks += clicks_per_click clicked = True elif submenu_rect.collidepoint(event.pos): if options_menu() == "quit": save_game(); pygame.quit(); sys.exit() elif shop_rect.collidepoint(event.pos): shop_menu() current_time = pygame.time.get_ticks() clicks += clicks_per_second * ((current_time - last_click_time) / 1000.0) last_click_time = current_time # Rotate & scale click object rotated = pygame.transform.rotate(click_image, click_angle) scaled = pygame.transform.scale(rotated, (int(CLICK_SIZE * scale_factor), int(CLICK_SIZE * scale_factor))) screen.blit(scaled, scaled.get_rect(center=click_rect.center)) click_angle += 1 # Draw UI screen.blit(submenu_text, submenu_rect) screen.blit(shop_text, shop_rect) screen.blit(game_font.render(f"Clicks {int(clicks)}", True, BLACK), (10, 10)) upgrade1, upgrade2 = draw_upgrades() if clicked: scale_factor = 1.1 clicked = False else: scale_factor = max(1.0, scale_factor - 0.05) handle_upgrades(upgrade1, upgrade2) pygame.display.flip() clock.tick(FPS) pygame.quit() sys.exit()