import pygame import sys import random import math # Import the math module for sine function # Initialize Pygame pygame.init() # Constants WIDTH, HEIGHT = 1920, 1080 FPS = 60 WHITE = (255, 255, 255) NUM_TARGETS = 3 # Number of targets displayed simultaneously GAME_DURATION = 30000 # 30 seconds in milliseconds RESTART_DELAY = 10000 # 10 seconds in milliseconds # Initialize Pygame mixer pygame.mixer.init() # Load the click sounds click_sounds = [ pygame.mixer.Sound("clown-horn-sound-effect_1.mp3"), # Add more sound files as needed ] # Create the screen screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Target Shooting Game") clock = pygame.time.Clock() # Load the background image background_img = pygame.image.load("bg_green.png") background_img = pygame.transform.scale(background_img, (WIDTH, HEIGHT)) # Load the target image target_img = pygame.image.load("target_red3.png") # Font font = pygame.font.Font(None, 36) # Game variables score = 0 total_shots = 0 hits = 0 targets = [] start_time = pygame.time.get_ticks() restart_time = 0 # Jiggle parameters JIGGLE_AMOUNT = 10 # Adjust the amount of jiggle as needed JIGGLE_SPEED = 0.001 # Adjust the speed of the jiggle as needed def generate_random_target(): target_radius = random.randint(60, 110) return [random.randint(target_radius, WIDTH - target_radius), random.randint(target_radius, HEIGHT - target_radius), target_radius] # Initialize targets for _ in range(NUM_TARGETS): targets.append(generate_random_target()) # Bouncing parameters BOUNCE_SPEED = 5 # Adjust the speed of the bounce as needed # Main game loop running = True while running: elapsed_time = pygame.time.get_ticks() - start_time remaining_time = max(0, GAME_DURATION - elapsed_time) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN and remaining_time > 0: total_shots += 1 mouse_x, mouse_y = pygame.mouse.get_pos() for target_pos in targets: distance = ((mouse_x - target_pos[0]) ** 2 + (mouse_y - target_pos[1]) ** 2) ** 0.5 if distance < target_pos[2]: score += 1 hits += 1 targets[targets.index(target_pos)] = generate_random_target() random_sound = random.choice(click_sounds) random_sound.play() # Main game loop running = True while running: elapsed_time = pygame.time.get_ticks() - start_time remaining_time = max(0, GAME_DURATION - elapsed_time) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN and remaining_time > 0: total_shots += 1 mouse_x, mouse_y = pygame.mouse.get_pos() for target_pos in targets: distance = ((mouse_x - target_pos[0]) ** 2 + (mouse_y - target_pos[1]) ** 2) ** 0.5 if distance < target_pos[2]: score += 1 hits += 1 targets[targets.index(target_pos)] = generate_random_target() random_sound = random.choice(click_sounds) random_sound.play() for i in range(NUM_TARGETS): targets[i][0] += BOUNCE_SPEED * math.sin(pygame.time.get_ticks() * JIGGLE_SPEED + i * 2 * math.pi / NUM_TARGETS) targets[i][1] += BOUNCE_SPEED * math.cos(pygame.time.get_ticks() * JIGGLE_SPEED + i * 2 * math.pi / NUM_TARGETS) # Bounce off walls if targets[i][0] - targets[i][2] < 0 or targets[i][0] + targets[i][2] > WIDTH: targets[i][0] -= BOUNCE_SPEED * math.sin(pygame.time.get_ticks() * JIGGLE_SPEED + i * 2 * math.pi / NUM_TARGETS) # Reflect the horizontal direction targets[i][0] = min(max(targets[i][0], targets[i][2]), WIDTH - targets[i][2]) if targets[i][1] - targets[i][2] < 0 or targets[i][1] + targets[i][2] > HEIGHT: targets[i][1] -= BOUNCE_SPEED * math.cos(pygame.time.get_ticks() * JIGGLE_SPEED + i * 2 * math.pi / NUM_TARGETS) # Reflect the vertical direction targets[i][1] = min(max(targets[i][1], targets[i][2]), HEIGHT - targets[i][2]) # Bounce off other targets for j in range(NUM_TARGETS): if i != j: distance = ((targets[i][0] - targets[j][0]) ** 2 + (targets[i][1] - targets[j][1]) ** 2) ** 0.5 if distance < targets[i][2] + targets[j][2]: # Calculate the normal vector normal = [targets[j][0] - targets[i][0], targets[j][1] - targets[i][1]] length = math.sqrt(normal[0] ** 2 + normal[1] ** 2) normal = [normal[0] / length, normal[1] / length] # Calculate the relative velocity relative_velocity = [BOUNCE_SPEED * math.sin(pygame.time.get_ticks() * JIGGLE_SPEED + i * 2 * math.pi / NUM_TARGETS), BOUNCE_SPEED * math.cos(pygame.time.get_ticks() * JIGGLE_SPEED + i * 2 * math.pi / NUM_TARGETS)] # Calculate the dot product of relative velocity and normal vector dot_product = relative_velocity[0] * normal[0] + relative_velocity[1] * normal[1] # Reflect the velocity vector reflected_velocity = [relative_velocity[0] - 2 * dot_product * normal[0], relative_velocity[1] - 2 * dot_product * normal[1]] # Update the target position with the reflected velocity targets[i][0] += reflected_velocity[0] targets[i][1] += reflected_velocity[1] # Draw tiled background for x in range(0, WIDTH, background_img.get_width()): for y in range(0, HEIGHT, background_img.get_height()): screen.blit(background_img, (x, y)) # Draw targets for target_pos in targets: target_radius = target_pos[2] # Retrieve the stored radius target_img_scaled = pygame.transform.scale(target_img, (target_radius * 2, target_radius * 2)) screen.blit(target_img_scaled, (target_pos[0] - target_radius, target_pos[1] - target_radius)) # Draw score, accuracy, and timer score_text = font.render(f"Score: {score}", True, (0, 0, 0)) score_text_rect = score_text.get_rect(topleft=(10, 10)) screen.blit(score_text, score_text_rect) accuracy_text = font.render(f"Accuracy: {hits}/{total_shots} ({(hits / max(1, total_shots)) * 100:.2f}%)", True, (0, 0, 0)) accuracy_text_rect = accuracy_text.get_rect(topleft=(score_text_rect.right + 20, 10)) screen.blit(accuracy_text, accuracy_text_rect) timer_text = font.render(f"Time Left: {remaining_time // 1000}s", True, (0, 0, 0)) timer_text_rect = timer_text.get_rect(topleft=(accuracy_text_rect.right + 20, 10)) screen.blit(timer_text, timer_text_rect) if remaining_time <= 0: if restart_time == 0: restart_time = pygame.time.get_ticks() final_score_text = font.render(f"Final Score: {score}", True, (0, 0, 0)) final_accuracy_text = font.render(f"Final Accuracy: {hits}/{total_shots} ({(hits / max(1, total_shots)) * 100:.2f}%)", True, (0, 0, 0)) screen.blit(final_score_text, (WIDTH // 2 - 100, HEIGHT // 2 - 30)) screen.blit(final_accuracy_text, (WIDTH // 2 - 140, HEIGHT // 2 + 10)) restart_countdown = max(0, (RESTART_DELAY - (pygame.time.get_ticks() - restart_time)) // 1000) countdown_text = font.render(f"Restart in: {restart_countdown}s", True, (0, 0, 0)) countdown_text_rect = countdown_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 70)) screen.blit(countdown_text, countdown_text_rect) if pygame.time.get_ticks() - restart_time >= RESTART_DELAY: score = 0 total_shots = 0 hits = 0 targets = [] start_time = pygame.time.get_ticks() restart_time = 0 for _ in range(NUM_TARGETS): targets.append(generate_random_target()) pygame.display.flip() clock.tick(FPS) pygame.quit() sys.exit()