import pyxel

# ── Bildschirm ──────────────────────────────────────────────────
SCREEN_W  = 256
SCREEN_H  = 192
GROUND_Y  = 140

# ── Spielregeln ─────────────────────────────────────────────────
SCROLL    = 1.25
LAENGE    = 2400
SCHILD_T  = 180
SCHWERKRAFT = 0.2

# ── Farben (Palette 0–15) ────────────────────────────────────────
SCHWARZ    = 0
DUNKELBLAU = 1
LILA       = 2
DUNKELGRUEN= 3
BRAUN      = 4
GRAU       = 5
MITTELBLAU = 6
WEISS      = 7
ROT        = 8
ORANGE     = 9
GELB       = 10
GRUEN      = 11
CYAN       = 12
HELLGRAU   = 13
PINK       = 14
PEACH      = 15


IMG_BANK = 0

SPRITES = {
    "spongebob": {
        "n":  (0, 16, 80, 32, 32),
        "run": [(0, 16, 80, 32, 32),
                (1, 0, 24, 32, 32)],
        "b":  (0, 16, 80, 32, 16),
        "f": GELB,
        "boden": 28
    },
    "patrick": {
        "n":  (0, 80, 8, 32, 32),
        "run": [(0, 80, 8, 32, 32),
                (1, 32, 64, 32, 32)],
        "b":  (0, 80, 8, 32, 20),
        "f": PINK,
        "boden": 32
    },
    "squidward": {
        "n":  (0, 72, 48, 32, 48),
        "run": [(0, 72, 48, 32, 48),
                (1, 56, 16, 32, 48)],
        "b":  (0, 72, 48, 32, 28),
        "f": CYAN,
        "boden": 40
    },
    "sandy": {
        "n":  (0, 16, 120, 32, 32),
        "run": [(0, 16, 120, 32, 32),
                (1, 80, 72, 32, 32)],
        "b":  (0, 16, 120, 32, 18),
        "f": BRAUN,
        "boden": 30
    },
    "plankton": {
        "n": (0, 24, 48, 16, 16),
        "boden": 12
    },
    "mr_krabs": {
    "n":     (0, 56, 160, 48, 40),   
    "rage":  (1, 56, 160, 48, 40), 
    "boden": 24
},
}


# ── Level-Aufbau ─────────────────────────────────────────────────
#   (Quallen, Bad-Guy, Patties, Schimmel-Patties)
LEVEL = [
    (1,  "plankton",  8, 2),
    (1,  "karen",     7, 3),
    (3,  "mr_krabs",  7, 3),
    (1, "mega",      7, 2),
]
CHARS = ["spongebob", "patrick", "squidward", "sandy"]

# ================================================================
#   SPIELZUSTAND
# ================================================================

s = {}

def spiel_init():
    global s
    s = {
        "screen": "menu",
        "tick":   0,
        "level":  0,
        "wahl":   0,
        "flash":  0,
        # Spieler
        "px": 40.0,  "py": float(GROUND_Y - 20),
        "pvy": 0.0,  "am_boden": True,
        "bueckt": False,
        "name": "spongebob",  "farbe": GELB,
        "richtung": 1,
        "schild": 0,  "ability_cd": 0,  "effekt": 0,
        "lebt": True,
        "projektile": [],
    
        # Welt
        "scroll": 0.0,  "ziel_x": float(LAENGE),
        # Gegner
        "quallen": [],
        "bg_name": "plankton",
        "bg_x": float(SCREEN_W + 100),  "bg_y": float(GROUND_Y - 16),
        "bg_vx": -1.0,  "bg_rage": False,  "bg_rage_t": 0,
        "bg_laser_cd": 0,  "laser": [],  "bg_lebt": True,
        # Patties & Hintergrund
        "patties": [],
        "deko": [],  "gebaeude": [],  "blasen": [],
        
      
    }


# ================================================================
#   LEVEL STARTEN
# ================================================================

def level_starten():
    n_q, bg, n_p, n_m = LEVEL[s["level"] % len(LEVEL)]
    char = CHARS[s["wahl"]]
    
    pyxel.playm(0, loop=True) 

    s["screen"] = "playing";  s["tick"] = 0
    s["scroll"] = 0.0;        s["ziel_x"] = float(LAENGE)
    s["flash"]  = 0

    s["name"]      = char
    s["farbe"]     = SPRITES[char]["f"]
    s["px"]        = 40.0
    s["py"]        = float(GROUND_Y - 20)
    s["pvy"]       = 0.0
    s["am_boden"]  = True
    s["bueckt"]    = False
    s["richtung"]  = 1
    s["schild"]    = 0
    s["ability_cd"]= 0
    s["effekt"]    = 0
    s["lebt"]      = True
    s["projektile"]= []

    s["quallen"]    = [qualle_neu(pyxel.rndi(100, SCREEN_W + 300)) for _ in range(n_q)]

    s["bg_name"]    = bg
    s["bg_x"]       = float(SCREEN_W + 100)
    s["bg_y"]       = float(GROUND_Y - 16)
    s["bg_vx"]      = -1.0
    s["bg_rage"]    = False
    s["bg_rage_t"]  = 0
    s["bg_laser_cd"]= 90
    s["laser"]      = []
    s["bg_lebt"]    = True
    

    s["patties"] = (
        [patty_neu(pyxel.rndi(150, LAENGE - 100), False) for _ in range(n_p)] +
        [patty_neu(pyxel.rndi(150, LAENGE - 100), True)  for _ in range(n_m)]
    )
    hintergrund_init()

# ================================================================
#   HILFSFUNKTIONEN
# ================================================================

def abstand(ax, ay, bx, by):
    # math.sqrt  →  ** 0.5  (nur Python-Grundoperatoren)
    return ((ax - bx) ** 2 + (ay - by) ** 2) ** 0.5

def beruehrt(ax, ay, ar, bx, by, br):
    return abstand(ax, ay, bx, by) < (ar + br)

# ================================================================
#   HINTERGRUND
# ================================================================

DEKO_TYPEN = ["fels", "koralle", "alge", "seestern", "stein_algen"]

def hintergrund_init():
    s["deko"] = []
    for i in range(30):
        s["deko"].append({
            "x": float(i * 85 + pyxel.rndi(0, 60)),
            "t": DEKO_TYPEN[pyxel.rndi(0, len(DEKO_TYPEN) - 1)],
            "v": pyxel.rndi(0, 5),
        })

    s["blasen"] = []
    for _ in range(18):
        s["blasen"].append({
            "x":  float(pyxel.rndi(0, SCREEN_W)),
            "y":  float(pyxel.rndi(20, GROUND_Y)),
            "sp": pyxel.rndf(0.3, 1.2),      # rndf(a,b)  statt random.uniform
        })

def hintergrund_update():
    for b in s["blasen"]:
        b["y"] -= b["sp"]
        if b["y"] < 5:
            b["y"] = float(GROUND_Y)
            b["x"] = float(pyxel.rndi(0, SCREEN_W))
    for d in s["deko"]:
        d["x"] -= SCROLL
        if d["x"] < -30:
            d["x"] += len(s["deko"]) * 85
    for g in s["gebaeude"]:
        g["x"] -= SCROLL
        if g["x"] < -80:
            g["x"] += len(s["gebaeude"]) * 300

def hintergrund_draw():
    t = s["tick"]

    # Wasser
    pyxel.cls(DUNKELBLAU)
    for y in range(0, GROUND_Y, 6):
        pyxel.rect(0, y, SCREEN_W, 6, DUNKELBLAU if y < 40 else DUNKELBLAU)

    # Lichtstrahlen  –  pyxel.sin(deg) statt math.sin(rad)
    for i in range(5):
        sx = int((t * 0.3 + i * 52) % (SCREEN_W + 40)) - 20
        pyxel.tri(sx, 0, sx + 20, 0, sx - 10, GROUND_Y, DUNKELBLAU)

    # Blasen  –  circb
    for b in s["blasen"]:
        pyxel.circb(int(b["x"]), int(b["y"]), 2, WEISS)

    # Deko + Gebäude
    for d in s["deko"]:
        deko_draw(int(d["x"]), d["t"], d["v"])
    
    # Sandboden
    pyxel.rect(0, GROUND_Y, SCREEN_W, SCREEN_H - GROUND_Y, ORANGE)

    # Wasseroberfläche
    for i in range(0, SCREEN_W, 4):
        welle = int(pyxel.sin((i + t) * 0.46) * 2)
        pyxel.rect(i, welle, 4, 5, CYAN)

    # HUD-Balken
    pyxel.rect(0, 0, SCREEN_W, 14, SCHWARZ)

# ── Deko ─────────────────────────────────────────────────────────

def deko_draw(x, typ, v):
    t = s["tick"]
    y = GROUND_Y
    if typ == "alge":
        h = 18 + v * 4
        for i in range(h):
            # pyxel.sin(deg)  –  Winkel in Grad
            sx = x + int(pyxel.sin((i * 23 + t * 3) % 360) * 3)
            pyxel.pset(sx, y - i, GRUEN if i % 2 == 0 else DUNKELGRUEN)
    elif typ == "koralle":
        pyxel.rect(x,     y - 14, 3, 14, ROT)
        pyxel.rect(x - 4, y -  8, 3,  8, ROT)
        pyxel.rect(x + 4, y - 10, 3, 10, ROT)
        pyxel.circ(x + 1, y - 14, 3, ROT)
        pyxel.circ(x - 3, y -  8, 2, ROT)
        pyxel.circ(x + 5, y - 10, 2, ROT)
    elif typ == "fels":
        pyxel.elli(x - 5, y - 3, 10, 6, GRAU)
        pyxel.ellib(x - 5, y - 3, 10, 6, HELLGRAU)
    elif typ == "seestern":
        for i in range(5):
            # pyxel.cos/sin(deg)  –  Winkel in Grad, kein math.radians nötig
            a = i * 72 - 90
            pyxel.line(x, y - 4,
                       x + int(pyxel.cos(a) * 5),
                       y - 4 + int(pyxel.sin(a) * 5), ROT)
    
    elif typ == "stein_algen":
    # ── Stein (Grundform) ──
        pyxel.elli(x - 6, y - 5, 12, 7, GRAU)
        pyxel.ellib(x - 6, y - 5, 12, 7, HELLGRAU)
    
        # Kleine Details (uneben)
        pyxel.pset(x - 2, y - 6, DUNKELBLAU)
        pyxel.pset(x + 3, y - 4, DUNKELBLAU)
    
        # ── Algen oben drauf ──
        for i in range(-3, 4, 2):
            h = 12 + (i % 4)
            for j in range(h):
                # leichtes Wackeln (wie bei deinen anderen Algen)
                sx = x + i + int(pyxel.sin((j * 20 + s["tick"] * 4) % 360) * 1.5)
                pyxel.pset(sx, y - 6 - j, GRUEN if j % 2 == 0 else DUNKELGRUEN)
    
        # kleiner Glanz auf dem Stein
        pyxel.pset(x + 2, y - 7, WEISS)

# ================================================================
#   KRABBY PATTIES
# ================================================================

def patty_neu(x, schimmelig):
    return {
        "x": float(x),
        "y": float(GROUND_Y - 20 - pyxel.rndi(0, 30)),
        "m": schimmelig,
        "b": pyxel.rndi(0, 30),
    }

def patty_draw(p):
    t  = s["tick"]
    x  = int(p["x"])
    # pyxel.sin(deg)  –  bob-Animation
    y  = int(p["y"]) + int(pyxel.sin((t + p["b"]) * 6 % 360) * 2)
    cb = ORANGE      if not p["m"] else DUNKELGRUEN
    cm = BRAUN       if not p["m"] else DUNKELGRUEN
    cv = GRUEN       if not p["m"] else DUNKELGRUEN
    pyxel.elli(x - 5, y - 10, 10, 5, cb)
    if not p["m"]:
        pyxel.pset(x - 3, y - 11, WEISS)
        pyxel.pset(x + 2, y - 10, WEISS)
    pyxel.rect(x - 7, y - 6, 14, 4, cm)
    pyxel.rect(x - 8, y - 3, 16, 2, cv)
    pyxel.elli(x - 5, y - 1, 10, 4, cb)
    if p["m"]:
        pyxel.circ(x + 2, y - 8, 3, GRUEN)
        pyxel.text(x - 9, y - 20, "MOLD!", GRUEN)

# ================================================================
#   QUALLEN
# ================================================================

QUALLEN_FARBEN = [PINK, CYAN, LILA]

def qualle_neu(x):
    return {
        "x":  float(x),
        "y":  float(pyxel.rndi(50, GROUND_Y - 30)),
        "vx": pyxel.rndf(-1.2, -0.6),          # rndf statt random.uniform
        "t":  pyxel.rndi(0, 60),
        "bt": 0,
        "c":  QUALLEN_FARBEN[pyxel.rndi(0, 2)], # rndi statt random.choice
    }

def qualle_update(q):
    if q["bt"] > 0:
        q["bt"] -= 1
        return
    q["t"] += 1
    q["x"] += q["vx"]
    # pyxel.sin(deg)  –  Schwebebewegung
    q["y"] += pyxel.sin(q["t"] * 3 % 360) * 0.5
    if q["y"] < 30:   q["y"] = 30.0
    if q["y"] > GROUND_Y - 20: q["y"] = float(GROUND_Y - 20)

def qualle_draw(q):
    x  = int(q["x"])
    y  = int(q["y"])
    t  = q["t"]
    c  = GRAU if q["bt"] > 0 else q["c"]
    pyxel.elli(x - 5, y - 4, 10, 7, c)
    pyxel.ellib(x - 5, y - 4, 10, 7, WEISS)
    for i in range(-4, 5, 2):
        lg = 8 + int(pyxel.sin((t * 6 + i * 30) % 360) * 3)
        ox = int(pyxel.sin((t * 5 + i * 25) % 360) * 2)
        pyxel.line(x + i, y + 3, x + i + ox, y + lg, c)
    if q["bt"] == 0 and (t // 10) % 2 == 0:
        pyxel.pset(x - 1, y - 5, GELB)
        pyxel.pset(x + 1, y - 5, GELB)

# ================================================================
#   BAD GUY
# ================================================================

def bad_guy_update():
    if not s["bg_lebt"]: return
    t  = s["tick"]
    px = s["px"]
    py = s["py"]
    n  = s["bg_name"]

    if n == "plankton":
        dx = px - s["bg_x"]
        s["bg_x"] += (1 if dx > 0 else -1) * 1.2

    elif n in ("karen", "mega"):
        sp = 1.0 if n == "karen" else 1.3
        s["bg_x"] += s["bg_vx"] * sp
        if s["bg_x"] < 20:
            s["bg_x"] = 20.0
            s["bg_vx"] = 1.0 * sp
        if s["bg_x"] > SCREEN_W - 20:
            s["bg_x"] = float(SCREEN_W - 30)
            s["bg_vx"] = -1.0 * sp
        s["bg_laser_cd"] -= 1
        if s["bg_laser_cd"] <= 0:
            s["bg_laser_cd"] = 90 if n == "karen" else 150
            laser_schiessen(px, py - 20)

    elif n == "mr_krabs":
        if not s["bg_rage"]:
            s["bg_x"] += s["bg_vx"]
            if s["bg_x"] < 30:  s["bg_vx"] =  0.8
            if s["bg_x"] > 220: s["bg_vx"] = -0.8
            if t % 200 == 0:
                s["bg_rage"] = True
                s["bg_rage_t"] = 80
        else:
            dx = px - s["bg_x"]
            s["bg_x"]     += (1 if dx > 0 else -1) * 2.1
            s["bg_rage_t"] -= 1
            if s["bg_rage_t"] <= 0:
                s["bg_rage"] = False

    for laser in s["laser"][:]:
        laser["x"] += laser["vx"]
        laser["y"] += laser["vy"]
        if laser["x"] < 0 or laser["x"] > SCREEN_W:
            s["laser"].remove(laser)

def laser_schiessen(tx, ty):
    dx = tx - s["bg_x"]
    dy = ty - s["bg_y"]
    d  = (dx*dx + dy*dy) ** 0.5        # ** 0.5  statt math.sqrt
    if d < 1: d = 1.0
    s["laser"].append({
        "x": s["bg_x"], "y": s["bg_y"],
        "vx": dx / d * 3.5,
        "vy": dy / d * 3.5,
    })

def bad_guy_trifft_spieler():
    if not s["bg_lebt"]: return False
    py_off = 4 if s["bueckt"] else 10
    r_hit  = 6 if s["bueckt"] else 10
    px, py = s["px"], s["py"] - py_off
    if beruehrt(s["bg_x"], s["bg_y"], 10, px, py, r_hit): return True
    for laser in s["laser"][:]:
        if beruehrt(laser["x"], laser["y"], 3, px, py, r_hit):
            s["laser"].remove(laser)
            return True
    return False

def bad_guy_draw():
    if not s["bg_lebt"]: return
    x = int(s["bg_x"])
    y = int(s["bg_y"])
    n = s["bg_name"]
    if   n == "plankton":  draw_plankton(x, y)
    elif n == "karen":     draw_karen(x, y)
    elif n == "mr_krabs":  draw_mr_krabs(x, y)
    elif n == "mega":      draw_mega(x, y)
    for laser in s["laser"]:
        lx, ly = int(laser["x"]), int(laser["y"])
        pyxel.line(lx - 2, ly, lx + 2, ly, ROT)
        pyxel.pset(lx, ly, GELB)

def draw_plankton(x, y):
    sp = SPRITES["plankton"]
    img, u, v, w, h = sp["n"]

    # 👉 Richtung zum Spieler
    if s["px"] > x:
        richtung = 1
    else:
        richtung = -1

    # 👉 Zeichnen
    pyxel.blt(x - w//2, y - sp["boden"], 0, u, v, w * richtung, h, 0)
    
def draw_karen(x, y):
    # Bildschirm
    pyxel.rect(x - 12, y - 28, 24, 20, GRAU)
    pyxel.rect(x - 10, y - 26, 20, 16, CYAN)

    # rote Pupillen
    pyxel.circ(x - 5, y - 18, 2, ROT)
    pyxel.circ(x + 5, y - 18, 2, ROT)
    pyxel.circ(x - 5, y - 18, 1, SCHWARZ)
    pyxel.circ(x + 5, y - 18, 1, SCHWARZ)

    # böse Augenbrauen
    pyxel.line(x - 8, y - 22, x - 2, y - 20, SCHWARZ)
    pyxel.line(x + 8, y - 22, x + 2, y - 20, SCHWARZ)

    # böser Mund
    pyxel.line(x - 5, y - 14, x - 3, y - 13, SCHWARZ)
    pyxel.line(x - 3, y - 13, x,     y - 12, SCHWARZ)
    pyxel.line(x,     y - 12, x + 3, y - 13, SCHWARZ)
    pyxel.line(x + 3, y - 13, x + 5, y - 14, SCHWARZ)
    
    # Räder
    pyxel.circ(x - 8, y - 4, 4, HELLGRAU)
    pyxel.circ(x + 8, y - 4, 4, HELLGRAU)

    # Name
    pyxel.text(x - 8, y - 35, "Karen", CYAN)
    
def draw_mr_krabs(x, y):
    sp = SPRITES["mr_krabs"]
    
    if s["bg_rage"]:
        img, u, v, w, h = sp["rage"]
    else:
        img, u, v, w, h = sp["n"]
    
    # Richtung zum Spieler
    if s["px"] > x:
        richtung = 1
    else:
        richtung = -1
    
    pyxel.blt(x - w//2, y - sp["boden"], img, u, v, w * richtung, h, 2)
    
    if s["bg_rage"]:
        pyxel.text(x - 10, y - sp["boden"] - 10, "RAGE!", ROT)

def draw_mega(x, y):
    pyxel.elli(x - 7,  y - 28, 14, 16, GRUEN)
    pyxel.ellib(x - 7, y - 28, 14, 16, DUNKELGRUEN)
    pyxel.circ(x, y - 22, 6, WEISS)
    pyxel.circ(x, y - 22, 3, ROT)
    pyxel.rect(x - 8, y - 14, 16, 8, GRAU)
    pyxel.rect(x - 6, y - 13, 12, 6, CYAN)
    pyxel.line(x - 4, y - 30, x - 8, y - 38, GRUEN)
    pyxel.line(x + 4, y - 30, x + 8, y - 38, GRUEN)
    pyxel.circ(x - 8, y - 38, 2, ROT)
    pyxel.circ(x + 8, y - 38, 2, ROT)
    pyxel.text(x - 20, y - 46, "MEGA BOSS!", ROT)

# ================================================================
#   SPIELER
# ================================================================

def spieler_update():
    if not s["lebt"]: return

    speed = 2.8 if (s["name"] == "spongebob" and s["effekt"] > 0) else 1.8

    # Bewegen  –  btn(key)
    if pyxel.btn(pyxel.KEY_RIGHT):
        s["px"] += speed;  s["richtung"] = 1
    if pyxel.btn(pyxel.KEY_LEFT):
        s["px"] -= speed;  s["richtung"] = -1
    if s["px"] < 10:          s["px"] = 10.0
    if s["px"] > SCREEN_W-10: s["px"] = float(SCREEN_W - 10)
    
    # Bewegung merken (für Animation)
    s["bewegt"] = pyxel.btn(pyxel.KEY_LEFT) or pyxel.btn(pyxel.KEY_RIGHT)

    # Bücken  –  btn(key)
    s["bueckt"] = pyxel.btn(pyxel.KEY_DOWN) and s["am_boden"]

    # Springen  –  btnp(key)
    if not s["bueckt"]:
        jump_v = -5.5 if (s["name"] == "sandy" and s["effekt"] > 0) else -4.2
        if pyxel.btnp(pyxel.KEY_UP) and s["am_boden"]:
            s["pvy"] = jump_v

    # Schwerkraft
    s["pvy"] += SCHWERKRAFT
    s["py"]  += s["pvy"]
    boden = GROUND_Y
    if s["py"] >= boden:
        s["py"] = float(boden);  s["pvy"] = 0.0;  s["am_boden"] = True
    else:
        s["am_boden"] = False

    # Sonderfähigkeit  –  btnp(key)
    if pyxel.btnp(pyxel.KEY_SPACE) and s["ability_cd"] <= 0:
        ability_aktivieren()
        s["ability_cd"] = 180

    # Timer
    if s["schild"]     > 0: s["schild"]     -= 1
    if s["ability_cd"] > 0: s["ability_cd"] -= 1
    if s["effekt"]     > 0: s["effekt"]     -= 1

    # Projektile
    for p in s["projektile"][:]:
        p["x"] += p["vx"];  p["y"] += p["vy"]
        if p["x"] > SCREEN_W + 20 or p["x"] < -20:
            s["projektile"].remove(p);  continue
        for q in s["quallen"][:]:
            if beruehrt(p["x"], p["y"], 4, q["x"], q["y"], 8):
                if p["typ"] == "netz":   q["bt"] = 90
                if p["typ"] == "blase"  and q in s["quallen"]: s["quallen"].remove(q)
                if p in s["projektile"]: s["projektile"].remove(p)
                break

    # Patties sammeln
    for p in s["patties"][:]:
        if beruehrt(s["px"], s["py"], 10, p["x"], p["y"], 8):
            if not p["m"]:
                s["schild"] = SCHILD_T
                pyxel.play(3, 2)
                s["patties"].remove(p)

def ability_aktivieren():
    s["effekt"] = 120
    r = s["richtung"]
    if s["name"] == "patrick":
        s["projektile"].append({"x": s["px"], "y": s["py"], "vx": 4.0*r, "vy": 0.0, "typ": "netz",  "c": PINK})
    elif s["name"] == "squidward":
        s["projektile"].append({"x": s["px"], "y": s["py"], "vx": 4.0*r, "vy": 0.0, "typ": "blase", "c": CYAN})
def spieler_getroffen():
    if s["schild"] > 0:
        s["schild"] = 0
        pyxel.play(3, 3)
        return False

    pyxel.stop()        
    pyxel.play(3, 1)
    s["lebt"] = False
    return True
    
def spieler_draw():
    if not s["lebt"]: return

    sx = int(s["px"])
    sy = int(s["py"])
    r  = s["richtung"]
    bk = s["bueckt"]
    sp = SPRITES[s["name"]]

    if bk:
        img, u, v, w, h = sp["b"]
    
    elif s.get("bewegt") and "run" in sp:
        frames = sp["run"]
        index = (s["tick"] // 5) % len(frames)
        img, u, v, w, h = frames[index]
    
    else:
        img, u, v, w, h = sp["n"]

    # 👉 WICHTIG: anderes Boden-Offset beim Bücken
    if bk:
        boden_offset = sp["boden"] - 12   # <- anpassen!
    else:
        boden_offset = sp["boden"]

    pyxel.blt(sx - w//2, sy - boden_offset, img, u, v, w * r, h, 0)
    
    # ─────────────────────────────────────────────────────────────


    # Schutz-Aura  –  circb
    if s["schild"] > 0:
        pyxel.circb(sx, sy - 8, 14 + s["schild"] % 6, GELB)

    # Projektile
    for p in s["projektile"]:
        px2, py2 = int(p["x"]), int(p["y"])
        pyxel.circb(px2, py2, 5, p["c"])
        if p["typ"] == "netz":
            pyxel.line(px2-4, py2, px2+4, py2, p["c"])
            pyxel.line(px2, py2-4, px2, py2+4, p["c"])

# ================================================================
#   HUD
# ================================================================

def hud_draw():
    pyxel.rect(0, 0, SCREEN_W, 14, SCHWARZ)
    pyxel.text(3, 3, s["name"].upper(), s["farbe"])
    lvl = s["level"] % len(LEVEL)
    pyxel.text(80, 3, "LVL " + str(s["level"]+1) + "  " + LEVEL[lvl][1].upper(), WEISS)
    if s["schild"] > 0:
        bw = int(s["schild"] / SCHILD_T * 50)
        pyxel.rect(SCREEN_W - 55, 3, 52, 6, GRAU)
        pyxel.rect(SCREEN_W - 55, 3, bw, 6, GELB)
        pyxel.text(SCREEN_W - 55, 3, "SHIELD", SCHWARZ)
    if s["ability_cd"] > 0:
        pyxel.text(3, 15, "SPC:" + str(s["ability_cd"]//10) + "s", GRAU)
    else:
        pyxel.text(3, 15, "SUPERPW:READY!", GRUEN)
    prog = s["ziel_x"] / LAENGE
    if prog < 0: prog = 0.0
    if prog > 1: prog = 1.0
    pyxel.rect(65, 15, 126, 4, GRAU)
    pyxel.rect(65, 15, int((1.0 - prog) * 126), 4, GRUEN)
    if s["bueckt"]:
        pyxel.text(3, 22, "DUCK!", GELB)

# ================================================================
#   SCREENS
# ================================================================

def menu_draw():
    t = s["tick"]
    pyxel.cls(DUNKELBLAU)
    for i in range(20):
        bx = (i * 67 + t // 2) % SCREEN_W
        by = SCREEN_H - ((t * (i%3+1)//3 + i*20) % SCREEN_H)
        pyxel.circb(bx, by, 3, WEISS)

    pyxel.rect(28, 18, 200, 32, SCHWARZ)
    pyxel.rectb(28, 18, 200, 32, GELB)
    pyxel.blt(68, 21, 2, 0, 8, 128, 32, 0)

    pyxel.text(76, 62, "CHOOSE CHARACTER:", WEISS)
    labels    = ["SPONGEBOB", "PATRICK", "SQUIDWARD", "SANDY"]
    abilities = ["Superspeed", "Net",   "Bubble",     "High jump"]
    farben    = [GELB,        PINK,     CYAN,        BRAUN]

    SPRITES = {
        "spongebob": { "n": (16, 80, 32, 32), "dy": 0 },
        "patrick":   { "n": (80, 8, 32, 32), "dy": -4 },
        "squidward": { "n": (72, 50, 32, 48), "dy": -6 },
        "sandy":     { "n": (16, 120, 32, 32), "dy": 0 },
    }
    
    for i in range(4):
        cx, cy = 28 + i*50, 80
    
        pyxel.rect(cx-2, cy-2, 44, 52, SCHWARZ)
    
        if i == s["wahl"]:
            pyxel.rectb(cx-2, cy-2, 44, 52, GELB)
    
        # ── Sprite ──
        char = CHARS[i]
        sp   = SPRITES[char]
        u, v, w, h = sp["n"]
        dy = sp["dy"]
    
        pyxel.blt(cx + 6, cy + 4 + dy, 0, u, v, w, h, 0)
    
        # Text
        labels    = ["SPONGEBOB", "PATRICK", "SQUIDWARD", "SANDY"]
        abilities = ["Superspeed", "Net", "Bubble", "High jump"]
        farben    = [GELB, PINK, GRUEN, BRAUN]
    
        pyxel.text(cx, cy+36, labels[i][:9], farben[i])
        pyxel.text(cx, cy+42, abilities[i], WEISS)
        
    ax = 28 + s["wahl"]*50 + 20
    pyxel.tri(ax-4, 77, ax+4, 77, ax, 73, GELB)

    pyxel.rect(18, 148, 220, 42, SCHWARZ)
    pyxel.rectb(18, 148, 220, 42, GRAU)
    pyxel.text(26, 151, "Left/Right: Move",          WEISS)
    pyxel.text(26, 159, "Up: Jump  Down: Duck", WEISS)
    pyxel.text(26, 167, "SPACE: Superpower",         CYAN)
    pyxel.text(26, 175, "Patties=Shield  Mold=Block",  GELB)
    pyxel.text(26, 183, "ENTER = Start game",           GRUEN)

def overlay_draw(titel, untertitel, col):
    pyxel.rect(38, 68, 180, 54, SCHWARZ)
    pyxel.rectb(38, 68, 180, 54, col)
    pyxel.text(38 + (180 - len(titel)*4)//2, 80, titel,      col)
    pyxel.text(38 + (180 - len(untertitel)*4)//2, 96, untertitel, WEISS)

def spielwelt_draw():
    hintergrund_draw()
    for p in s["patties"]:
        if -20 < p["x"] < SCREEN_W + 20:
            patty_draw(p)
    gx = int(s["ziel_x"])
    if -10 < gx < SCREEN_W + 10:
        t = s["tick"]
        for yy in range(0, SCREEN_H, 4):
            c = GELB if (yy//4 + t//10) % 2 == 0 else SCHWARZ
            pyxel.rect(gx-1, yy, 3, 3, c)
        pyxel.text(gx-8, GROUND_Y-72, "ZIEL!", GELB)
    for q in s["quallen"]:
        qualle_draw(q)
    bad_guy_draw()
    spieler_draw()
    if s["flash"] > 0 and s["flash"] % 4 < 2:
        pyxel.rect(0, 0, SCREEN_W, SCREEN_H, ROT)
    hud_draw()

def endgewinn_draw():
    t = s["tick"]
    pyxel.cls(SCHWARZ)
    for i in range(0, SCREEN_W, 8):
        # pyxel.sin(deg)
        h = int(pyxel.sin((i * 4 + t * 3) % 360) * 20) + 80
        pyxel.rect(i, h, 8, SCREEN_H - h, GELB)
    pyxel.rect(18, 28, SCREEN_W-36, 136, SCHWARZ)
    pyxel.rectb(18, 28, SCREEN_W-36, 136, GELB)
    pyxel.text(30, 38, "Congratulations!", GELB)
    pyxel.text(30, 52, "You passed all the levels!", WEISS)
    pyxel.text(30, 66, "Your reward is...", CYAN)
    pyxel.rect(56, 80, SCREEN_W-112, 62, ORANGE)
    pyxel.rectb(56, 80, SCREEN_W-112, 62, GELB)
    pyxel.text(64, 86,  "SACRED KRABBY PATTY", ROT)
    pyxel.text(64, 96,  "RECIPE!",              ROT)
    pyxel.text(64, 108, "Ingredients: Top Secret!", BRAUN)
    pyxel.text(64, 117, "Love + Seespices", GRUEN)
    pyxel.text(64, 126, "+ 1 pinch Bikini Bottom", CYAN)
    patty_draw({"x": SCREEN_W//2, "y": 150, "m": False, "b": 0})
    pyxel.text(30, 150, "ENTER = Main menu", WEISS)

# ================================================================
#   UPDATE & DRAW
# ================================================================

def update():
    s["tick"] += 1
    sc = s["screen"]

    if sc == "menu":
        if s["tick"] == 1:        
            pyxel.playm(2, loop=True)
        if pyxel.btnp(pyxel.KEY_RIGHT): s["wahl"] = (s["wahl"]+1) % 4
        if pyxel.btnp(pyxel.KEY_LEFT):  s["wahl"] = (s["wahl"]-1) % 4
        if pyxel.btnp(pyxel.KEY_RETURN): level_starten()

    elif sc == "playing":
        if s["flash"] > 0: s["flash"] -= 1
        s["scroll"] += SCROLL
        s["ziel_x"] -= SCROLL
        hintergrund_update()

        for p in s["patties"]:
            p["x"] -= SCROLL

        for q in s["quallen"]:
            q["x"] -= SCROLL
            qualle_update(q)
            if q["x"] < -20:
                q["x"] = float(SCREEN_W + pyxel.rndi(50, 200))
                q["y"] = float(pyxel.rndi(50, GROUND_Y - 30))

        s["bg_x"] -= SCROLL
        bad_guy_update()
        spieler_update()

        # Kollision Quallen → Spieler
        py_hit = s["py"] - (4 if s["bueckt"] else 10)
        r_hit  = 8 if s["bueckt"] else 10
        for q in s["quallen"]:
            if q["bt"] > 0: continue
            if beruehrt(s["px"], py_hit, r_hit, q["x"], q["y"], 10):
                if spieler_getroffen():
                    s["flash"] = 30;  s["screen"] = "game_over";  return
                else:
                    q["bt"] = 60

        # Kollision Bad Guy → Spieler
        if bad_guy_trifft_spieler():
            if spieler_getroffen():
                s["flash"] = 30;  s["screen"] = "game_over";  return

        # Schimmel-Patties blockieren
        for p in s["patties"]:
            if p["m"] and beruehrt(s["px"], s["py"], 8, p["x"], p["y"], 10):
                s["px"] -= SCROLL + 1

        
        if s["ziel_x"] <= s["px"]:
            s["screen"] = "level_win"
            pyxel.stop()
            pyxel.play(3, 4) 

    elif sc == "game_over":
        if pyxel.btnp(pyxel.KEY_RETURN):
            level_starten()


    elif sc == "level_win":
        if pyxel.btnp(pyxel.KEY_RETURN):
            s["level"] += 1
            if s["level"] >= len(LEVEL):
                s["screen"] = "win_final"
                pyxel.play(3, 6)
            else:
                level_starten()

    elif sc == "win_final":
        if pyxel.btnp(pyxel.KEY_RETURN):
            s["level"] = 0;  s["screen"] = "menu"


def draw():
    sc = s["screen"]
    if sc == "menu":
        menu_draw()
    elif sc == "playing":
        pyxel.cls(SCHWARZ);  spielwelt_draw()
    elif sc == "game_over":
        pyxel.cls(SCHWARZ);  spielwelt_draw()
        overlay_draw("GAME OVER!", "ENTER = neu starten", ROT)
    elif sc == "level_win":
        pyxel.cls(SCHWARZ);  spielwelt_draw()
        overlay_draw("LEVEL " + str(s["level"]+1) + " SUCCESS!", "ENTER = continue", GELB)
    elif sc == "win_final":
        endgewinn_draw()

# ================================================================
#   START  –  init()  dann  run(update, draw)
# ================================================================

spiel_init()
pyxel.init(SCREEN_W, SCREEN_H, title="Bikini Bottom Adventures", fps=60)
pyxel.load("res.pyxres")
pyxel.run(update, draw)