import pyxel
import math

S = 3
OX = 16
OY = 76

# ============================================================
# FARBPALETTE (Pyxel 16 Farben, konsistent verwendet)
# 0  = Schwarz          8  = Rot/Dunkelorange
# 1  = Dunkelblau       9  = Orange/Braun
# 2  = Dunkelrot/Lila  10  = Gelb
# 3  = Dunkelgrün      11  = Hellgrün
# 4  = Braun            12  = Cyan/Hellblau
# 5  = Dunkelgrau       13  = Hellgrau/Weiß-Blau
# 6  = Hellgrau         14  = Rosa/Hautton
# 7  = Weiß            15  = Pfirsich/Hellhaut
# ============================================================

def sp(x):
    return int(x) * S + OX

def spy(y):
    return int(y) * S + OY

def scl(v):
    return int(v) * S

def drect(x, y, w, h, c):
    pyxel.rect(sp(x), spy(y), scl(w), scl(h), c)

def drectb(x, y, w, h, c):
    pyxel.rectb(sp(x), spy(y), scl(w), scl(h), c)

def dline(x1, y1, x2, y2, c):
    pyxel.line(sp(x1), spy(y1), sp(x2), spy(y2), c)

def dtri(x1, y1, x2, y2, x3, y3, c):
    pyxel.tri(sp(x1), spy(y1), sp(x2), spy(y2), sp(x3), spy(y3), c)

def dcirc(x, y, r, c):
    pyxel.circ(sp(x), spy(y), scl(r), c)

def dcircb(x, y, r, c):
    pyxel.circb(sp(x), spy(y), scl(r), c)

def dpset(x, y, c):
    pyxel.rect(sp(x), spy(y), S, S, c)

def dtext(x, y, s, c):
    pyxel.text(sp(x), spy(y), s, c)


class SchoolEscape:

    def __init__(self):
        pyxel.init(512, 512, title="School Escape", fps=30)
        pyxel.load("res1.pyxres")
        self._define_music()

        self.show_lore = True
        self.lore_page = 0
        self.lore_timer = 0
        self.show_controls = False
        self.controls_timer = 0
        self.level_select = False
        self.current_level = 1

        self._init_level(1)
        pyxel.playm(0, loop=True)
        pyxel.run(self.update, self.draw)

    # ================================================================
    #  LEVEL INITIALISIERUNG
    # ================================================================
    def _init_level(self, level):
        self.current_level = level

        self.p1_x = 20.0
        self.p1_y = 100.0
        self.p2_x = 40.0
        self.p2_y = 100.0
        self.p1_vy = 0.0
        self.p2_vy = 0.0
        self.p1_vx = 0.0
        self.p2_vx = 0.0

        self.player_w = 8
        self.player_h = 16

        self.gravity = 0.5
        self.jump = -6
        self.ground = 116 - self.player_h   # = 100

        self.camera_x = 0.0

        self.checkpoint_x = 20.0
        self.checkpoint_y = float(self.ground)

        self.flag_timer = 0
        self.flag_frame = 0
        self.exit_unlocked = False

        self.win = False
        self.win_timer = 0
        self.dead = False
        self.dead_timer = 0

        # Spieler-Animation: 4 Walk-Frames, Stand-Frame 0
        self.p1_frame = 0
        self.p1_dir = 1
        self.p1_anim_timer = 0
        self.p1_on_ground = True

        self.p2_frame = 0
        self.p2_dir = 1
        self.p2_anim_timer = 0
        self.p2_on_ground = True

        self.bg_scroll = 0.0
        self.spike_blink = 0

        self.particles = []
        self.patties = []
        self.burritos = []
        self.ice_floors = []
        self.breaking_ice = []

        self.timer_frames = 3000
        self.time_up = False

        if level == 1:
            self._init_level1()
        elif level == 2:
            self._init_level2()
        elif level == 3:
            self._init_level3()
        elif level == 4:
            self._init_level4()

    # ----------------------------------------------------------------
    def _init_level1(self):
        self.level_width = 1000
        self.exit_x = 940
        self.exit_y = 100
        self.platforms = [
            (60,  90, 40, 5), (120, 80, 30, 5), (180, 70, 30, 5),
            (240, 85, 40, 5), (320, 75, 30, 5), (380, 90, 40, 5),
            (440, 78, 25, 5), (480, 65, 30, 5), (430, 55, 20, 5),
            (530, 88, 35, 5), (580, 75, 25, 5), (630, 62, 30, 5),
            (680, 80, 35, 5), (720, 68, 20, 5), (760, 55, 25, 5),
            (800, 70, 30, 5), (840, 85, 40, 5), (880, 72, 25, 5),
            (910, 60, 20, 5),
        ]
        self.pits = [
            (155, 175), (215, 235), (295, 315), (500, 525),
            (610, 625), (745, 758), (860, 878),
        ]
        self.spikes = [
            (170, 110), (260, 110), (340, 110), (405, 110), (465, 110),
        ]
        self.icicles = [
            [100, 20, 5, 12, False, 0.0, True],
            [230, 20, 5, 12, False, 0.0, True],
            [370, 20, 5, 12, False, 0.0, True],
            [490, 20, 5, 12, False, 0.0, True],
            [620, 20, 5, 12, False, 0.0, True],
            [750, 20, 5, 12, False, 0.0, True],
            [850, 20, 5, 12, False, 0.0, True],
        ]
        self.bg_decos = [(bx + 10, (bx // 45) % 5) for bx in range(0, 1000, 45)]
        self.lockers = []
        self.coins = [
            [70,82,False],[90,82,False],[125,72,False],[145,72,False],
            [185,62,False],[200,62,False],[250,77,False],[270,77,False],
            [325,67,False],[345,67,False],[385,82,False],[400,82,False],
            [445,70,False],[460,70,False],[483,57,False],[433,47,False],
            [535,80,False],[555,80,False],[583,67,False],[600,67,False],
            [633,54,False],[655,54,False],[683,72,False],[700,72,False],
            [723,60,False],[763,47,False],[803,62,False],[843,77,False],
            [883,64,False],[913,52,False],
        ]
        self.coins_total = len(self.coins)
        self.coins_collected = 0
        self.boss = None
        self.moving_platforms = []

    # ----------------------------------------------------------------
    def _init_level2(self):
        self.level_width = 800
        self.exit_x = 740
        self.exit_y = 100
        self.platforms = [
            (80,88,30,5),(140,88,30,5),(200,88,30,5),(260,88,30,5),
            (320,88,30,5),(380,88,30,5),(440,88,30,5),(500,88,30,5),
            (560,75,25,5),(600,60,20,5),(640,75,25,5),(680,88,25,5),
        ]
        self.pits = [(50,65),(410,430)]
        self.spikes = [(120,110),(280,110),(460,110),(620,110)]
        self.icicles = [
            [160,20,5,12,False,0.0,True],[310,20,5,12,False,0.0,True],
            [470,20,5,12,False,0.0,True],[580,20,5,12,False,0.0,True],
        ]
        self.bg_decos = [(bx+5,(bx//50)%3) for bx in range(0,800,50)]
        self.lockers = []
        self.coins = [
            [85,80,False],[100,80,False],[145,80,False],[160,80,False],
            [205,80,False],[220,80,False],[265,80,False],[280,80,False],
            [325,80,False],[340,80,False],[385,80,False],[400,80,False],
            [445,80,False],[460,80,False],[505,80,False],[520,80,False],
            [563,67,False],[603,52,False],[643,67,False],[683,80,False],
        ]
        self.coins_total = len(self.coins)
        self.coins_collected = 0
        # Boss: Herr Florian
        self.boss = {
            "x":550.0,"y":100.0,"w":12,"h":16,
            "hp":5,"max_hp":5,"dir":-1,"speed":1.0,
            "patrol_left":500,"patrol_right":700,
            "attack_timer":0,"attack_interval":60,
            "projectiles":[],"frame":0,"anim_timer":0,
            "stun_timer":0,"alive":True,"stomp_cooldown":0,
            "name":"FLORIAN",
        }
        self.moving_platforms = []

    # ----------------------------------------------------------------
    def _init_level3(self):
        self.level_width = 1200
        self.exit_x = 1140
        self.exit_y = 100
        self.platforms = [
            (60,90,30,5),(130,78,25,5),(200,65,25,5),(260,78,25,5),
            (330,65,25,5),(400,52,30,5),(460,65,20,5),(510,78,20,5),
            (560,60,25,5),(620,48,25,5),(680,62,30,5),(740,50,20,5),
            (790,65,25,5),(850,78,30,5),(900,60,25,5),(950,48,20,5),
            (1000,62,30,5),(1060,78,30,5),(1100,65,25,5),
        ]
        self.moving_platforms = [
            [310,85,30,5,1,290,370,1.2],[550,70,30,5,-1,520,620,1.5],
            [830,55,25,5,1,800,900,1.0],[1010,65,25,5,-1,980,1080,1.3],
        ]
        self.pits = [
            (105,125),(225,248),(372,392),(500,520),
            (652,668),(810,830),(980,1000),
        ]
        self.spikes = [
            (145,110),(285,110),(430,110),(590,110),
            (710,110),(870,110),(1040,110),
        ]
        self.icicles = [
            [80,15,5,14,False,0.0,True],[210,15,5,14,False,0.0,True],
            [360,15,5,14,False,0.0,True],[490,15,5,14,False,0.0,True],
            [640,15,5,14,False,0.0,True],[800,15,5,14,False,0.0,True],
            [960,15,5,14,False,0.0,True],[1090,15,5,14,False,0.0,True],
        ]
        self.bg_decos = [(bx+15,(bx//60)%4) for bx in range(0,1200,60)]
        self.lockers = []
        self.coins = []
        coin_positions = [65,135,205,265,335,405,465,515,
                          565,625,685,745,795,855,905,955,1005,1065,1105]
        platform_y = [90,78,65,78,65,52,65,78,60,48,62,50,65,78,60,48,62,78,65]
        for i,(cx2,cy) in enumerate(zip(coin_positions,platform_y)):
            self.coins.append([cx2,cy-10,False])
            if i%3==0:
                self.coins.append([cx2+12,cy-10,False])
        self.coins_total = len(self.coins)
        self.coins_collected = 0
        # Boss: Herr Tobias
        self.boss = {
            "x":900.0,"y":100.0,"w":14,"h":18,
            "hp":8,"max_hp":8,"dir":-1,"speed":1.5,
            "patrol_left":850,"patrol_right":1100,
            "attack_timer":0,"attack_interval":45,
            "projectiles":[],"frame":0,"anim_timer":0,
            "stun_timer":0,"alive":True,"stomp_cooldown":0,
            "phase":1,"jump_timer":0,"jump_interval":90,
            "name":"TOBIAS",
        }

    # ----------------------------------------------------------------
    def _init_level4(self):
        self.level_width = 1400
        self.exit_x = 1340
        self.exit_y = 100
        self.ice_zone_start = 600
        self.ice_zone_end = 1100
        self.platforms = [
            (50,92,45,5),(110,85,40,5),(170,78,35,5),(230,88,50,5),
            (300,75,30,5),(350,65,25,5),(400,80,40,5),(460,70,35,5),
            (520,85,30,5),(1140,85,35,5),(1200,75,30,5),
            (1260,88,40,5),(1310,78,25,5),
        ]
        self.moving_platforms = [[480,92,25,5,1,460,550,0.8]]
        self.pits = [
            (95,108),(285,298),(555,570),(690,710),
            (815,835),(1000,1020),(1175,1195),
        ]
        self.spikes = [(140,110),(320,110),(490,110)]
        self.icicles = [
            [680,15,6,14,False,0.0,True],[760,15,6,14,False,0.0,True],
            [870,15,6,14,False,0.0,True],[950,15,6,14,False,0.0,True],
            [1030,15,6,14,False,0.0,True],
        ]
        self.ice_floors = [
            [620,112,35,4,0,False,0],[700,112,30,4,0,False,0],
            [770,112,35,4,0,False,0],[860,112,40,4,0,False,0],
            [940,112,30,4,0,False,0],[1010,112,35,4,0,False,0],
            [1070,112,25,4,0,False,0],[650,88,30,5,0,False,0],
            [720,75,25,5,0,False,0],[780,62,30,5,0,False,0],
            [850,78,35,5,0,False,0],[920,65,25,5,0,False,0],
            [980,80,30,5,0,False,0],[1040,70,25,5,0,False,0],
        ]
        self.patties = [
            [180,100,-1,True,0,0,False],[350,100,1,True,0,0,False],
            [480,100,-1,True,0,0,False],
        ]
        self.burritos = [
            [660,100,-1,True,0,0,False,0],[740,100,1,True,0,0,False,0],
            [820,100,-1,True,0,0,False,0],[900,100,1,True,0,0,False,0],
            [970,100,-1,True,0,0,False,0],[1050,100,1,True,0,0,False,0],
        ]
        self.bg_decos = []
        for bx in range(0,600,55):
            self.bg_decos.append((bx+10,(bx//55)%5,"mensa"))
        for bx in range(600,1100,50):
            self.bg_decos.append((bx+5,(bx//50)%4,"cold"))
        for bx in range(1100,1400,60):
            self.bg_decos.append((bx+10,(bx//60)%3,"kitchen"))
        self.lockers = []
        self.coins = [
            [55,84,False],[75,84,False],[115,77,False],[135,77,False],
            [175,70,False],[195,70,False],[240,80,False],[265,80,False],
            [305,67,False],[325,67,False],[355,57,False],[405,72,False],
            [430,72,False],[465,62,False],[490,62,False],[525,77,False],
            [655,80,False],[675,80,False],[725,67,False],[745,67,False],
            [785,54,False],[805,54,False],[855,70,False],[875,70,False],
            [925,57,False],[945,57,False],[985,72,False],[1045,62,False],
            [1145,77,False],[1165,77,False],[1205,67,False],
            [1265,80,False],[1315,70,False],
        ]
        self.coins_total = len(self.coins)
        self.coins_collected = 0
        self.boss = None

    # ================================================================
    #  MUSIK
    # ================================================================
    def _define_music(self):
        s = pyxel.sound(0)
        s.set(
            "c3r  e3r  g3r  e3r  a3r  g3r  e3r  c3r  "
            "d3r  f3r  a3r  f3r  g3r  e3r  c3r  r    "
            "e3r  a3r  c4r  a3r  g3r  f3r  e3r  d3r  "
            "c3r  e3r  g3r  c4r  b3r  a3r  g3r  r    ",
            "t",
            "4030 4030 4030 4030 4030 4030 4030 0000 "
            "4030 4030 4030 4030 4030 4030 4030 0000 "
            "4030 4030 4030 4030 4030 4030 4030 4030 "
            "4030 4030 4030 4030 4030 4030 4030 0000 ",
            "n", 6
        )
        s = pyxel.sound(1)
        s.set(
            "c2r  r    r    g1r  a1r  r    r    f1r  "
            "d2r  r    r    a1r  g1r  r    r    r    "
            "c2r  r    r    g1r  a1r  r    r    e1r  "
            "f1r  r    r    c1r  g1r  r    r    r    ",
            "t",
            "4000 0000 0000 3000 4000 0000 0000 3000 "
            "4000 0000 0000 3000 4000 0000 0000 0000 "
            "4000 0000 0000 3000 4000 0000 0000 3000 "
            "4000 0000 0000 3000 4000 0000 0000 0000 ",
            "n", 6
        )
        s = pyxel.sound(2)
        s.set(
            "c3r  g3r  e3r  g3r  a2r  e3r  c3r  e3r  "
            "d3r  a3r  f3r  a3r  g2r  d3r  b2r  d3r  "
            "c3r  g3r  e3r  g3r  a2r  e3r  c3r  e3r  "
            "f2r  c3r  a2r  c3r  g2r  r    r    r    ",
            "s",
            "2010 2010 2010 2010 2010 2010 2010 2010 "
            "2010 2010 2010 2010 2010 2010 2010 2010 "
            "2010 2010 2010 2010 2010 2010 2010 2010 "
            "2010 2010 2010 2010 2010 0000 0000 0000 ",
            "n", 6
        )
        s = pyxel.sound(3); s.set("c3e3g3c4","t","5432","n",15)
        s = pyxel.sound(4); s.set("g2e2c2","t","654","n",10)
        s = pyxel.sound(5); s.set("c3e3g3c4e4g4c4","t","7777777","n",10)
        s = pyxel.sound(6); s.set("c2c1","n","53","n",8)
        s = pyxel.sound(7); s.set("e3c3g2","t","543","n",12)
        s = pyxel.sound(8); s.set("c4r","t","70","n",8)
        m = pyxel.music(0)
        m.set([0],[1],[2],[])

    # ================================================================
    #  HILFSFUNKTIONEN
    # ================================================================
    def in_pit(self, x):
        for px, py in self.pits:
            if px < x + self.player_w and x < py:
                return True
        return False

    def on_ice(self, x):
        if self.current_level != 4:
            return False
        return self.ice_zone_start <= x <= self.ice_zone_end

    def on_ice_floor(self, x, y):
        if self.current_level != 4:
            return None
        for ice in self.ice_floors:
            if ice[5]:
                continue
            ix, iy, iw, ih = ice[0], ice[1], ice[2], ice[3]
            if (x + self.player_w > ix and x < ix + iw and
                abs(y + self.player_h - iy) < 3):
                return ice
        return None

    def collide_platform(self, x, y, vy):
        # Normale Plattformen
        for px, py, pw, ph in self.platforms:
            if (x + self.player_w > px and x < px + pw and
                y + self.player_h >= py and
                y + self.player_h <= py + ph + abs(vy) + 1 and
                vy >= 0):
                return py - self.player_h, 0.0

        # Bewegliche Plattformen
        if self.current_level in (3, 4):
            for mp in self.moving_platforms:
                px, py, pw, ph = mp[0], mp[1], mp[2], mp[3]
                if (x + self.player_w > px and x < px + pw and
                    y + self.player_h >= py and
                    y + self.player_h <= py + ph + abs(vy) + 1 and
                    vy >= 0):
                    return py - self.player_h, 0.0

        # Eisböden
        if self.current_level == 4:
            for ice in self.ice_floors:
                if ice[5]:
                    continue
                ix, iy, iw, ih = ice[0], ice[1], ice[2], ice[3]
                if (x + self.player_w > ix and x < ix + iw and
                    y + self.player_h >= iy and
                    y + self.player_h <= iy + ih + abs(vy) + 1 and
                    vy >= 0):
                    return iy - self.player_h, 0.0

        return y, vy

    def is_on_any_surface(self, x, y):
        """Returns True if player is standing on ground or a platform"""
        if y >= self.ground and not self.in_pit(x):
            return True
        for px, py, pw, ph in self.platforms:
            if (x + self.player_w > px and x < px + pw and
                abs(y + self.player_h - py) <= 2):
                return True
        if self.current_level in (3, 4):
            for mp in self.moving_platforms:
                px, py, pw, ph = mp[0], mp[1], mp[2], mp[3]
                if (x + self.player_w > px and x < px + pw and
                    abs(y + self.player_h - py) <= 2):
                    return True
        if self.current_level == 4:
            for ice in self.ice_floors:
                if ice[5]:
                    continue
                ix, iy, iw, ih = ice[0], ice[1], ice[2], ice[3]
                if (x + self.player_w > ix and x < ix + iw and
                    abs(y + self.player_h - iy) <= 2):
                    return True
        return False

    def collide_players(self):
        if (self.p1_x + self.player_w > self.p2_x and
            self.p1_x < self.p2_x + self.player_w and
            self.p1_y + self.player_h >= self.p2_y and
            self.p1_y + self.player_h <= self.p2_y + 3 and
            self.p1_vy >= 0):
            self.p1_y = self.p2_y - self.player_h
            self.p1_vy = 0
        if (self.p2_x + self.player_w > self.p1_x and
            self.p2_x < self.p1_x + self.player_w and
            self.p2_y + self.player_h >= self.p1_y and
            self.p2_y + self.player_h <= self.p1_y + 3 and
            self.p2_vy >= 0):
            self.p2_y = self.p1_y - self.player_h
            self.p2_vy = 0

    def collect_coins(self):
        for coin in self.coins:
            if coin[2]:
                continue
            cx2, cy = coin[0], coin[1]
            for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                if (px < cx2+6 and px+self.player_w > cx2 and
                    py < cy+6 and py+self.player_h > cy):
                    coin[2] = True
                    self.coins_collected += 1
                    pyxel.play(3, 3)
                    break
        self.exit_unlocked = (self.coins_collected >= self.coins_total)
        if self.current_level in (2,3) and self.boss and not self.boss["alive"]:
            self.exit_unlocked = True

    def check_spikes(self):
        for sx, sy in self.spikes:
            for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                if (px < sx+12 and px+self.player_w > sx and
                    py < sy+6 and py+self.player_h > sy):
                    self._kill_players()

    def check_icicles(self):
        for ic in self.icicles:
            if not ic[6]:
                continue
            ix, iy, iw, ih = ic[0], ic[1], ic[2], ic[3]
            if not ic[4]:
                for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                    if abs(px + self.player_w/2 - (ix + iw/2)) < 15:
                        ic[4] = True
            if ic[4]:
                ic[5] += 0.6
                ic[1] += ic[5]
                for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                    if (px < ix+iw and px+self.player_w > ix and
                        py < ic[1]+ih and py+self.player_h > ic[1]):
                        self._kill_players()
                        ic[6] = False
                if ic[1] > 120:
                    ic[6] = False

    def _kill_players(self):
        self.dead = True
        self.dead_timer = 40
        self.p1_x = float(self.checkpoint_x)
        self.p1_y = float(self.checkpoint_y)
        self.p1_vy = 0.0; self.p1_vx = 0.0
        self.p2_x = float(self.checkpoint_x) + 12
        self.p2_y = float(self.checkpoint_y)
        self.p2_vy = 0.0; self.p2_vx = 0.0

    # ================================================================
    #  PATTIES
    # ================================================================
    def update_patties(self):
        if self.current_level != 4:
            return
        for patty in self.patties:
            if not patty[3]:
                continue
            patty[0] += patty[2] * 0.7
            if patty[0] < 10 or patty[0] > 590:
                patty[2] = -patty[2]
            patty[5] += 1
            if patty[5] % 10 == 0:
                patty[4] = (patty[4]+1) % 2
            patty_w, patty_h = 10, 8
            for i, (player_x, player_y, player_vy) in enumerate([
                (self.p1_x, self.p1_y, self.p1_vy),
                (self.p2_x, self.p2_y, self.p2_vy)
            ]):
                if (player_x+self.player_w > patty[0] and
                    player_x < patty[0]+patty_w and
                    player_y+self.player_h > patty[1] and
                    player_y < patty[1]+patty_h):
                    if player_y+self.player_h <= patty[1]+5 and player_vy > 0:
                        patty[3] = False; patty[6] = True
                        pyxel.play(3, 7)
                        if i == 0: self.p1_vy = self.jump * 0.6
                        else:       self.p2_vy = self.jump * 0.6
                    else:
                        self._kill_players()

    # ================================================================
    #  BURRITOS
    # ================================================================
    def update_burritos(self):
        if self.current_level != 4:
            return
        for b in self.burritos:
            if not b[3]:
                continue
            b[7] += 1
            if b[7] % 60 < 10:
                shiver = 1 if (b[7] % 4 < 2) else -1
                b[0] += shiver * 0.3
            else:
                b[0] += b[2] * 0.8
            if b[0] < self.ice_zone_start+10 or b[0] > self.ice_zone_end-20:
                b[2] = -b[2]
            b[5] += 1
            if b[5] % 8 == 0:
                b[4] = (b[4]+1) % 2
            bw, bh = 10, 12
            for i, (player_x, player_y, player_vy) in enumerate([
                (self.p1_x, self.p1_y, self.p1_vy),
                (self.p2_x, self.p2_y, self.p2_vy)
            ]):
                if (player_x+self.player_w > b[0] and
                    player_x < b[0]+bw and
                    player_y+self.player_h > b[1] and
                    player_y < b[1]+bh):
                    if player_y+self.player_h <= b[1]+5 and player_vy > 0:
                        b[3] = False; b[6] = True
                        pyxel.play(3, 7)
                        if i == 0: self.p1_vy = self.jump * 0.6
                        else:       self.p2_vy = self.jump * 0.6
                    else:
                        self._kill_players()

    # ================================================================
    #  EISBÖDEN
    # ================================================================
    def update_ice_floors(self):
        if self.current_level != 4:
            return
        for ice in self.ice_floors:
            if ice[5]:
                continue
            player_on = False
            for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                if (px+self.player_w > ice[0] and px < ice[0]+ice[2] and
                    abs(py+self.player_h - ice[1]) < 4):
                    player_on = True; break
            if player_on:
                ice[4] += 1
                ice[6] = min(3, ice[4] // 20)
                if ice[4] > 60:
                    ice[5] = True
                    pyxel.play(3, 6)
            else:
                if ice[4] > 0:
                    ice[4] = max(0, ice[4] - 0.5)
                ice[6] = min(3, int(ice[4]) // 20)

    # ================================================================
    #  BOSS
    # ================================================================
    def update_boss(self):
        b = self.boss
        if not b["alive"]:
            return
        if self.current_level == 3 and b["hp"] <= b["max_hp"]//2 and b["phase"] == 1:
            b["phase"] = 2
            b["speed"] = 2.5
            b["attack_interval"] = 30
        if b["stun_timer"] > 0:
            b["stun_timer"] -= 1
        b["x"] += b["speed"] * b["dir"]
        if b["x"] <= b["patrol_left"]:  b["dir"] = 1
        if b["x"] >= b["patrol_right"]: b["dir"] = -1
        b["anim_timer"] += 1
        if b["anim_timer"] % 8 == 0:
            b["frame"] = (b["frame"]+1) % 2
        b["attack_timer"] += 1
        if b["attack_timer"] >= b["attack_interval"]:
            b["attack_timer"] = 0
            target_x = (self.p1_x + self.p2_x) / 2
            vx = 2.0 if target_x > b["x"] else -2.0
            b["projectiles"].append([b["x"]+b["w"]/2, b["y"]+4, vx, True])
            if self.current_level == 3 and b["phase"] == 2:
                b["projectiles"].append([b["x"]+b["w"]/2, b["y"]+4, vx*0.7, True, 1.5])
        for proj in b["projectiles"]:
            if not proj[3]: continue
            proj[0] += proj[2]
            if len(proj) > 4: proj[1] += proj[4]
            if proj[0] < 0 or proj[0] > self.level_width: proj[3] = False
            for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                if (px < proj[0]+4 and px+self.player_w > proj[0] and
                    py < proj[1]+4 and py+self.player_h > proj[1]):
                    proj[3] = False
                    self._kill_players()
        b["projectiles"] = [p for p in b["projectiles"] if p[3]]
        if b["stomp_cooldown"] > 0: b["stomp_cooldown"] -= 1
        if b["stun_timer"] == 0 and b["stomp_cooldown"] == 0:
            for player_x, player_y, player_vy in [
                (self.p1_x, self.p1_y, self.p1_vy),
                (self.p2_x, self.p2_y, self.p2_vy)
            ]:
                if (player_x+self.player_w > b["x"] and
                    player_x < b["x"]+b["w"] and
                    player_y+self.player_h >= b["y"] and
                    player_y+self.player_h <= b["y"]+4 and
                    player_vy > 0):
                    b["hp"] -= 1
                    b["stun_timer"] = 30
                    b["stomp_cooldown"] = 20
                    pyxel.play(3, 4)
                    if player_x == self.p1_x: self.p1_vy = self.jump * 0.7
                    else:                      self.p2_vy = self.jump * 0.7
                    if b["hp"] <= 0:
                        b["alive"] = False
                        pyxel.play(3, 5)
        if b["stun_timer"] == 0:
            for px, py in [(self.p1_x, self.p1_y), (self.p2_x, self.p2_y)]:
                if (px+self.player_w > b["x"] and px < b["x"]+b["w"] and
                    py+self.player_h > b["y"] and py < b["y"]+b["h"]):
                    if not (py+self.player_h <= b["y"]+6):
                        self._kill_players()

    # ================================================================
    #  UPDATE
    # ================================================================
    def update(self):
        # ---- LORE ----
        if self.show_lore:
            self.lore_timer += 1
            if pyxel.btnp(pyxel.KEY_SPACE) or pyxel.btnp(pyxel.KEY_RETURN):
                self.lore_page += 1
                self.lore_timer = 0
                if self.lore_page >= 4:
                    self.show_lore = False
                    self.show_controls = True
                    self.controls_timer = 0
            elif self.lore_timer > 420:   # 14 Sekunden statt 8
                self.lore_timer = 0
                self.lore_page += 1
                if self.lore_page >= 4:
                    self.show_lore = False
                    self.show_controls = True
                    self.controls_timer = 0
            return

        if self.show_controls:
            self.controls_timer += 1
            if (pyxel.btnp(pyxel.KEY_SPACE) or pyxel.btnp(pyxel.KEY_RETURN)
                    or self.controls_timer > 360):
                self.show_controls = False
                self.level_select = True
            return

        if self.level_select:
            if pyxel.btnp(pyxel.KEY_1): self.level_select=False; self._init_level(1)
            elif pyxel.btnp(pyxel.KEY_2): self.level_select=False; self._init_level(2)
            elif pyxel.btnp(pyxel.KEY_3): self.level_select=False; self._init_level(3)
            elif pyxel.btnp(pyxel.KEY_4): self.level_select=False; self._init_level(4)
            return

        if self.win:
            self.win_timer += 1
            if self.win_timer > 180:
                self.level_select = True; self.win = False; self.win_timer = 0
            return

        if self.dead:
            self.dead_timer -= 1
            if self.dead_timer <= 0: self.dead = False
            return

        # ---- TIMER ----
        if not self.time_up:
            self.timer_frames -= 1
            if self.timer_frames <= 0:
                self.timer_frames = 0; self.time_up = True
                self._kill_players()
            elif self.timer_frames <= 300 and self.timer_frames % 30 == 0:
                pyxel.play(3, 8)

        self.flag_timer += 1
        if self.flag_timer >= 15:
            self.flag_timer = 0
            self.flag_frame = (self.flag_frame+1) % 2
        self.spike_blink = (self.spike_blink+1) % 20

        # Bewegliche Plattformen
        if self.current_level in (3, 4):
            for mp in self.moving_platforms:
                mp[0] += mp[4] * mp[7]
                if mp[0] <= mp[5]: mp[4] = 1
                if mp[0] >= mp[6]: mp[4] = -1

        # ---- EIS-PHYSIK ----
        p1_on_ice = self.on_ice(self.p1_x)
        p2_on_ice = self.on_ice(self.p2_x)
        ice_friction = 0.98
        ice_accel = 0.3
        normal_speed = 2

        # Player 1
        moving_p1 = False
        if p1_on_ice and self.p1_y >= self.ground - 2:
            if pyxel.btn(pyxel.KEY_A): self.p1_vx -= ice_accel; self.p1_dir=-1; moving_p1=True
            if pyxel.btn(pyxel.KEY_D): self.p1_vx += ice_accel; self.p1_dir= 1; moving_p1=True
            self.p1_vx *= ice_friction
            self.p1_vx = max(-4, min(4, self.p1_vx))
            self.p1_x += self.p1_vx
        else:
            self.p1_vx = 0
            if pyxel.btn(pyxel.KEY_A): self.p1_x -= normal_speed; self.p1_dir=-1; moving_p1=True
            if pyxel.btn(pyxel.KEY_D): self.p1_x += normal_speed; self.p1_dir= 1; moving_p1=True

        self.p1_on_ground = self.is_on_any_surface(self.p1_x, self.p1_y)
        if pyxel.btnp(pyxel.KEY_W) and self.p1_vy == 0 and self.p1_on_ground:
            self.p1_vy = self.jump

        if moving_p1 or abs(self.p1_vx) > 0.5:
            self.p1_anim_timer += 1
            if self.p1_anim_timer % 6 == 0:
                self.p1_frame = (self.p1_frame+1) % 4
        else:
            self.p1_frame = 0

        # Player 2
        moving_p2 = False
        if p2_on_ice and self.p2_y >= self.ground - 2:
            if pyxel.btn(pyxel.KEY_LEFT):  self.p2_vx -= ice_accel; self.p2_dir=-1; moving_p2=True
            if pyxel.btn(pyxel.KEY_RIGHT): self.p2_vx += ice_accel; self.p2_dir= 1; moving_p2=True
            self.p2_vx *= ice_friction
            self.p2_vx = max(-4, min(4, self.p2_vx))
            self.p2_x += self.p2_vx
        else:
            self.p2_vx = 0
            if pyxel.btn(pyxel.KEY_LEFT):  self.p2_x -= normal_speed; self.p2_dir=-1; moving_p2=True
            if pyxel.btn(pyxel.KEY_RIGHT): self.p2_x += normal_speed; self.p2_dir= 1; moving_p2=True

        self.p2_on_ground = self.is_on_any_surface(self.p2_x, self.p2_y)
        if pyxel.btnp(pyxel.KEY_UP) and self.p2_vy == 0 and self.p2_on_ground:
            self.p2_vy = self.jump

        if moving_p2 or abs(self.p2_vx) > 0.5:
            self.p2_anim_timer += 1
            if self.p2_anim_timer % 6 == 0:
                self.p2_frame = (self.p2_frame+1) % 4
        else:
            self.p2_frame = 0

        # Gravitation
        self.p1_vy += self.gravity; self.p1_y += self.p1_vy
        self.p2_vy += self.gravity; self.p2_y += self.p2_vy

        # Boden
        if self.p1_y >= self.ground and not self.in_pit(self.p1_x):
            self.p1_y = float(self.ground); self.p1_vy = 0
        if self.p2_y >= self.ground and not self.in_pit(self.p2_x):
            self.p2_y = float(self.ground); self.p2_vy = 0

        # Plattform-Kollisionen
        self.p1_y, self.p1_vy = self.collide_platform(self.p1_x, self.p1_y, self.p1_vy)
        self.p2_y, self.p2_vy = self.collide_platform(self.p2_x, self.p2_y, self.p2_vy)

        self.collide_players()
        self.collect_coins()
        self.check_spikes()
        self.check_icicles()

        if self.current_level in (2,3) and self.boss:
            self.update_boss()
        if self.current_level == 4:
            self.update_patties()
            self.update_burritos()
            self.update_ice_floors()

        # Checkpoints
        if self.current_level == 1:
            if abs(self.p1_x-80) < 5 and abs(self.p2_x-80) < 5:
                self.checkpoint_x = 80.0
        elif self.current_level == 4:
            if abs(self.p1_x-600) < 10 and abs(self.p2_x-600) < 15:
                self.checkpoint_x = 590.0; self.checkpoint_y = float(self.ground)
            if abs(self.p1_x-1100) < 10 and abs(self.p2_x-1100) < 15:
                self.checkpoint_x = 1090.0; self.checkpoint_y = float(self.ground)

        if self.p1_y > 125 or self.p2_y > 125:
            self._kill_players()

        self.p1_x = max(0, min(self.p1_x, self.level_width - self.player_w))
        self.p2_x = max(0, min(self.p2_x, self.level_width - self.player_w))

        if self.exit_unlocked:
            if abs(self.p1_x-self.exit_x) < 12 and abs(self.p2_x-self.exit_x) < 12:
                self.win = True

        center = (self.p1_x + self.p2_x) / 2
        self.camera_x = center - 80
        self.camera_x = max(0, min(self.camera_x, self.level_width - 160))

    # ================================================================
    #  DRAW
    # ================================================================
    def draw(self):
        pyxel.cls(0)
        # Rand abdunkeln
        pyxel.rect(0,0,512,OY,0)
        pyxel.rect(0,512-(512-OY-360),512,512-(512-OY-360),0)
        pyxel.rect(0,0,OX,512,0)
        pyxel.rect(512-OX,0,OX,512,0)

        if self.show_lore:   self._draw_lore();         return
        if self.show_controls: self._draw_controls();   return
        if self.level_select:  self._draw_level_select(); return

        cx = self.camera_x
        if   self.current_level == 1: self._draw_level1_bg(cx)
        elif self.current_level == 2: self._draw_level2_bg(cx)
        elif self.current_level == 3: self._draw_level3_bg(cx)
        elif self.current_level == 4: self._draw_level4_bg(cx)

        self._draw_common(cx)
        self._draw_hud()
        if self.win: self._draw_win()

    # ================================================================
    #  LORE (4 Seiten, klare Zeichnungen, mehr Zeit)
    # ================================================================
    def _draw_lore(self):
        t = self.lore_timer
        page = self.lore_page

        # Fortschrittsbalken unten (zeigt verbleibende Zeit)
        progress = min(1.0, t / 420.0)
        pyxel.rect(40, 498, int(432 * progress), 6, 5)
        pyxel.rectb(40, 498, 432, 6, 6)

        if page == 0:
            # ---- SEITE 1: Die Schule ----
            # Himmel (gedämpftes Blau → schwarz oben)
            for y in range(512):
                c = 1 if y > 200 else 0
                pyxel.rect(0, y, 512, 1, c)

            # Boden vor Schule
            pyxel.rect(0, 400, 512, 112, 4)
            pyxel.rect(0, 400, 512, 4, 9)

            # Schulgebäude – klarer, detaillierter
            # Hauptgebäude
            pyxel.rect(80, 180, 352, 225, 5)
            # Dach-Dreiecke
            pyxel.tri(78, 180, 256, 120, 434, 180, 2)
            pyxel.tri(80, 180, 256, 125, 432, 180, 4)
            # Seitenturm links
            pyxel.rect(70, 200, 60, 200, 2)
            pyxel.tri(60, 200, 100, 160, 140, 200, 4)
            # Seitenturm rechts
            pyxel.rect(382, 200, 60, 200, 2)
            pyxel.tri(372, 200, 412, 158, 452, 200, 4)
            # Zentralturm oben
            pyxel.rect(220, 120, 72, 80, 5)
            pyxel.tri(210, 120, 256, 78, 302, 120, 2)
            pyxel.tri(215, 120, 256, 83, 297, 120, 4)
            # Turm-Fenster (glühend)
            pyxel.rect(244, 130, 24, 20, 8)
            pyxel.rect(247, 133, 18, 14, 2)
            if t % 30 < 15: pyxel.rect(250, 136, 12, 8, 8)

            # Hauptfenster (4 Reihen, klar erkennbar)
            for row in range(2):
                for col in range(5):
                    wx = 100 + col * 62
                    wy = 210 + row * 50
                    pyxel.rect(wx, wy, 36, 28, 1)
                    pyxel.rect(wx+2, wy+2, 32, 24, 0)
                    # Fensterglas (teilweise beleuchtet = rot/böse)
                    gc = 8 if (col+row) % 2 == 0 else 2
                    pyxel.rect(wx+3, wy+3, 13, 20, gc)
                    pyxel.rect(wx+18, wy+3, 13, 20, gc)
                    pyxel.line(wx+16, wy+2, wx+16, wy+28, 1)
                    pyxel.line(wx+2, wy+14, wx+34, wy+14, 1)
                    # Fensterrahmen-Highlights
                    pyxel.line(wx+3, wy+3, wx+14, wy+3, 6)

            # Eingangstür (groß und einschüchternd)
            pyxel.rect(218, 315, 76, 90, 0)
            pyxel.rect(222, 318, 34, 87, 8)
            pyxel.rect(258, 318, 34, 87, 8)
            pyxel.rect(224, 320, 30, 83, 2)
            pyxel.rect(260, 320, 30, 83, 2)
            pyxel.circ(256, 318, 38, 0)
            pyxel.circ(256, 318, 36, 8)
            pyxel.circ(256, 318, 34, 2)
            pyxel.line(256, 282, 256, 405, 0)
            # Türklinke
            pyxel.rect(248, 365, 8, 3, 10)
            pyxel.rect(260, 365, 8, 3, 10)

            # Schulschild
            pyxel.rect(128, 145, 256, 42, 9)
            pyxel.rectb(128, 145, 256, 42, 10)
            pyxel.rectb(130, 147, 252, 38, 0)
            pyxel.text(148, 152, "GRUNDSCHULE FINSTERHAUSEN", 10)
            pyxel.text(158, 166, "Disziplin. Pflicht. Gehorsam.", 7)

            # Titelbox
            pyxel.rect(50, 28, 412, 80, 0)
            pyxel.rectb(50, 28, 412, 80, 9)
            pyxel.rectb(53, 31, 406, 74, 8)
            for dx in range(3):
                for dy in range(3):
                    pyxel.text(102+dx, 40+dy, "SCHOOL  ESCAPE", 8)
            pyxel.text(102, 40, "SCHOOL  ESCAPE", 10)
            for dx in range(2):
                for dy in range(2):
                    pyxel.text(148+dx, 65+dy, "Die Legende", 8)
            pyxel.text(148, 65, "Die Legende", 7)

            # Erzähltext (klarer Hintergrund)
            pyxel.rect(30, 420, 452, 72, 0)
            pyxel.rectb(30, 420, 452, 72, 5)
            pyxel.text(46, 430, "Es war ein ganz normaler Montag in Finsterhausen...", 7)
            pyxel.text(46, 444, "Die Schulglocke hatte soeben gelaeutet.", 13)
            pyxel.text(46, 458, "Doch hinter diesen Mauern lauerte das Chaos.", 9)
            pyxel.text(46, 472, "MAX und LISA beschlossen: Heute entkommen wir!", 10)

            if t % 35 < 22:
                pyxel.text(152, 488, "[LEERTASTE] Weiter  >>>", 6)

        elif page == 1:
            # ---- SEITE 2: Die beiden Helden ----
            pyxel.rect(0, 0, 512, 512, 1)
            # Vertikaler Trennstrich mit Verlauf
            for y in range(512):
                c = 5 if 240 < y < 260 else (2 if 230 < y < 270 else 1)
                pyxel.pset(256, y, 0)
            pyxel.line(255, 0, 255, 512, 0)
            pyxel.line(257, 0, 257, 512, 0)

            # === SPIELER 1: MAX (links) ===
            # Körper (rotes Shirt)
            pyxel.rect(88, 145, 80, 70, 8)       # Shirt
            pyxel.rect(92, 147, 72, 66, 2)       # Shirt-Schatten
            pyxel.rect(100, 148, 56, 10, 8)      # Kragen-Highlight
            # Hose (dunkelblau)
            pyxel.rect(88, 215, 36, 65, 1)
            pyxel.rect(128, 215, 36, 65, 1)
            pyxel.line(120, 215, 120, 280, 0)
            # Schuhe
            pyxel.rect(82, 278, 44, 14, 0)
            pyxel.rect(124, 278, 44, 14, 0)
            pyxel.rect(84, 279, 42, 6, 5)
            pyxel.rect(126, 279, 42, 6, 5)
            # Arme
            pyxel.rect(68, 148, 22, 50, 8)        # linker Arm
            pyxel.rect(178, 148, 22, 50, 8)       # rechter Arm
            pyxel.rect(58, 196, 14, 30, 15)       # linke Hand
            pyxel.rect(188, 196, 14, 30, 15)      # rechte Hand
            # Rucksack (blau)
            pyxel.rect(52, 148, 20, 50, 12)
            pyxel.rectb(52, 148, 20, 50, 1)
            pyxel.rect(55, 152, 14, 8, 7)         # Rucksack-Tasche
            pyxel.rectb(55, 152, 14, 8, 1)

            # Kopf
            pyxel.rect(96, 68, 80, 80, 15)        # Gesicht (Hautfarbe)
            pyxel.rectb(96, 68, 80, 80, 9)
            # BRAUNE HAARE (oben)
            pyxel.rect(96, 52, 80, 20, 4)         # Haar-Basis
            pyxel.rect(90, 58, 10, 28, 4)         # Seite links
            pyxel.rect(176, 58, 10, 28, 4)        # Seite rechts
            # Stachelige Haarspitzen
            for i in range(5):
                bx_ = 100 + i * 15
                pyxel.tri(bx_, 52, bx_+6, 38, bx_+12, 52, 4)
                pyxel.tri(bx_+2, 52, bx_+8, 42, bx_+14, 52, 9)  # Highlights
            # BRILLE
            pyxel.rectb(104, 88, 24, 18, 0)
            pyxel.rectb(148, 88, 24, 18, 0)
            pyxel.line(128, 96, 148, 96, 0)       # Brillenbügel
            pyxel.rect(108, 92, 16, 10, 12)       # Glas links (blau getönt)
            pyxel.rect(152, 92, 16, 10, 12)       # Glas rechts
            pyxel.line(110, 93, 115, 93, 7)       # Reflektion links
            pyxel.line(154, 93, 159, 93, 7)       # Reflektion rechts
            pyxel.rect(110, 94, 6, 6, 1)          # Pupille links
            pyxel.rect(154, 94, 6, 6, 1)          # Pupille rechts
            # Mund (entschlossen)
            pyxel.line(122, 128, 150, 128, 0)
            pyxel.line(122, 129, 150, 129, 0)

            # Namensbox
            pyxel.rect(20, 380, 216, 100, 0)
            pyxel.rectb(20, 380, 216, 100, 9)
            pyxel.rectb(22, 382, 212, 96, 8)
            pyxel.text(36, 392, "SPIELER 1: MAX", 10)
            pyxel.line(36, 404, 224, 404, 5)
            pyxel.text(36, 412, "Tasten:  A / D / W", 7)
            pyxel.text(36, 426, "Links / Rechts / Springen", 13)
            pyxel.text(36, 444, "\"Ich will nur nach Hause!\"", 6)
            pyxel.text(36, 460, "Braune Haare, blaue Brille", 5)

            # === SPIELER 2: LISA (rechts) ===
            # Körper (lila/violettes Shirt)
            pyxel.rect(344, 145, 80, 70, 11)
            pyxel.rect(348, 147, 72, 66, 3)
            pyxel.rect(356, 148, 56, 10, 11)
            # Hose (dunkelgrün)
            pyxel.rect(344, 215, 36, 65, 3)
            pyxel.rect(384, 215, 36, 65, 3)
            pyxel.line(374, 215, 374, 280, 0)
            # Schuhe
            pyxel.rect(338, 278, 44, 14, 9)
            pyxel.rect(380, 278, 44, 14, 9)
            pyxel.rect(340, 279, 42, 6, 4)
            pyxel.rect(382, 279, 42, 6, 4)
            # Arme
            pyxel.rect(324, 148, 22, 50, 11)
            pyxel.rect(434, 148, 22, 50, 11)
            pyxel.rect(314, 196, 14, 30, 15)
            pyxel.rect(444, 196, 14, 30, 15)

            # Kopf
            pyxel.rect(352, 68, 80, 80, 15)
            pyxel.rectb(352, 68, 80, 80, 9)
            # BRAUNE HAARE (Zöpfe/Pferdeschwanz)
            pyxel.rect(352, 52, 80, 25, 4)        # Haar-Basis
            pyxel.rect(346, 58, 12, 38, 4)        # Seite links
            pyxel.rect(426, 58, 12, 38, 4)        # Seite rechts
            # Zopf rechts (charakteristisch)
            pyxel.rect(436, 68, 16, 55, 4)
            pyxel.rectb(436, 68, 16, 55, 9)
            pyxel.rect(438, 70, 12, 12, 9)        # Haarband
            # Zopf links
            pyxel.rect(332, 68, 16, 55, 4)
            pyxel.rectb(332, 68, 16, 55, 9)
            pyxel.rect(334, 70, 12, 12, 9)
            # Haarsträhnen-Details
            for i in range(4):
                pyxel.line(356+i*20, 52, 360+i*20, 38, 9)
            # BRILLE (runde Gläser für Lisa)
            pyxel.circb(376, 99, 14, 0)
            pyxel.circb(408, 99, 14, 0)
            pyxel.line(390, 99, 394, 99, 0)
            pyxel.circ(376, 99, 11, 12)
            pyxel.circ(408, 99, 11, 12)
            pyxel.circ(373, 96, 3, 7)    # Reflektion
            pyxel.circ(405, 96, 3, 7)
            pyxel.circ(376, 100, 5, 1)   # Pupille
            pyxel.circ(408, 100, 5, 1)
            # Mund (leicht lächelnd, aber skeptisch)
            pyxel.line(375, 130, 395, 128, 0)
            pyxel.line(395, 128, 408, 132, 0)

            # Namensbox
            pyxel.rect(276, 380, 216, 100, 0)
            pyxel.rectb(276, 380, 216, 100, 3)
            pyxel.rectb(278, 382, 212, 96, 11)
            pyxel.text(292, 392, "SPIELER 2: LISA", 11)
            pyxel.line(292, 404, 480, 404, 5)
            pyxel.text(292, 412, "Tasten:  <- / -> / Hoch", 7)
            pyxel.text(292, 426, "Links / Rechts / Springen", 13)
            pyxel.text(292, 444, "\"Das Mittagessen war falsch!\"", 6)
            pyxel.text(292, 460, "Braune Haare, runde Brille", 5)

            # Titel
            pyxel.rect(0, 0, 512, 48, 0)
            pyxel.rectb(0, 0, 512, 48, 5)
            pyxel.text(130, 10, "DIE HELDEN DER GESCHICHTE", 7)
            pyxel.text(140, 24, "Zwei Schueler. Ein Ziel.", 10)
            pyxel.text(134, 36, "100 Sekunden pro Level!", 8)

            if t % 35 < 22:
                pyxel.text(152, 488, "[LEERTASTE] Weiter  >>>", 6)

        elif page == 2:
            # ---- SEITE 3: Die Feinde ----
            pyxel.rect(0, 0, 512, 512, 0)
            # Rote Warn-Ecken
            for i in range(40):
                c = 8 if i % 2 == 0 else 2
                pyxel.rect(0, i*4, i*2, 4, c)
                pyxel.rect(512-i*2, i*4, i*2, 4, c)

            # Haupt-Panel
            pyxel.rect(14, 14, 484, 468, 0)
            pyxel.rectb(14, 14, 484, 468, 8)
            pyxel.rectb(17, 17, 478, 462, 5)

            pyxel.text(164, 22, "!  ACHTUNG: FEINDE  !", 8)
            pyxel.line(28, 34, 484, 34, 8)

            # --- Herr Florian (Lehrer) ---
            # Körper (dunkler Anzug)
            pyxel.rect(40, 70, 80, 100, 5)
            pyxel.rect(48, 72, 64, 96, 1)
            # Hemd/Krawatte
            pyxel.rect(60, 72, 40, 50, 7)
            pyxel.tri(76, 72, 88, 72, 82, 150, 8)   # Krawatte
            # Kopf
            pyxel.rect(50, 38, 60, 35, 15)
            pyxel.rectb(50, 38, 60, 35, 9)
            # Graue Haare
            pyxel.rect(50, 34, 60, 8, 6)
            pyxel.rect(46, 38, 8, 18, 6)
            pyxel.rect(106, 38, 8, 18, 6)
            # Brille (eckig, böse)
            pyxel.rectb(53, 46, 18, 12, 0)
            pyxel.rectb(76, 46, 18, 12, 0)
            pyxel.line(71, 51, 76, 51, 0)
            pyxel.rect(55, 48, 14, 8, 12)     # Gläser
            pyxel.rect(78, 48, 14, 8, 12)
            pyxel.pset(62, 51, 8)  # böse Pupillen
            pyxel.pset(85, 51, 8)
            # Mund (böses Grinsen)
            pyxel.line(60, 65, 68, 67, 0)
            pyxel.line(68, 67, 76, 65, 0)
            pyxel.line(76, 65, 84, 68, 0)
            pyxel.line(84, 68, 90, 65, 0)
            # Hut
            pyxel.rect(48, 32, 64, 8, 5)
            pyxel.rect(56, 20, 48, 14, 5)
            pyxel.rectb(56, 20, 48, 14, 4)
            # Beine/Schuhe
            pyxel.rect(52, 170, 28, 45, 1)
            pyxel.rect(82, 170, 28, 45, 1)
            pyxel.rect(46, 212, 38, 10, 0)
            pyxel.rect(80, 212, 38, 10, 0)
            # Aktentasche
            pyxel.rect(120, 110, 30, 24, 4)
            pyxel.rectb(120, 110, 30, 24, 9)
            pyxel.rect(128, 106, 14, 6, 4)
            pyxel.rectb(128, 106, 14, 6, 9)
            pyxel.line(120, 122, 150, 122, 9)

            # Info-Box Florian
            pyxel.rect(28, 232, 144, 90, 0)
            pyxel.rectb(28, 232, 144, 90, 8)
            pyxel.text(38, 240, "HERR FLORIAN", 8)
            pyxel.text(38, 252, "Deutschlehrer", 5)
            pyxel.line(38, 262, 164, 262, 5)
            pyxel.text(38, 268, "HP:  [#####]", 8)
            pyxel.text(38, 280, "Waffe: Kreide", 7)
            pyxel.text(38, 292, "Schwaeche: Kopf", 13)
            pyxel.text(38, 304, "Level 2 Boss", 6)

            # --- Herr Tobias (Direktor) ---
            # Körper (dicker, imposant)
            pyxel.rect(188, 60, 96, 115, 9)
            pyxel.rect(196, 63, 80, 110, 4)
            pyxel.rect(212, 63, 48, 40, 7)   # Hemd
            # Dicke Krawatte
            pyxel.tri(228, 63, 248, 63, 238, 175, 8)
            pyxel.tri(230, 63, 246, 63, 238, 165, 2)
            # Kopf (größer)
            pyxel.rect(196, 24, 72, 40, 15)
            pyxel.rectb(196, 24, 72, 40, 9)
            # WENIG HAARE (fast kahl, macht ihn böser)
            pyxel.rect(196, 20, 72, 8, 4)
            pyxel.rect(192, 24, 8, 20, 4)
            pyxel.rect(264, 24, 8, 20, 4)
            # Brille (rund, golden)
            pyxel.circb(210, 38, 10, 10)
            pyxel.circb(254, 38, 10, 10)
            pyxel.line(220, 38, 244, 38, 10)
            pyxel.circ(210, 39, 8, 12)
            pyxel.circ(254, 39, 8, 12)
            pyxel.pset(214, 40, 8)  # böse Pupillen (rot)
            pyxel.pset(258, 40, 8)
            # Bushy Augenbrauen
            pyxel.line(202, 28, 222, 26, 0)
            pyxel.line(202, 29, 222, 27, 0)
            pyxel.line(246, 26, 266, 28, 0)
            pyxel.line(246, 27, 266, 29, 0)
            # Mund (strenger Strich)
            pyxel.line(214, 54, 250, 54, 0)
            pyxel.line(214, 55, 250, 55, 0)
            # Hut (imposanter)
            pyxel.rect(192, 18, 80, 8, 5)
            pyxel.rect(200, 4, 64, 16, 5)
            pyxel.rectb(200, 4, 64, 16, 4)
            pyxel.pset(232, 4, 9)
            # Beine
            pyxel.rect(200, 175, 34, 50, 1)
            pyxel.rect(250, 175, 34, 50, 1)
            pyxel.rect(194, 222, 44, 10, 0)
            pyxel.rect(248, 222, 44, 10, 0)
            # Aktenkoffer
            pyxel.rect(284, 140, 32, 28, 4)
            pyxel.rectb(284, 140, 32, 28, 9)
            pyxel.rect(292, 134, 16, 8, 4)
            pyxel.rectb(292, 134, 16, 8, 9)
            pyxel.line(284, 154, 316, 154, 9)

            # Info-Box Tobias
            pyxel.rect(180, 232, 160, 90, 0)
            pyxel.rectb(180, 232, 160, 90, 9)
            pyxel.text(190, 240, "HERR TOBIAS", 9)
            pyxel.text(190, 252, "Schulleiter", 5)
            pyxel.line(190, 262, 332, 262, 5)
            pyxel.text(190, 268, "HP:  [########]", 9)
            pyxel.text(190, 280, "Phase 2: +Geschwindigkeit", 8)
            pyxel.text(190, 292, "Waffe: Aktenmappen", 7)
            pyxel.text(190, 304, "Level 3 Endgegner", 6)

            # --- Patties & Burritos (rechts) ---
            # Patty Burger-Feind
            pyxel.rect(370, 80, 56, 40, 4)
            pyxel.rect(373, 82, 50, 36, 9)
            pyxel.rectb(370, 80, 56, 40, 0)
            # Augen
            pyxel.rect(378, 90, 10, 8, 7)
            pyxel.rect(398, 90, 10, 8, 7)
            pyxel.rect(381, 92, 4, 4, 0)
            pyxel.rect(401, 92, 4, 4, 0)
            # Böse Augenbrauen
            pyxel.line(376, 88, 390, 86, 0)
            pyxel.line(396, 86, 410, 88, 0)
            pyxel.line(382, 102, 404, 100, 0)  # Mund
            # Beine
            pyxel.rect(376, 120, 12, 16, 9)
            pyxel.rect(400, 120, 12, 16, 9)

            # Eisiger Burrito
            pyxel.rect(368, 155, 60, 50, 7)    # Tortilla
            pyxel.rect(371, 158, 54, 44, 12)   # Eis-Inneres
            pyxel.rect(368, 155, 60, 8, 6)     # Falte oben
            # Eis-Kristalle
            for xi in range(3):
                pyxel.pset(375+xi*15, 163, 7)
                pyxel.pset(378+xi*15, 167, 12)
            # Augen (böse)
            pyxel.rect(376, 168, 8, 6, 8)
            pyxel.rect(396, 168, 8, 6, 8)
            pyxel.rect(378, 170, 4, 3, 0)
            pyxel.rect(398, 170, 4, 3, 0)
            # Frost-Atem
            pyxel.text(408, 160, "~*~", 12)
            pyxel.text(408, 168, "*~*", 7)

            pyxel.rect(356, 208, 168, 96, 0)
            pyxel.rectb(356, 208, 168, 96, 9)
            pyxel.text(366, 216, "PATTIES  (Mensa)", 9)
            pyxel.text(366, 228, "Burger-Wachposten", 7)
            pyxel.line(366, 240, 516, 240, 5)
            pyxel.text(366, 246, "Kuehlzone: BURRITOS!", 12)
            pyxel.text(366, 258, "Rutschig + gefaehrlich", 7)
            pyxel.text(366, 270, "Beide: Von oben springen", 10)
            pyxel.text(366, 282, "Seitlich = TOD", 8)
            pyxel.text(366, 294, "Eisboeden brechen durch!", 12)

            # Mission-Box
            pyxel.rect(14, 332, 484, 130, 0)
            pyxel.rectb(14, 332, 484, 130, 7)
            pyxel.text(28, 342, "DIE MISSION:", 7)
            pyxel.text(28, 355, "4 Level der Schule durchqueren:", 13)
            pyxel.text(28, 368, "  [1] Korridor  ->  [2] Klassenzimmer", 10)
            pyxel.text(28, 381, "  [3] Dachboden  ->  [4] Mensa", 10)
            pyxel.text(28, 394, "Jedes Level: NUR 100 SEKUNDEN!", 8)
            pyxel.text(28, 407, "Alle Muenzen sammeln, Fahne erreichen = Sieg!", 7)
            pyxel.text(28, 420, "Bossse von oben besiegen (Herr Florian / Herr Tobias)", 6)
            pyxel.text(28, 433, "Im Kuehlhaus: Alle Plattformen sind Eis und brechen!", 12)

            if t % 35 < 22:
                pyxel.text(152, 488, "[LEERTASTE] Weiter  >>>", 6)

        elif page == 3:
            # ---- SEITE 4: Dramatischer Abschluss ----
            pyxel.rect(0, 0, 512, 512, 0)
            # Dramatische Hintergrund-Strahlen (Scheinwerfer-Effekt)
            for i in range(8):
                ang = math.pi/4 * i + t * 0.005
                x2 = int(256 + math.cos(ang) * 400)
                y2 = int(256 + math.sin(ang) * 400)
                pyxel.line(256, 256, x2, y2, 1)

            # Zentrales Leuchten
            pyxel.circ(256, 230, 150, 1)
            pyxel.circ(256, 230, 120, 0)

            # Große Uhr (klar erkennbar)
            pyxel.circ(256, 220, 95, 1)
            pyxel.circ(256, 220, 93, 2)
            pyxel.circ(256, 220, 90, 0)
            # Uhr-Zifferblatt
            pyxel.circb(256, 220, 85, 5)
            pyxel.circb(256, 220, 83, 6)
            # 12 Markierungen
            for i in range(12):
                ang = -math.pi/2 + 2*math.pi*i/12
                r_inner = 68 if i % 3 == 0 else 72
                x1u = int(256 + math.cos(ang) * r_inner)
                y1u = int(220 + math.sin(ang) * r_inner)
                x2u = int(256 + math.cos(ang) * 78)
                y2u = int(220 + math.sin(ang) * 78)
                col = 10 if i % 3 == 0 else 6
                pyxel.line(x1u, y1u, x2u, y2u, col)
            # Stundenzeiger (fest)
            for r in range(2, 55):
                ang2 = -math.pi/2 + 2*math.pi*0.25
                pyxel.pset(int(256+math.cos(ang2)*r), int(220+math.sin(ang2)*r), 7)
            # Minutenzeiger (dreht sich)
            angle_frames = t % 60
            for r in range(2, 74):
                cr = math.cos(-math.pi/2 + 2*math.pi*angle_frames/60)
                sr = math.sin(-math.pi/2 + 2*math.pi*angle_frames/60)
                pyxel.pset(int(256+cr*r), int(220+sr*r), 10)
            pyxel.circ(256, 220, 5, 10)
            pyxel.circ(256, 220, 3, 7)

            # "100" groß anzeigen
            pyxel.rect(190, 280, 136, 52, 0)
            pyxel.rectb(190, 280, 136, 52, 8)
            for dx in range(4):
                for dy in range(4):
                    pyxel.text(214+dx, 288+dy, "100", 8)
            pyxel.text(214, 288, "100", 10)
            for dx in range(2):
                for dy in range(2):
                    pyxel.text(204+dx, 316+dy, "SEKUNDEN", 8)
            pyxel.text(204, 316, "SEKUNDEN", 7)

            # Haupt-Text
            pyxel.rect(28, 36, 456, 50, 0)
            pyxel.rectb(28, 36, 456, 50, 9)
            for dx in range(2):
                for dy in range(2):
                    pyxel.text(52+dx, 44+dy, "KOENNT IHR ES SCHAFFEN?", 9)
            pyxel.text(52, 44, "KOENNT IHR ES SCHAFFEN?", 7)
            pyxel.text(68, 62, "2 Spieler. 4 Level. Je 100 Sekunden.", 13)
            pyxel.text(68, 74, "Herr Florian und Herr Tobias warten!", 8)

            # Timer-Erklaerung
            pyxel.rect(48, 348, 416, 60, 0)
            pyxel.rectb(48, 348, 416, 60, 5)
            pyxel.text(62, 358, "Timer laeuft ab = Checkpoint + Zeitverlust", 6)
            pyxel.text(62, 372, "Letzte 10s: ALARM-BLINKEN!", 8)
            pyxel.text(62, 386, "Zeit sinnvoll: Muenzen + Geschwindigkeit!", 13)

            # Blinkende Start-Taste
            if t % 22 < 13:
                pyxel.rect(86, 424, 340, 42, 8)
                pyxel.rectb(86, 424, 340, 42, 7)
                pyxel.rectb(89, 427, 334, 36, 9)
                for dx in range(2):
                    for dy in range(2):
                        pyxel.text(122+dx, 440+dy, "LEERTASTE = LOS GEHT'S!", 7)
                pyxel.text(122, 440, "LEERTASTE = LOS GEHT'S!", 0)

    # ----------------------------------------------------------------
    #  CONTROLS SCREEN
    # ----------------------------------------------------------------
    def _draw_controls(self):
        pyxel.cls(0)
        for y in range(OY, OY+360, 8):
            c = 1 if (y//8)%2==0 else 0
            pyxel.rect(OX, y, 480, 8, c)
        pyxel.rect(OX+24, OY+15, 432, 330, 1)
        pyxel.rectb(OX+24, OY+15, 432, 330, 7)
        pyxel.rectb(OX+27, OY+18, 426, 324, 5)
        pyxel.rect(OX+36, OY+27, 408, 42, 5)
        pyxel.text(OX+90, OY+33, "SCHOOL ESCAPE", 10)
        pyxel.text(OX+135, OY+48, "STEUERUNG", 7)
        pyxel.line(OX+45, OY+75, OX+435, OY+75, 13)

        pyxel.rect(OX+36, OY+84, 195, 114, 0)
        pyxel.rectb(OX+36, OY+84, 195, 114, 6)
        pyxel.text(OX+45, OY+93, "SPIELER 1 - MAX", 6)
        pyxel.line(OX+45, OY+111, OX+219, OY+111, 6)
        pyxel.text(OX+45, OY+120, "A      - Links", 7)
        pyxel.text(OX+45, OY+141, "D      - Rechts", 7)
        pyxel.text(OX+45, OY+162, "W      - Springen", 7)

        pyxel.rect(OX+249, OY+84, 201, 114, 0)
        pyxel.rectb(OX+249, OY+84, 201, 114, 8)
        pyxel.text(OX+258, OY+93, "SPIELER 2 - LISA", 8)
        pyxel.line(OX+258, OY+111, OX+435, OY+111, 8)
        pyxel.text(OX+258, OY+120, "LINKS  - Bewegung", 7)
        pyxel.text(OX+258, OY+141, "RECHTS - Bewegung", 7)
        pyxel.text(OX+258, OY+162, "HOCH   - Springen", 7)

        pyxel.rect(OX+36, OY+210, 408, 105, 0)
        pyxel.rectb(OX+36, OY+210, 408, 105, 13)
        pyxel.text(OX+45, OY+219, "TIPPS:", 10)
        pyxel.text(OX+45, OY+237, "Alle Muenzen/Marken sammeln!", 7)
        pyxel.text(OX+45, OY+255, "Fahne erreichbar wenn alle gesammelt!", 8)
        pyxel.text(OX+45, OY+273, "Bosse: Von oben draufspringen!", 6)
        pyxel.text(OX+45, OY+291, "Kuehlhaus: Eisboeden brechen, Vorsicht!", 12)
        if (self.controls_timer//15)%2==0:
            pyxel.text(OX+84, OY+315, "LEERTASTE zum Starten", 11)

    # ----------------------------------------------------------------
    #  LEVEL SELECT
    # ----------------------------------------------------------------
    def _draw_level_select(self):
        pyxel.cls(1)
        for y in range(OY, OY+360, 8):
            c = 1 if (y//8)%2==0 else 2
            pyxel.rect(OX, y, 480, 8, c)
        pyxel.rect(OX+30, OY+24, 420, 318, 0)
        pyxel.rectb(OX+30, OY+24, 420, 318, 7)
        pyxel.rectb(OX+33, OY+27, 414, 312, 5)
        pyxel.text(OX+120, OY+36, "SCHOOL ESCAPE", 10)
        pyxel.text(OX+132, OY+60, "LEVEL SELECT", 7)
        pyxel.line(OX+45, OY+81, OX+438, OY+81, 5)
        levels = [
            ("[1]  KORRIDOR",      "Schulkorridor mit Fallen",           6),
            ("[2]  KLASSENZIMMER", "Boss: Herr Florian!",                8),
            ("[3]  DACHBODEN",     "Boss: Herr Tobias!",                 9),
            ("[4]  MENSA",         "Kuehlhaus + Burritos + Eisboeden!",  12),
        ]
        for i,(name,desc,col) in enumerate(levels):
            y0 = OY+93+i*57
            pyxel.rect(OX+42, y0, 396, 42, 1)
            pyxel.rectb(OX+42, y0, 396, 42, col)
            pyxel.text(OX+54, y0+12, name, 7)
            pyxel.text(OX+54, y0+28, desc, 13)
        pyxel.text(OX+90, OY+300, "Druecke 1, 2, 3 oder 4 zum Starten", 6)

    # ----------------------------------------------------------------
    #  WIN SCREEN
    # ----------------------------------------------------------------
    def _draw_win(self):
        pyxel.rect(sp(10), spy(28), scl(140), scl(54), 0)
        pyxel.rectb(sp(10), spy(28), scl(140), scl(54), 10)
        pyxel.rectb(sp(11), spy(29), scl(138), scl(52), 9)
        msgs = {
            1: ("ENTKOMMEN!", "Korridor bezwungen!"),
            2: ("FLORIAN BESIEGT!", "Klasse entkommen!"),
            3: ("TOBIAS BESIEGT!", "Dachboden geschafft!"),
            4: ("MENSA ESCAPED!", "Mittagspause vorbei!"),
        }
        top,sub = msgs.get(self.current_level, ("GEWONNEN!","Super!"))
        sec_left = self.timer_frames // 30
        pyxel.text(sp(20), spy(35), top, 10)
        pyxel.text(sp(15), spy(45), sub, 7)
        pyxel.text(sp(14), spy(55), f"Coins: {self.coins_collected}/{self.coins_total}", 9)
        pyxel.text(sp(14), spy(63), f"Zeit uebrig: {sec_left}s", 11)
        pyxel.text(sp(13), spy(73), "Zurueck zur Auswahl...", 6)

    # ================================================================
    #  HUD
    # ================================================================
    def _draw_hud(self):
        coin_color = 11 if self.exit_unlocked else 6
        pyxel.rect(sp(80), spy(0), scl(80), scl(10), 0)
        pyxel.rectb(sp(80), spy(0), scl(80), scl(10), 5)
        label = "Marken" if self.current_level == 4 else "Coins"
        pyxel.text(sp(83), spy(2), f"{label}:{self.coins_collected}/{self.coins_total}", coin_color)

        secs = self.timer_frames // 30
        t_color = 7
        if secs <= 30: t_color = 9
        if secs <= 10:
            t_color = 8
            if self.spike_blink < 10:
                pyxel.rect(sp(0), spy(0), scl(60), scl(10), 2)

        pyxel.rect(sp(0), spy(0), scl(60), scl(10), 0)
        pyxel.rectb(sp(0), spy(0), scl(60), scl(10), 5)
        pyxel.circb(sp(5), spy(5), scl(4), t_color)
        ang = -math.pi/2 + 2*math.pi*(1 - self.timer_frames/3000)
        pyxel.line(sp(5), spy(5),
                   int(sp(5)+math.cos(ang)*scl(3)),
                   int(spy(5)+math.sin(ang)*scl(3)), t_color)
        pyxel.text(sp(12), spy(2), f"ZEIT: {secs:3d}s", t_color)

        if not self.exit_unlocked and self.current_level in (1,4):
            missing = self.coins_total - self.coins_collected
            if missing <= 5:
                if self.spike_blink < 10:
                    pyxel.rect(sp(0), spy(11), scl(86), scl(10), 0)
                    pyxel.rectb(sp(0), spy(11), scl(86), scl(10), 10)
                    item = "Marke(n)" if self.current_level==4 else "Muenze(n)"
                    pyxel.text(sp(3), spy(13), f"Noch {missing} {item}!", 10)

        if self.current_level == 4:
            if self.on_ice(self.p1_x) or self.on_ice(self.p2_x):
                if self.spike_blink % 30 < 15:
                    pyxel.text(sp(50), spy(12), "RUTSCHIG!", 12)

        # Boss-HP
        if self.current_level == 2 and self.boss and self.boss["alive"]:
            b = self.boss
            pyxel.text(sp(2), spy(2), "FLORIAN", 8)
            for i in range(b["max_hp"]):
                hx = sp(2+i*7); hy = spy(9)
                col = 8 if i < b["hp"] else 5
                pyxel.rect(hx, hy, scl(5), scl(5), col)
                pyxel.rectb(hx, hy, scl(5), scl(5), 0)
        elif self.current_level == 3 and self.boss and self.boss["alive"]:
            b = self.boss
            boss_col = 9 if b["phase"]==2 else 8
            pyxel.text(sp(2), spy(2), "TOBIAS", boss_col)
            for i in range(b["max_hp"]):
                hx = sp(2+i*7); hy = spy(9)
                col = boss_col if i < b["hp"] else 5
                pyxel.rect(hx, hy, scl(5), scl(5), col)
                pyxel.rectb(hx, hy, scl(5), scl(5), 0)

        if self.dead and self.dead_timer > 20:
            pyxel.rect(sp(25), spy(42), scl(110), scl(16), 0)
            pyxel.rectb(sp(25), spy(42), scl(110), scl(16), 8)
            if self.time_up:
                pyxel.text(sp(40), spy(47), "ZEIT IST UM!", 8)
                pyxel.text(sp(36), spy(53), "Checkpoint...", 7)
            else:
                pyxel.text(sp(45), spy(47), "AUTSCHI!", 7)
                pyxel.text(sp(36), spy(53), "Checkpoint...", 7)

    # ================================================================
    #  LEVEL-HINTERGRÜNDE
    # ================================================================
    def _draw_level1_bg(self, cx):
        drect(0, 0, 160, 20, 1)
        wall_offset = int(cx * 0.3) % 160
        for wx in range(-wall_offset, 160+40, 40):
            drect(wx, 20, 38, 96, 2)
            dline(wx+38, 20, wx+38, 116, 1)
            drect(wx+5, 25, 28, 20, 6)
            drect(wx+7, 27, 24, 16, 12)
            dline(wx+19, 27, wx+19, 43, 6)
            dline(wx+7, 35, wx+31, 35, 6)
            drect(wx+7, 27, 5, 4, 7)
            drect(wx+8, 50, 10, 24, 5)
            drect(wx+9, 51, 8, 22, 13)
            dline(wx+13, 51, wx+13, 73, 5)
            dpset(wx+11, 62, 9)
            dpset(wx+15, 62, 9)
        mid_offset = int(cx * 0.6)
        for bx, btype in self.bg_decos:
            dx = bx - mid_offset
            if dx < -20 or dx > 170: continue
            if btype == 0:
                drect(dx, 45, 14, 18, 8)
                drectb(dx, 45, 14, 18, 0)
                pyxel.text(sp(dx+1), spy(49), "!!", 7)
            elif btype == 1:
                drect(dx, 48, 16, 12, 12)
                drectb(dx, 48, 16, 12, 1)
                pyxel.text(sp(dx+1), spy(51), "EXIT", 7)
            elif btype == 2:
                drect(dx, 73, 12, 30, 4)
                drect(dx+1, 74, 10, 28, 9)
                dline(dx+6, 74, dx+6, 102, 4)
                dpset(dx+3, 88, 10); dpset(dx+9, 88, 10)
            elif btype == 3:
                drect(dx+3, 108, 6, 7, 4)
                dcirc(dx+6, 102, 6, 11)
                dcirc(dx+4, 104, 4, 3)
            elif btype == 4:
                dcirc(dx+7, 35, 7, 13); dcirc(dx+7, 35, 6, 7)
                dline(dx+7, 35, dx+7, 30, 0); dline(dx+7, 35, dx+11, 35, 0)
        lamp_offset = int(cx * 0.8)
        for lx in range(0, 1000, 80):
            lsx = lx - lamp_offset
            if -10 < lsx < 170:
                drect(lsx-1, 0, 10, 3, 13)
                drect(lsx+1, 3, 6, 2, 10)
                dtri(lsx+1, 5, lsx+8, 5, lsx+4, 22, 6)
                dpset(lsx+4, 12, 10)
        # Boden
        drect(0, 116, 160, 4, 4)
        drect(0, 116, 160, 1, 5)
        tile_offset = int(cx) % 20
        for tx in range(-tile_offset, 160, 20):
            dline(tx, 116, tx, 120, 5)
        drect(0, 117, 160, 1, 5)

    def _draw_level2_bg(self, cx):
        drect(0, 0, 160, 12, 6); drect(0, 12, 160, 3, 4)
        dline(0, 15, 160, 15, 9); drect(0, 16, 160, 100, 15)
        for sy in range(20, 116, 16): dline(0, sy, 160, sy, 14)
        drect(0, 110, 160, 6, 4); dline(0, 110, 160, 110, 9)
        # Tafel
        tafel_x = 15 - int(cx*0.3)
        if -60 < tafel_x < 160:
            drect(tafel_x-2, 20, 64, 36, 4); drect(tafel_x, 22, 60, 32, 3)
            drectb(tafel_x, 22, 60, 32, 0)
            pyxel.text(sp(tafel_x+2), spy(24), "HAUSAUFGABE:", 7)
            pyxel.text(sp(tafel_x+2), spy(32), "2+2 = ESCAPE!", 11)
            dline(tafel_x+3, 48, tafel_x+30, 48, 7)
            drect(tafel_x, 55, 60, 3, 4)
            for ci,(cx_,cc) in enumerate([(3,7),(15,8),(25,11),(45,9)]):
                drect(tafel_x+cx_, 54, 6, 2, cc)
            dcirc(tafel_x+50, 35, 7, 7)
            dpset(tafel_x+47, 33, 0); dpset(tafel_x+53, 33, 0)
            dline(tafel_x+47, 38, tafel_x+53, 38, 0)
        # Uhr
        uhr_x = 70 - int(cx*0.3)
        if -20 < uhr_x < 170:
            dcirc(uhr_x, 22, 6, 7); dcircb(uhr_x, 22, 6, 0)
            dline(uhr_x, 22, uhr_x, 18, 0); dline(uhr_x, 22, uhr_x+3, 22, 8)
        # Neonlichter
        lamp_offset = int(cx*0.8)
        for lx in range(40, 800, 90):
            lsx = lx - lamp_offset
            if -10 < lsx < 170:
                drect(lsx-6, 8, 20, 4, 7); drect(lsx-5, 9, 18, 2, 10)
                drectb(lsx-6, 8, 20, 4, 6)
        # Bänke
        desk_off = int(cx*0.5) % 40
        for dx2 in range(-desk_off, 165, 40):
            drect(dx2, 95, 18, 10, 9); drect(dx2+1, 96, 16, 8, 10)
            drect(dx2+2, 97, 6, 4, 7); dpset(dx2+3, 98, 0)
        drect(0, 116, 160, 4, 9); drect(0, 116, 160, 1, 10)
        tile_offset = int(cx) % 24
        for tx in range(-tile_offset, 160, 24): dline(tx, 116, tx, 120, 4)

    def _draw_level3_bg(self, cx):
        for y in range(20):
            pyxel.rect(OX, OY+y*S, 480, S, 0 if y < 10 else 1)
        beam_offset = int(cx*0.2)
        for bx in range(-beam_offset%70, 170, 70):
            drect(bx, 0, 5, 45, 4); drect(bx+1, 0, 3, 45, 9)
            dline(bx, 0, bx+35, 45, 4)
        wall_offset = int(cx*0.35) % 160
        for wy in range(20, 116, 12):
            row_off = (wy//12)%2*12
            for wx in range(-(wall_offset+row_off)%24, 165, 24):
                drect(wx, wy, 22, 10, 2); drectb(wx, wy, 22, 10, 4)
                drect(wx+1, wy+1, 20, 2, 8); dpset(wx+10, wy+5, 3)
        deco_offset = int(cx*0.55)
        for bx, btype in self.bg_decos:
            dx2 = bx - deco_offset
            if dx2 < -25 or dx2 > 175: continue
            if btype == 0:
                drect(dx2, 100, 18, 14, 4); drectb(dx2, 100, 18, 14, 9)
                dline(dx2, 107, dx2+18, 107, 9)
            elif btype == 1:
                drect(dx2+3, 99, 12, 8, 9); drect(dx2, 101, 18, 4, 9)
            elif btype == 2:
                dcircb(dx2+3, 108, 4, 5); dcircb(dx2+15, 108, 4, 5)
                dline(dx2+3, 108, dx2+15, 108, 5)
            elif btype == 3:
                dline(dx2, 20, dx2+12, 32, 5); dline(dx2+12, 20, dx2, 32, 5)
        lamp_offset = int(cx*0.7)
        for lx in range(20, 1200, 100):
            lsx = lx - lamp_offset
            if -15 < lsx < 175:
                for ky in range(0, 18, 2):
                    dpset(lsx+(1 if (ky//2)%2==0 else -1), ky, 0)
                dcirc(lsx, 20, 3, 10); drect(lsx-1, 23, 3, 2, 13)
                dtri(lsx-10, 30, lsx+10, 30, lsx, 25, 4)
                dcirc(lsx, 24, 5, 9); dcirc(lsx, 24, 3, 10)
        drect(0, 116, 160, 4, 4); drect(0, 116, 160, 1, 9)
        plank_off = int(cx) % 30
        for tx in range(-plank_off, 165, 30): dline(tx, 116, tx, 120, 0)

    def _draw_level4_bg(self, cx):
        screen_left = cx; screen_right = cx + 160
        # Mensa-Bereich
        if screen_left < 600:
            drect(0, 0, 160, 15, 15); dline(0, 15, 160, 15, 4)
            drect(0, 16, 160, 100, 10)
            for wy in range(20, 116, 14): dline(0, wy, 160, wy, 9)
            deco_offset = int(cx*0.4)
            for item in self.bg_decos:
                if len(item)<3 or item[2]!="mensa": continue
                bx, btype = item[0], item[1]; dx2 = bx - deco_offset
                if dx2 < -30 or dx2 > 180: continue
                if btype == 0:
                    drect(dx2, 80, 40, 30, 7); drectb(dx2, 80, 40, 30, 5)
                    dcirc(dx2+10, 90, 4, 5); dcirc(dx2+25, 90, 5, 5)
                elif btype == 1:
                    drect(dx2, 25, 30, 22, 3); drectb(dx2, 25, 30, 22, 4)
                    pyxel.text(sp(dx2+2), spy(28), "MENU", 7)
                elif btype == 2:
                    drect(dx2, 65, 18, 40, 8); drectb(dx2, 65, 18, 40, 0)
                    drect(dx2+2, 68, 14, 20, 1)
            lamp_offset = int(cx*0.7)
            for lx in range(30, 600, 70):
                lsx = lx - lamp_offset
                if -20 < lsx < 180:
                    drect(lsx-12, 3, 24, 5, 7); drect(lsx-10, 4, 20, 3, 10)
                    drectb(lsx-12, 3, 24, 5, 6)
        # Kühllager
        if screen_right > 600 and screen_left < 1100:
            kl_start = max(0, int(600-cx)); kl_end = min(160, int(1100-cx))
            drect(kl_start, 0, kl_end-kl_start, 15, 1)
            for fy in range(0, 15, 3): dline(kl_start, fy, kl_end, fy, 12)
            drect(kl_start, 16, kl_end-kl_start, 100, 5)
            for wy in range(20, 116, 10): dline(kl_start, wy, kl_end, wy, 13)
            # Frost-Partikel
            if self.spike_blink % 5 == 0:
                for px2 in range(kl_start, kl_end, 15):
                    py2 = (self.spike_blink*3+px2)%100+15
                    dpset(px2, py2, 7)
        # Küchenbereich
        if screen_right > 1100:
            k_start = max(0, int(1100-cx))
            drect(k_start, 0, 160-k_start, 15, 6)
            dline(k_start, 14, 160, 14, 13)
            drect(k_start, 16, 160-k_start, 100, 7)
            for wy in range(20, 116, 12): dline(k_start, wy, 160, wy, 6)
        # Boden
        if screen_left < 600:
            end_x = min(160, int(600-cx))
            drect(0, 116, end_x, 4, 9); drect(0, 116, end_x, 1, 10)
            tile_off = int(cx) % 16
            for tx in range(-tile_off, end_x, 16): dline(tx, 116, tx, 120, 4)
        if screen_right > 600 and screen_left < 1100:
            start_x = max(0, int(600-cx)); end_x = min(160, int(1100-cx))
            drect(start_x, 116, end_x-start_x, 4, 12)
            drect(start_x, 116, end_x-start_x, 1, 7)
        if screen_right > 1100:
            start_x = max(0, int(1100-cx))
            drect(start_x, 116, 160-start_x, 4, 7)
            drect(start_x, 116, 160-start_x, 1, 6)

    # ================================================================
    #  GEMEINSAME DRAW-ELEMENTE
    # ================================================================
    def _draw_common(self, cx):
        # ---- Plattformen (mit Unterseite/Tiefe) ----
        for px2, py, pw, ph in self.platforms:
            sx = px2 - cx
            if sx > 170 or sx+pw < -10: continue
            # Tiefe der Plattform (untere Seite)
            depth = 3
            if self.current_level == 2:
                drect(sx, py, pw, ph, 9)
                drect(sx, py, pw, 1, 10)
                drect(sx, py+ph-1, pw, 1, 4)
                # Plattform-Unterseite (gibt dem Springen Tiefe)
                drect(sx+1, py+ph, pw-1, depth, 4)
                drect(sx+2, py+ph, pw-3, 1, 0)
            elif self.current_level == 3:
                drect(sx, py, pw, ph, 4)
                drect(sx, py, pw, 1, 10)
                drect(sx, py+ph-1, pw, 1, 0)
                drect(sx+1, py+ph, pw-1, depth, 2)
                dline(sx+3, py+1, sx+3, py+ph-2, 9)
            elif self.current_level == 4:
                if px2 < 600:
                    drect(sx, py, pw, ph, 9)
                    drect(sx, py, pw, 1, 10)
                    drect(sx+1, py+ph, pw-1, depth, 4)
                else:
                    drect(sx, py, pw, ph, 13)
                    drect(sx, py, pw, 1, 7)
                    drect(sx+1, py+ph, pw-1, depth, 5)
            else:
                drect(sx, py, pw, ph, 5)
                drect(sx, py, pw, 1, 6)
                drect(sx, py+ph-1, pw, 1, 4)
                # Plattform-Unterseite (braun, gibt Tiefe)
                drect(sx+1, py+ph, pw-1, depth, 4)
                drect(sx+2, py+ph, pw-2, 1, 0)

        # Boden-Rendering: Der Boden unter den Spielern klar darstellen
        # (eine sichtbare Linie, die anzeigt dass da ein Boden ist)
        if self.current_level != 4 or cx < 600:
            pass  # Boden wird vom Level-BG gezeichnet

        # ---- Bewegliche Plattformen ----
        if self.current_level in (3, 4):
            for mp in self.moving_platforms:
                sx = mp[0]-cx; py = mp[1]; pw,ph = mp[2],mp[3]
                if -10 < sx < 175:
                    col = 9 if self.current_level==4 else 8
                    drect(sx, py, pw, ph, col)
                    drect(sx, py, pw, 1, 10)
                    drect(sx+1, py+ph, pw-1, 3, 4 if col==9 else 0)
                    mid = sx+pw//2
                    if mp[4]==1: dtri(mid, py+1, mid-3, py+3, mid+3, py+3, 7)
                    else:        dtri(mid, py+3, mid-3, py+1, mid+3, py+1, 7)

        # ---- Eisböden ----
        if self.current_level == 4:
            for ice in self.ice_floors:
                if ice[5]: continue
                sx = ice[0]-cx
                if -10 < sx < 175:
                    ice_col = 12 if ice[6] < 2 else 7
                    drect(sx, ice[1], ice[2], ice[3], ice_col)
                    drect(sx, ice[1], ice[2], 1, 7)
                    dpset(sx+ice[2]//3, ice[1], 6)
                    # Riss-Stufen
                    if ice[6] >= 1: dline(sx+5, ice[1], sx+10, ice[1]+3, 5)
                    if ice[6] >= 2: dline(sx+15, ice[1]+1, sx+20, ice[1]+3, 5)
                    if ice[6] >= 3:
                        if self.spike_blink < 5: drectb(sx-1, ice[1]-1, ice[2]+2, ice[3]+2, 8)

        # ---- Gruben ----
        for px2, py_end in self.pits:
            sx = px2-cx; ew = py_end-px2
            if sx > 160 or sx+ew < 0: continue
            drect(sx, 116, ew, 4, 0)
            dline(sx, 116, sx, 120, 1)
            dline(sx+ew, 116, sx+ew, 120, 1)
            dline(sx, 116, sx+ew, 116, 8)

        # ---- Stacheln ----
        spike_color = 7 if self.spike_blink < 10 else 8
        for sx_raw, sy_raw in self.spikes:
            ssx = sx_raw-cx
            if -10 < ssx < 170:
                if self.current_level == 4:
                    for i in range(4):
                        tx = ssx+i*3
                        dtri(tx, sy_raw+5, tx+1, sy_raw, tx+3, sy_raw+5, 7)
                    drect(ssx, sy_raw+4, 12, 2, 6)
                else:
                    for i in range(3):
                        tx = ssx+i*4
                        dtri(tx, sy_raw+6, tx+2, sy_raw, tx+4, sy_raw+6, spike_color)
                    drect(ssx, sy_raw+5, 12, 1, 13)

        # ---- Eiszapfen ----
        for ic in self.icicles:
            if not ic[6]: continue
            isx = ic[0]-cx
            if -10 < isx < 170:
                isy = ic[1]; iw,ih = ic[2],ic[3]
                drect(isx, isy, iw, ih-4, 12)
                dtri(isx, isy+ih-4, isx+iw, isy+ih-4, isx+iw//2, isy+ih, 7)
                drect(isx+1, isy, 1, ih-6, 7)
                if ic[4] and self.spike_blink < 5: drectb(isx-1, isy-1, iw+2, ih+2, 8)

        # ---- Patties ----
        if self.current_level == 4:
            for patty in self.patties:
                if not patty[3]:
                    if patty[6]:
                        psx = patty[0]-cx
                        if -15 < psx < 175: drect(psx, 112, 10, 2, 4)
                    continue
                psx = patty[0]-cx; psy = patty[1]
                if -15 < psx < 175:
                    drect(psx, psy+2, 10, 6, 4)
                    drect(psx+1, psy+1, 8, 2, 9)
                    dpset(psx+3, psy+3, 10); dpset(psx+7, psy+2, 10)
                    eye_x = 3 if patty[2]==1 else 1
                    dpset(psx+eye_x, psy+4, 7); dpset(psx+eye_x+4, psy+4, 7)
                    dline(psx+eye_x-1, psy+3, psx+eye_x+2, psy+3, 8)
                    foot_off = patty[4]*2
                    drect(psx+1, psy+8, 3, 2-foot_off, 9)
                    drect(psx+6, psy+8, 3, 2+foot_off-1, 9)

            # ---- Burritos ----
            for b in self.burritos:
                if not b[3]:
                    if b[6]:
                        bsx = b[0]-cx
                        if -15 < bsx < 175:
                            drect(bsx, 112, 10, 2, 12); dpset(bsx+2, 113, 7)
                    continue
                bsx = b[0]-cx; bsy = b[1]
                if -15 < bsx < 175:
                    shiver = b[7]%60 < 10
                    so = 1 if (shiver and b[7]%4<2) else 0
                    drect(bsx+so, bsy+4, 10, 8, 7)
                    drect(bsx+so+1, bsy+5, 8, 6, 12)
                    drect(bsx+so, bsy+4, 10, 2, 6)
                    dpset(bsx+so+2, bsy+5, 7); dpset(bsx+so+7, bsy+7, 7)
                    dpset(bsx+so+4, bsy+9, 12)
                    eye_x = 4 if b[2]==1 else 1
                    dpset(bsx+so+eye_x, bsy+6, 8); dpset(bsx+so+eye_x+3, bsy+6, 8)
                    if shiver: dpset(bsx+so+5, bsy+3, 12); dpset(bsx+so+3, bsy+2, 7)
                    foot_off = b[4]
                    drect(bsx+so+1, bsy+12, 3, 2+foot_off, 12)
                    drect(bsx+so+6, bsy+12, 3, 2-foot_off+1, 12)
                    if shiver and self.spike_blink<8:
                        drectb(bsx+so-1, bsy+3, 12, 12, 12)

        # ---- Münzen ----
        for coin in self.coins:
            if not coin[2]:
                ccx = coin[0]-cx; ccy = coin[1]
                if -10 < ccx < 170:
                    if self.current_level == 4:
                        drect(ccx, ccy, 6, 6, 10)
                        drectb(ccx, ccy, 6, 6, 9)
                        dpset(ccx+2, ccy+2, 7); dpset(ccx+3, ccy+3, 7)
                    else:
                        dcirc(ccx+3, ccy+3, 3, 10)
                        dcirc(ccx+3, ccy+3, 2, 9)
                        dpset(ccx+2, ccy+2, 7); dpset(ccx+4, ccy+4, 4)

        # ---- Checkpoints ----
        if self.current_level == 1:
            drect(78-cx, 111, 4, 5, 11)
        if self.current_level == 4:
            for cp_x, label in [(590,"KALT"),(1090,"EXIT")]:
                cpsx = cp_x-cx
                if -20 < cpsx < 175:
                    drect(cpsx, 100, 4, 16, 4)
                    drect(cpsx-8, 98, 20, 10, 10)
                    drectb(cpsx-8, 98, 20, 10, 9)
                    pyxel.text(sp(cpsx-6), spy(101), label, 0)

        # ---- Fahne ----
        fx = self.exit_x-cx; fy = self.exit_y
        dline(fx+4, fy-8, fx+4, fy+16, 7)
        dline(fx+5, fy-8, fx+5, fy+16, 13)
        if self.exit_unlocked:
            if self.flag_frame == 0: dtri(fx+5, fy-8, fx+20, fy-2, fx+5, fy+6, 11)
            else:                    dtri(fx+5, fy-8, fx+18, fy,   fx+5, fy+8, 11)
            dpset(fx+4, fy-9, 10)
            if self.flag_frame == 0: drectb(fx+3, fy-10, 20, 28, 11)
        else:
            dtri(fx+5, fy-8, fx+18, fy-2, fx+5, fy+6, 13)
            pyxel.text(sp(fx-8), spy(fy+18), "LOCK", 8)
            dcirc(fx, fy+22, 3, 8)
            drect(fx-2, fy+23, 5, 4, 4)

        # ---- Bosse ----
        if self.current_level == 2 and self.boss and self.boss["alive"]:
            self._draw_boss_florian(cx)
        elif self.current_level == 3 and self.boss and self.boss["alive"]:
            self._draw_boss_tobias(cx)

        # ====================================================
        # SPIELER ZEICHNEN (neue detaillierte Schüler-Sprites)
        # ====================================================
        self._draw_player1(cx)
        self._draw_player2(cx)

    # ================================================================
    #  SPIELER 1: MAX – Schüler mit braunen Haaren + Brille
    # ================================================================
    def _draw_player1(self, cx):
        x = self.p1_x - cx
        y = self.p1_y
        d = self.p1_dir
        f = self.p1_frame
        on_ground = self.p1_on_ground
        vy = self.p1_vy

        # --- Körper (rotes Shirt) ---
        drect(x+1, y+6, 6, 8, 8)   # Shirt
        drect(x+2, y+7, 4, 6, 2)   # Shirt-Schatten

        # --- Beine mit Walk-Animation ---
        if on_ground and (abs(self.p1_vx) > 0.5 or f > 0):
            # Walk-Frames: abwechselnde Beinstellung
            if f % 4 in (0, 2):
                drect(x+1, y+14, 3, 4, 1)   # linkes Bein vor
                drect(x+4, y+14, 3, 3, 1)   # rechtes Bein zurück
                drect(x+0, y+17, 4, 1, 0)   # linker Schuh
                drect(x+4, y+16, 4, 1, 0)   # rechter Schuh
            else:
                drect(x+1, y+14, 3, 3, 1)   # linkes Bein zurück
                drect(x+4, y+14, 3, 4, 1)   # rechtes Bein vor
                drect(x+0, y+16, 4, 1, 0)   # linker Schuh
                drect(x+4, y+17, 4, 1, 0)   # rechter Schuh
        else:
            # Stand oder Sprung
            drect(x+1, y+14, 3, 4, 1)
            drect(x+4, y+14, 3, 4, 1)
            drect(x+0, y+17, 4, 1, 0)
            drect(x+4, y+17, 4, 1, 0)

        # --- Arme (Walk-Gegenschwung) ---
        if d == 1:  # rechts schauend
            if on_ground and f % 4 in (1, 3):
                drect(x+0, y+7, 2, 5, 8)   # linker Arm vor
                drect(x+7, y+8, 2, 4, 8)   # rechter Arm zurück
            else:
                drect(x+0, y+8, 2, 4, 8)
                drect(x+7, y+7, 2, 5, 8)
        else:       # links schauend
            if on_ground and f % 4 in (1, 3):
                drect(x+6, y+7, 2, 5, 8)
                drect(x+0, y+8, 2, 4, 8)
            else:
                drect(x+6, y+8, 2, 4, 8)
                drect(x+0, y+7, 2, 5, 8)

        # --- Kopf ---
        drect(x+1, y+0, 6, 6, 15)   # Gesicht (Hautton)

        # --- BRAUNE HAARE ---
        drect(x+1, y+0, 6, 2, 4)    # Haar oben
        dpset(x+0, y+1, 4)           # Seite links
        dpset(x+7, y+1, 4)           # Seite rechts
        dpset(x+0, y+2, 4)
        dpset(x+7, y+2, 4)
        # Haarstrahnen-Spitze (charakteristisch für Max)
        if d == 1:
            dpset(x+6, y+0, 4)
            dpset(x+7, y+0, 0)      # eine Strähne rechts
        else:
            dpset(x+1, y+0, 4)
            dpset(x+0, y+0, 0)

        # --- BRILLE ---
        # Linkes Glas
        dpset(x+2, y+3, 0)
        dpset(x+3, y+3, 12)
        dpset(x+2, y+4, 12)
        dpset(x+3, y+4, 1)
        # Rechtes Glas
        dpset(x+5, y+3, 0)
        dpset(x+6, y+3, 12)
        dpset(x+5, y+4, 12)
        dpset(x+6, y+4, 1)
        # Brillensteg
        dpset(x+4, y+3, 0)

        # --- Mund (Richtungsabhängig) ---
        if d == 1:
            dpset(x+5, y+5, 0)
        else:
            dpset(x+2, y+5, 0)

        # --- Rucksack (immer auf der dem Betrachter abgewandten Seite) ---
        if d == 1:
            drect(x-1, y+5, 2, 6, 12)   # Rucksack links
            dpset(x-1, y+7, 7)
        else:
            drect(x+7, y+5, 2, 6, 12)
            dpset(x+8, y+7, 7)

        # --- Sprung-Squash-Animation ---
        if not on_ground and vy < -2:
            # Strecken beim Hochsprung
            dpset(x+3, y-1, 15)
            dpset(x+4, y-1, 15)

    # ================================================================
    #  SPIELER 2: LISA – Schülerin mit braunen Haaren + runder Brille
    # ================================================================
    def _draw_player2(self, cx):
        x = self.p2_x - cx
        y = self.p2_y
        d = self.p2_dir
        f = self.p2_frame
        on_ground = self.p2_on_ground
        vy = self.p2_vy

        # --- Körper (lila/violettes Shirt) ---
        drect(x+1, y+6, 6, 8, 11)   # Shirt
        drect(x+2, y+7, 4, 6, 3)    # Shirt-Schatten

        # --- Beine mit Walk-Animation ---
        if on_ground and (abs(self.p2_vx) > 0.5 or f > 0):
            if f % 4 in (0, 2):
                drect(x+1, y+14, 3, 4, 3)
                drect(x+4, y+14, 3, 3, 3)
                drect(x+0, y+17, 4, 1, 9)   # Schuh (orange/braun für Lisa)
                drect(x+4, y+16, 4, 1, 9)
            else:
                drect(x+1, y+14, 3, 3, 3)
                drect(x+4, y+14, 3, 4, 3)
                drect(x+0, y+16, 4, 1, 9)
                drect(x+4, y+17, 4, 1, 9)
        else:
            drect(x+1, y+14, 3, 4, 3)
            drect(x+4, y+14, 3, 4, 3)
            drect(x+0, y+17, 4, 1, 9)
            drect(x+4, y+17, 4, 1, 9)

        # --- Arme ---
        if d == 1:
            if on_ground and f % 4 in (1, 3):
                drect(x+0, y+7, 2, 5, 11)
                drect(x+7, y+8, 2, 4, 11)
            else:
                drect(x+0, y+8, 2, 4, 11)
                drect(x+7, y+7, 2, 5, 11)
        else:
            if on_ground and f % 4 in (1, 3):
                drect(x+6, y+7, 2, 5, 11)
                drect(x+0, y+8, 2, 4, 11)
            else:
                drect(x+6, y+8, 2, 4, 11)
                drect(x+0, y+7, 2, 5, 11)

        # --- Kopf ---
        drect(x+1, y+0, 6, 6, 15)

        # --- BRAUNE HAARE (Lisa hat längere Haare + Zopf-Detail) ---
        drect(x+1, y+0, 6, 2, 4)    # Haar oben
        dpset(x+0, y+1, 4)
        dpset(x+7, y+1, 4)
        dpset(x+0, y+2, 4)
        dpset(x+7, y+2, 4)
        dpset(x+0, y+3, 4)          # Längere Seiten (Zopf-Ansatz)
        dpset(x+7, y+3, 4)
        dpset(x+0, y+4, 4)
        dpset(x+7, y+4, 4)
        # Kleines Haarband (charakteristisch)
        if d == 1:
            dpset(x+7, y+2, 8)     # Haarband rechts (rot)
            dpset(x+7, y+3, 8)
        else:
            dpset(x+0, y+2, 8)     # Haarband links
            dpset(x+0, y+3, 8)

        # --- RUNDE BRILLE (sieht anders aus als Max) ---
        # Runde Form durch 4 Pixel pro Glas
        dpset(x+2, y+2, 0)
        dpset(x+3, y+3, 12)
        dpset(x+2, y+4, 12)
        dpset(x+3, y+2, 12)
        dpset(x+5, y+2, 0)
        dpset(x+6, y+3, 12)
        dpset(x+5, y+4, 12)
        dpset(x+6, y+2, 12)
        # Brillensteg (rund = geschwungen)
        dpset(x+4, y+3, 0)
        # Augen dahinter
        dpset(x+2, y+3, 1)
        dpset(x+5, y+3, 1)

        # --- Mund ---
        if d == 1:
            dpset(x+5, y+5, 0)
        else:
            dpset(x+2, y+5, 0)

        # --- Rucksack (grün) ---
        if d == 1:
            drect(x-1, y+5, 2, 6, 3)
            dpset(x-1, y+7, 10)
        else:
            drect(x+7, y+5, 2, 6, 3)
            dpset(x+8, y+7, 10)

        # --- Sprung ---
        if not on_ground and vy < -2:
            dpset(x+3, y-1, 15)
            dpset(x+4, y-1, 15)

    # ================================================================
    #  BOSS: HERR FLORIAN (Level 2 Lehrer)
    # ================================================================
    def _draw_boss_florian(self, cx):
        b = self.boss
        bx = int(b["x"])-cx; by = int(b["y"])
        if b["stun_timer"] > 0 and b["stun_timer"]%4 < 2: return
        # Körper (dunkler Anzug)
        drect(bx+1, by+6, 10, 10, 5)
        drect(bx+3, by+6, 6, 4, 7)   # Hemd
        dtri(bx+6, by+6, bx+8, by+6, bx+7, by+14, 8)  # Krawatte
        # Kopf
        drect(bx+2, by, 8, 7, 15)
        # GRAUE HAARE (Lehrer ist älter)
        drect(bx+2, by, 8, 2, 6)
        dpset(bx+1, by+1, 6); dpset(bx+10, by+1, 6)
        # BRILLE (eckig, streng)
        dpset(bx+2, by+2, 0); dpset(bx+4, by+2, 0)
        dpset(bx+3, by+2, 12); dpset(bx+3, by+3, 12)
        dpset(bx+6, by+2, 0); dpset(bx+8, by+2, 0)
        dpset(bx+7, by+2, 12); dpset(bx+7, by+3, 12)
        dpset(bx+5, by+2, 0)   # Steg
        # Böse Augenbrauen
        if b["dir"]==1:
            dline(bx+2, by+1, bx+4, by+2, 0)
            dline(bx+6, by+2, bx+9, by+1, 0)
        else:
            dline(bx+2, by+1, bx+4, by+2, 0)
            dline(bx+6, by+2, bx+9, by+1, 0)
        # Mund (dünner strenger Strich)
        dline(bx+3, by+6, bx+9, by+6, 0)
        # Hut
        drect(bx+1, by-2, 10, 3, 5)
        drect(bx+3, by-5, 6, 3, 5)
        dpset(bx+6, by-5, 9)
        # Beine
        leg_off = b["frame"]*2
        drect(bx+2, by+16, 3, 5-leg_off, 1)
        drect(bx+7, by+16, 3, 3+leg_off, 1)
        drect(bx+1, by+20, 4, 1, 0)
        drect(bx+6, by+18+leg_off//2, 4, 1, 0)
        # Aktentasche
        if b["dir"]==1:
            drect(bx+12, by+8, 6, 5, 4)
            drectb(bx+12, by+8, 6, 5, 9)
            dpset(bx+14, by+10, 10)
        else:
            drect(bx-6, by+8, 6, 5, 4)
            drectb(bx-6, by+8, 6, 5, 9)
            dpset(bx-4, by+10, 10)
        # Projektile (Kreide)
        for proj in b["projectiles"]:
            if not proj[3]: continue
            px2 = int(proj[0])-cx; py2 = int(proj[1])
            if -5 < px2 < 165:
                drect(px2, py2, 4, 2, 7)
                dpset(px2+1, py2, 13)

    # ================================================================
    #  BOSS: HERR TOBIAS (Level 3 Schulleiter)
    # ================================================================
    def _draw_boss_tobias(self, cx):
        b = self.boss
        bx = int(b["x"])-cx; by = int(b["y"])
        if b["stun_timer"] > 0 and b["stun_timer"]%4 < 2: return
        phase_col = 9 if b["phase"]==2 else 8
        # Körper (größer, imposanter)
        drect(bx+1, by+7, 12, 11, 1)
        drect(bx+4, by+7, 6, 5, 7)   # Hemd
        dtri(bx+8, by+7, bx+10, by+7, bx+9, by+17, phase_col)  # Krawatte (farbig je Phase)
        # Kopf
        drect(bx+2, by, 10, 8, 15)
        # WENIG BRAUNE HAARE (fast kahl)
        drect(bx+2, by, 10, 2, 4)
        dpset(bx+1, by+1, 4); dpset(bx+12, by+1, 4)
        # GOLDENE RUNDE BRILLE
        dpset(bx+3, by+3, 10); dpset(bx+4, by+2, 10)
        dpset(bx+4, by+4, 10); dpset(bx+3, by+4, 12)
        dpset(bx+8, by+3, 10); dpset(bx+9, by+2, 10)
        dpset(bx+9, by+4, 10); dpset(bx+8, by+4, 12)
        dpset(bx+6, by+3, 10)  # Steg
        # Böse Augenbrauen (buschig)
        dline(bx+2, by+1, bx+5, by+2, 0)
        dline(bx+2, by+2, bx+5, by+3, 0)
        dline(bx+7, by+2, bx+11, by+1, 0)
        dline(bx+7, by+3, bx+11, by+2, 0)
        # Mund
        dline(bx+4, by+6, bx+10, by+6, 0)
        dline(bx+4, by+7, bx+10, by+7, 0)
        # Imposanter Hut
        drect(bx+1, by-4, 12, 4, 5)
        drect(bx+3, by-7, 8, 4, 5)
        dpset(bx+7, by-7, 9)
        dpset(bx+8, by-7, 10)   # Abzeichen
        # Beine
        leg_off = b["frame"]*2
        drect(bx+2, by+18, 4, 5-leg_off, 1)
        drect(bx+8, by+18, 4, 3+leg_off, 1)
        drect(bx+1, by+22, 5, 1, 0)
        drect(bx+7, by+20+leg_off//2, 5, 1, 0)
        # Aktentasche (dicker)
        if b["dir"]==1:
            drect(bx+13, by+9, 7, 8, 4)
            drectb(bx+13, by+9, 7, 8, 9)
            drect(bx+15, by+7, 3, 4, 4)
            drectb(bx+15, by+7, 3, 4, 9)
        else:
            drect(bx-6, by+9, 7, 8, 4)
            drectb(bx-6, by+9, 7, 8, 9)
            drect(bx-4, by+7, 3, 4, 4)
            drectb(bx-4, by+7, 3, 4, 9)
        # Phase-2-Effekt (rot leuchten)
        if b["phase"]==2 and self.spike_blink < 8:
            drectb(bx, by-8, 14, 30, 8)
        # Projektile (Aktenmappen)
        for proj in b["projectiles"]:
            if not proj[3]: continue
            px2 = int(proj[0])-cx; py2 = int(proj[1])
            if -5 < px2 < 165:
                drect(px2, py2, 5, 4, 7)
                dline(px2+1, py2+1, px2+3, py2+1, 0)
                dline(px2+1, py2+2, px2+4, py2+2, 0)


SchoolEscape()