# Pyxel Studio
# Pyxel Studio

from pyxel import *
import random
import math

init(160, 200, title="Climb to survive")
load("res.pyxres")

# Spieler
player_x = 80
player_y = 180
vel_y = 0
frame_count = 0
shield = 0
shield_timer = 0

# Listen
platforms = []
nuts = []
obstacles = []
boosters = []
birds = []

# Stats
score = 0
hearts = 3

# Wasser
water_level = 200
water_speed = 0.2

# Game State
game_over = False
camera_y = 0
jump_boost = 0
jump_boost_timer = 0

# Plattformen erstellen
def create_platforms():
    global platforms
    platforms.append([70,190])
    
    for i in range(1,10):
        x = random.randint(20,140)
        y = 190 - i*20
        platforms.append([x,y])
        
    for i in range(10):
        x = random.randint(20,140)
        y = 180 - i*20 
        platforms.append([x,y])
        
    if random.random() < 0.03:
        if random.random() < 0.5:
            boosters.append([x + 5, y - 10, "shield"])
        else:
            boosters.append([x + 5, y - 10, "jump"])

create_platforms()

def spawn_birds():
    x = random.randint(20, 140)
    y = player_y - random.randint(80, 160)
    birds.append([x, y, random.choice([-1, 1])])  # Richtung



# höchste Plattform
highest_platform_y = min(p[1] for p in platforms)

# neue Plattform
def spawn_platform():
    global highest_platform_y
    x = random.randint(20, 140)
    y = highest_platform_y - random.randint(15, 20)
    platforms.append([x, y])
    highest_platform_y = y

    if random.random() < 0.05:
        if random.random() < 0.5:
            boosters.append([x + 5, y - 10, "shield"])
        else:
            boosters.append([x + 5, y - 10, "jump"])

def update():
    print ("New Code")
    global frame_count
    frame_count += 1
    global player_x, player_y, vel_y
    global water_level, water_speed, game_over
    global camera_y, score, platforms
    global jump_boost, jump_boost_timer
    global hearts
    global shield
    global shield_timer
    global birds
    
    if random.random() < 0.005:
        spawn_birds()
        
        for b in birds:
            b[0] += b[2] * 1.5   # links/rechts Bewegung

            # Umdrehen an Rand
            if b[0] < 10 or b[0] > 150:
                b[2] *= -1
            
    if shield_timer > 0:
        shield_timer -= 1
    else:
        shield = 0

    camera_y = player_y - 120

    if game_over:
        if btnp(KEY_R):
            restart()
        return

    # Bewegung
    if btn(KEY_LEFT):
        player_x -= 2
    if btn(KEY_RIGHT):
        player_x += 2

    # Gravitation
    vel_y += 0.3
    player_y += vel_y

    # Plattform Kollision
    for p in platforms:
        px, py = p
        if (player_x > px-10 and
        player_x < px+20 and
        player_y+8 > py and
        player_y+8 < py+5 and
        vel_y > 0):

            player_y = py-8
    
            if jump_boost:
                vel_y = -8   # stärkerer Sprung
            else:
                vel_y = -5

            score += 1
            
    new_birds = []

    for b in birds:
        bx, by, _ = b

        if abs(player_x - bx) < 10 and abs(player_y - by) < 10:

            if shield == 1:
                continue  # Vogel verschwindet

            hearts -= 1

            if hearts <= 0:
                game_over = True

            continue  # Vogel entfernen

        new_birds.append(b)

    birds = new_birds

    # Booster einsammeln
    for b in boosters:
        bx, by, typ = b

        if abs(player_x - bx) < 10 and abs(player_y - by) < 10:

            if typ == "shield":
                shield = 1
                shield_timer = 300
            else:
                jump_boost = 1
                jump_boost_timer = 120

            boosters.remove(b)
            break
    
    if jump_boost_timer > 0:
        jump_boost_timer -= 1
    else:
        jump_boost = 0
        
    boosters[:] = [b for b in boosters if b[1] < player_y + 200]
    
    # Wasser
    water_level -= water_speed
    water_speed += 0.0005

    if player_y > water_level:
        game_over = True

    # Plattformen nachspawnen
    while highest_platform_y > camera_y -100:
        print(highest_platform_y, player_y-200)
        spawn_platform()

    # alte löschen
    platforms[:] = [p for p in platforms if p[1] < player_y + 200]


def draw():
    cls(0)
    camera(0, camera_y)
    

    # Map
    #bltm(0, 0, 0, 0, 240, 160, 200, 0)
    
    # ENDLOS MAP (HELLGRÜN + BÄUME)

    tile_size = 40

    start_y = int(camera_y // tile_size) * tile_size
    end_y = start_y + 600

    for y in range(start_y, end_y, tile_size):
        for x in range(0, 160, tile_size):

            # Gras / hellgrüner Boden
            rect(x, y, tile_size, tile_size, 11)

            # stabile "random" Werte pro Tile
            seed = (x * 31 + y * 17) % 100

            if seed < 35:
                trunk_x = x + 18
                trunk_y = y + 10

                tree_type = seed % 3

                # Baum 1: klassisch
                if tree_type == 0:
                    rect(trunk_x, trunk_y, 5, 14, 4)
                    circ(trunk_x + 2, trunk_y - 6, 8, 3)

                # Baum 2: höher + schmaler
                elif tree_type == 1:
                    rect(trunk_x, trunk_y, 4, 18, 4)
                    circ(trunk_x + 2, trunk_y - 10, 6, 3)
                    circ(trunk_x + 2, trunk_y - 16, 5, 3)

                # Baum 3: breit (Busch/krone groß)
                else:
                    rect(trunk_x, trunk_y, 6, 12, 4)
                    circ(trunk_x + 2, trunk_y - 6, 10, 3)
                    circ(trunk_x - 2, trunk_y - 4, 7, 3)
                    circ(trunk_x + 6, trunk_y - 4, 7, 3)
    
    # Plattformen
    for p in platforms:
        rect(p[0], p[1], 20, 4, 3)
        
    for b in birds:
        x, y, _ = b

        # kleiner wackel Effekt
        offset = math.sin(frame_count * 0.2) * 1

        # Körper
        circ(x, y + offset, 4, 8)   # Vogelkörper (blau/grau)

        # Flügel
        line(x-6, y+offset, x, y+offset, 8)
        line(x+6, y+offset, x, y+offset, 8)



    # Wasser
    rect(0, water_level, 160, 200, 12)
    
    # Spieler
    blt(player_x, player_y, 0, 0, 16, 16, 16, 0)
    if shield == 1:
        circ(player_x + 8, player_y + 8, 14 + int(math.sin(frame_count * 0.2) * 2), 12)
    
    # Boosters
    for b in boosters:
        x, y, typ = b

        offset = math.sin(frame_count * 0.1) * 2

        if typ == "jump":
            # blauer Pfeil
            circ(x, y + offset, 3, 12)
            tri(x, y-4 + offset, x-3, y+2 + offset, x+3, y+2 + offset, 12)

        elif typ == "shield":
        # gelber Stern (einfacher Stil)
            circ(x, y + offset, 6, 10)
            circ(x+3, y + offset, 4, 10)
            circ(x-3, y + offset, 4, 10)
    
    camera()

    # HUD
    text(5, 5, f"Score: {score}", 7)
    text(5, 15, f"Hearts: {hearts}", 8)
    

    if game_over:
        text(60,100,"GAME OVER",8)
        text(45,120,f"Score: {score}",7)
        text(35,140,"Press R to restart",7)


def restart():
    global player_x, player_y, vel_y
    global platforms, score, water_level, water_speed
    global game_over, highest_platform_y
    global hearts

    player_x = 80
    player_y = 180
    vel_y = 0

    platforms = []
    create_platforms()

    highest_platform_y = min(p[1] for p in platforms)

    score = 0
    water_level = 200
    water_speed = 0.2
    game_over = False
    
    hearts = 3


run(update, draw)