# Pyxel Studio
import pyxel
import random

pyxel.init(160, 120, title="Bat Escape")

state = "title"

seasons = ["winter", "spring", "summer", "autumn"]

# ===== SOUND =====
pyxel.music(0).set([0], [1], [2], [3])
pyxel.playm(0, loop=True)
pyxel.sound(3).set("c1b0a0g0", "n", "7", "n", 15)

# ===== PLAYER =====
bat_x = 20
bat_y = 60
velocity = 0
world_x = 0

gravity = 0.35
flap = -3
base_speed = 2

# ===== OBJECTS =====
towers = []
boosters = []
stars = []
shooting_stars = []

score = 0
game_over = False

shield = False
shield_timer = 0
slow_timer = 0

next_tower_spawn = 0

SHIELD_DURATION = 180   # ~3 Sekunden
SLOW_DURATION = 180     # ~3 Sekunden

MIN_VERTICAL_MARGIN = 15

# ===== TITLE SCREEN BATS =====
menu_bats = []
for i in range(8):
    menu_bats.append([
        random.randint(0, 160),
        random.randint(20, 100),
        random.uniform(0.5, 1.2)
    ])

# ===== STARS =====
for _ in range(40):
    stars.append([random.randint(0, 160), random.randint(0, 120)])

def draw_bat(x, y):
    pyxel.circ(x, y, 2, 8)
    if pyxel.frame_count % 20 < 10:
        pyxel.tri(x, y, x-6, y-3, x-6, y+3, 8)
        pyxel.tri(x, y, x+6, y-3, x+6, y+3, 8)
    else:
        pyxel.tri(x, y, x-6, y-6, x-6, y+6, 8)
        pyxel.tri(x, y, x+6, y-6, x+6, y+6, 8)

def draw_tower(x, gap_y, tower_type):
    if tower_type == "gap":
        pyxel.tri(x, 0, x+10, 0, x+5, gap_y-15, 4)
        pyxel.tri(x, 120, x+10, 120, x+5, gap_y+15, 4)
    elif tower_type == "top":
        pyxel.tri(x, 0, x+10, 0, x+5, gap_y, 4)
    elif tower_type == "bottom":
        pyxel.tri(x, 120, x+10, 120, x+5, gap_y, 4)
    elif tower_type == "double":
        pyxel.tri(x, 0, x+10, 0, x+5, gap_y-10, 4)
        pyxel.tri(x, 120, x+10, 120, x+5, gap_y+10, 4)

def draw_cave():
    pyxel.cls(0)

    season = seasons[(score // 10) % 4]

    if season == "winter":
        cave_color = 6
        star_color = 7
    elif season == "spring":
        cave_color = 11
        star_color = 7
    elif season == "summer":
        cave_color = 10
        star_color = 10
    else:
        cave_color = 9    
        star_color = 7

    for i in range(0, 160, 8):
        pyxel.rect(i, 0, 8, 10 + (i % 12), cave_color)
        h = 100 + (i % 10)
        pyxel.rect(i, h, 8, 120 - h, cave_color)

    for s in stars:
        pyxel.pset(s[0], s[1], star_color)

        if season == "winter":
            s[1] += 0.3
        elif season == "spring":
            s[1] += 0.2
            s[0] += 0.1
        elif season == "summer":
            s[1] += 0.1
        elif season == "autumn":
            s[1] += 0.25
            s[0] += 0.2

        if s[1] > 120:
            s[1] = 0
            s[0] = random.randint(0, 160)

    if season == "summer":
        if pyxel.frame_count % 60 == 0:
            shooting_stars.append([160, random.randint(0, 120)])

    for ss in shooting_stars[:]:
        ss[0] -= 2
        pyxel.pset(ss[0], ss[1], 7)
        if ss[0] < 0:
            shooting_stars.remove(ss)

    pyxel.text(100, 5, season.upper(), 7)

def update():
    global bat_y, velocity, world_x, score, game_over
    global shield, shield_timer, slow_timer, state, next_tower_spawn

    if state == "title":
        if pyxel.btnp(pyxel.KEY_RETURN):
            state = "game"

        for bat in menu_bats:
            bat[0] += bat[2]
            if bat[0] > 160:
                bat[0] = -10
                bat[1] = random.randint(20, 100)
        return

    if game_over:
        if pyxel.btnp(pyxel.KEY_R):
            reset()
        return

    if pyxel.btnp(pyxel.KEY_SPACE):
        velocity = flap

    velocity += gravity
    bat_y += velocity

    speed = base_speed + score * 0.02

    if slow_timer > 0:
        speed *= 0.5

    world_x += speed

    # ===== TOWERS =====
    if world_x > next_tower_spawn:
        gap = random.randint(50, 90)
        tower_type = random.choice(["gap", "top", "bottom", "double"])

        gap = max(MIN_VERTICAL_MARGIN, min(120 - MIN_VERTICAL_MARGIN, gap))
        towers.append([world_x + 160, gap, False, tower_type])

        distance = random.randint(80, 120)
        next_tower_spawn = world_x + distance

    for t in towers:
        x, gap, counted, _ = t
        if not counted and x - world_x < bat_x:
            score += 1
            t[2] = True

    towers[:] = [t for t in towers if t[0] - world_x > -10]

    # ===== BOOSTER SPAWN =====
    if random.random () < 0.003:
        booster_type = random.choice(["shield", "slow"])
        y = random.randint(20, 100)
        boosters.append([world_x + 160, y, booster_type])

    # ===== BOOSTER UPDATE =====
    for b in boosters[:]:
        bx, by, btype = b
        sx = bx - world_x

        if abs(bat_x - sx) < 6 and abs(bat_y - by) < 6:
            if btype == "shield":
                shield = True
                shield_timer = SHIELD_DURATION
            elif btype == "slow":
                slow_timer = SLOW_DURATION
            boosters.remove(b)

    boosters[:] = [b for b in boosters if b[0] - world_x > -10]

    # ===== TIMER =====
    if shield:
        shield_timer -= 1
        if shield_timer <= 0:
            shield = False

    if slow_timer > 0:
        slow_timer -= 1

    # ===== COLLISION =====
    for x, gap_y, _, tower_type in towers:
        sx = x - world_x

        if bat_x > sx and bat_x < sx + 10:
            hit = False
            if tower_type == "gap":
                hit = bat_y < gap_y - 15 or bat_y > gap_y + 15
            elif tower_type == "top":
                hit = bat_y < gap_y
            elif tower_type == "bottom":
                hit = bat_y > gap_y
            elif tower_type == "double":
                hit = bat_y < gap_y - 10 or bat_y > gap_y + 10

            if hit and not shield:
                game_over = True
                pyxel.play(3, 3)

    if (bat_y < 0 or bat_y > 120):
        game_over = True
        pyxel.play(3, 3)

def draw():
    global state

    if state == "title":
        draw_cave()
        for bat in menu_bats:
            draw_bat(bat[0], bat[1])
        pyxel.text(35, 30, "BAT ESCAPE", 10)
        pyxel.text(25, 45, "by PyxelStudios", 7)
        pyxel.text(20, 80, "PRESS ENTER", 6)
        return

    draw_cave()

    for x, gap_y, _, tower_type in towers:
        draw_tower(x - world_x, gap_y, tower_type)

    # BOOSTER DRAW
    for bx, by, btype in boosters:
        sx = bx - world_x
        if btype == "shield":
            pyxel.circ(sx, by, 3, 11)
        elif btype == "slow":
            pyxel.circ(sx, by, 3, 12)

    draw_bat(bat_x, bat_y)

    if shield:
        pyxel.circb(bat_x, bat_y, 6, 11)

    pyxel.text(5, 5, f"Score: {score}", 7)

    if game_over:
        pyxel.text(50, 50, "GAME OVER", 8)
        pyxel.text(25, 60, "Press R to restart", 7)

def reset():
    global bat_y, velocity, world_x, score, game_over
    global shield, shield_timer, slow_timer, next_tower_spawn

    bat_y = 60
    velocity = 0
    world_x = 0
    towers.clear()
    boosters.clear()
    score = 0
    game_over = False
    shield = False
    shield_timer = 0
    slow_timer = 0
    next_tower_spawn = 0

pyxel.run(update, draw)