import pygame
import random
import sys

pygame.init()

window_width = 900
window_height = 400
screen = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Mr Bean Runner Game")
clock = pygame.time.Clock()
fps = 60
DEBUG = False

bg_image = pygame.image.load("bg.jpg")
bg_image = pygame.transform.scale(bg_image, (window_width, window_height))
game_over_image = pygame.image.load("Game over.png")
game_over_image = pygame.transform.scale(game_over_image, (window_width, window_height))
start_image = pygame.image.load("start.png")
bg_scroll = 0
bg_speed = 5

pygame.mixer.init()
pygame.mixer.music.load("music.mp3")
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play(-1)

white = (255, 255, 255)
black = (0, 0, 0)
green = (0, 150, 0)
gray = (100, 100, 100)

def load_font(size, bold=False):
    try:
        return pygame.font.Font("mushbei.ttf", size)
    except Exception:
        return pygame.font.SysFont("mushbei", size, bold=bold)

small_font = load_font(24)
intro_font = load_font(60, bold=True)

INTRO = "INTRO"
PLAYING = "PLAYING"
GAME_OVER = "GAME_OVER"
game_state = INTRO
blink_timer = 0
blink_visible = True
game_over_delay = 600
game_over_timer = 0

ground_y = 330
ground_scroll = 0

car_x = 80
car = pygame.image.load("main.png")
car_height = 120
car_real_width = car.get_width()
car_real_height = car.get_height()
car_width = int(car_real_width * car_height / car_real_height)
car = pygame.transform.scale(car, (car_width, car_height))
car_mask = pygame.mask.from_surface(car)
car_y = ground_y - car_height
car_speed_y = 0
gravity = 0.4
jump_power = -12
is_jumping = False

danger = pygame.image.load("Danger.png")
danger_height = 115
danger_real_width = danger.get_width()
danger_real_height = danger.get_height()
danger_width = int(danger_real_width * danger_height / danger_real_height)
danger = pygame.transform.scale(danger, (danger_width, danger_height))
danger_mask = pygame.mask.from_surface(danger)
danger_x = 1000
danger_y = (ground_y + 35) - danger_height

score = 0
game_speed = 10

def draw_car():
    screen.blit(car, (car_x, car_y))

def draw_danger():
    screen.blit(danger, (danger_x, danger_y))

def draw_score():
    score_text = small_font.render("Score: " + str(score), True, black)
    screen.blit(score_text, (700, 20))

def draw_game_over():
    screen.blit(game_over_image, (0, 0))
    score_text = intro_font.render("Score: " + str(score), True, white)
    screen.blit(score_text, score_text.get_rect(center=(window_width // 2, window_height // 2)))
    restart_text = small_font.render("Press SPACE to Restart", True, white)
    screen.blit(restart_text, (window_width / 2 - 110, window_height - 50))

def draw_text_with_outline(text, font, center_x, center_y):
    outline = font.render(text, True, black)
    for dx, dy in [(-2, -2), (2, -2), (-2, 2), (2, 2)]:
        screen.blit(outline, outline.get_rect(center=(center_x + dx, center_y + dy)))
    label = font.render(text, True, white)
    screen.blit(label, label.get_rect(center=(center_x, center_y)))

def draw_intro():
    screen.fill(black)
    img_width = start_image.get_width()
    img_height = start_image.get_height()
    scale = min(window_width / img_width, window_height / img_height)
    new_width = int(img_width * scale)
    new_height = int(img_height * scale)
    scaled_start = pygame.transform.scale(start_image, (new_width, new_height))
    screen.blit(scaled_start, ((window_width - new_width) // 2, (window_height - new_height) // 2))
    if blink_visible:
        draw_text_with_outline("PRESS SPACE TO START", intro_font, window_width // 2, window_height // 2)

def check_collision():
    offset_x = danger_x - car_x
    offset_y = danger_y - car_y
    hit = car_mask.overlap(danger_mask, (offset_x, offset_y))
    if hit:
        return True
    else:
        return False

running = True
while running:
    dt = clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                if game_state == INTRO:
                    game_state = PLAYING
                elif game_state == GAME_OVER:
                    car_y = ground_y - car_height
                    car_speed_y = 0
                    is_jumping = False
                    danger_x = 900
                    score = 0
                    game_speed = 6
                    game_state = PLAYING
                elif game_state == PLAYING:
                    if is_jumping == False:
                        car_speed_y = jump_power
                        is_jumping = True

    if game_state == INTRO:
        blink_timer = blink_timer + dt
        if blink_timer >= 500:
            blink_timer = 0
            blink_visible = not blink_visible
        draw_intro()
        pygame.display.update()
        continue

    if game_state == PLAYING:
        car_speed_y = car_speed_y + gravity
        car_y = car_y + car_speed_y
        if car_y >= ground_y - car_height:
            car_y = ground_y - car_height
            car_speed_y = 0
            is_jumping = False
        danger_x = danger_x - game_speed
        if danger_x < -danger_width:
            danger_x = 900 + random.randint(0, 300)
            score = score + 1
            game_speed = game_speed + 0.3
        ground_scroll = ground_scroll - game_speed
        if ground_scroll < -40:
            ground_scroll = 0
        bg_scroll = bg_scroll - bg_speed
        if bg_scroll <= -window_width:
            bg_scroll = 0
        if check_collision() == True:
            game_state = GAME_OVER
            game_over_timer = 0

    screen.blit(bg_image, (bg_scroll, 0))
    screen.blit(bg_image, (bg_scroll + window_width, 0))

    mark_x = ground_scroll
    while mark_x < window_width:
        pygame.draw.line(screen, gray, (mark_x, ground_y + 8), (mark_x + 15, ground_y + 8), 2)
        mark_x = mark_x + 40

    draw_car()
    draw_danger()

    if DEBUG == True:
        pygame.draw.rect(screen, green, (car_x, car_y, car_width, car_height), 2)
        pygame.draw.rect(screen, (255, 0, 0), (danger_x, danger_y, danger_width, danger_height), 2)

    draw_score()

    if game_state == GAME_OVER:
        game_over_timer = game_over_timer + dt
        if game_over_timer >= game_over_delay:
            draw_game_over()

    pygame.display.update()

pygame.quit()
sys.exit()
