from random import randint
from math import *
import pyxel

class game():
    def __init__(self):
        self.level = [[randint(0, 15) for x in range(32)] for y in range(32)]
        self.dir = 0
        self.x = 35
        self.y = 34.14
        self.vel = 0
        self.velDir = 0

        self.vehicle = "car"
        self.menu_active = True
        self.menu_selection = 0  # 0 = Auto, 1 = Motorrad

        self.anim_frame = 0
        self.anim_timer = 0
        self.turn_state = 0
        self.is_accelerating = False
        self.exhaust_timer = 0
        self.exhaust_particles = []
        self.bob_timer = 0

        pyxel.init(160, 100)
        pyxel.load("resx.pyxres")
        pyxel.run(self.controls, self.draw)

    # ── Menü ────────────────────────────────────────────────────────────────

    def controls_menu(self):
        if pyxel.btnp(pyxel.KEY_LEFT) or pyxel.btnp(pyxel.KEY_RIGHT):
            self.menu_selection = 1 - self.menu_selection
        if pyxel.btnp(pyxel.KEY_RETURN) or pyxel.btnp(pyxel.KEY_SPACE):
            self.vehicle = "car" if self.menu_selection == 0 else "bike"
            self.menu_active = False

    def draw_auto_pixel(self, ax, ay, selected):
        c = 11 if selected else 5
        # Karosserie oben
        for dx in range(3, 9):
            pyxel.rect(ax + dx*2, ay, 2, 2, 12)
        # Karosserie mitte
        pyxel.rect(ax, ay+2, 2, 2, c)
        for dx in range(1, 8):
            shade = 7 if 2 <= dx <= 5 else 12
            pyxel.rect(ax + dx*2, ay+2, 2, 2, shade)
        pyxel.rect(ax+16, ay+2, 2, 2, c)
        # Karosserie unten
        for dx in range(0, 10):
            pyxel.rect(ax + dx*2, ay+4, 2, 2, c)
        # Unterboden
        pyxel.rect(ax, ay+6, 2, 2, 1)
        pyxel.rect(ax+4, ay+6, 2, 2, 0)
        for dx in [1, 3, 4, 5, 7, 9]:
            pyxel.rect(ax + dx*2, ay+6, 2, 2, 1)
        pyxel.rect(ax+12, ay+6, 2, 2, 0)
        # Räder
        for wx in [2, 8]:
            pyxel.rect(ax + wx*2,   ay+8, 2, 2, 5)
            pyxel.rect(ax + wx*2+2, ay+8, 2, 2, 13)
            pyxel.rect(ax + wx*2+4, ay+8, 2, 2, 5)
            pyxel.pset(ax + wx*2+2, ay+8, 7)
        # Scheinwerfer
        pyxel.rect(ax+18, ay+2, 2, 1, 10)
        # Auswahlrahmen
        pyxel.rectb(ax-2, ay-2, 24, 14, c)
        pyxel.text(ax+2, ay+13, "AUTO", c)

    def draw_bike_pixel(self, mx, my, selected):
        c = 11 if selected else 5
        # Hinterrad
        for dx, dy in [(1,4),(2,3),(3,2),(4,3),(5,4),(2,4),(3,4),(4,4)]:
            pyxel.rect(mx + dx*2, my + dy*2, 2, 2, 13 if dy < 4 else 5)
        pyxel.pset(mx+6, my+6, 7)
        # Rahmen rot
        for dx, dy in [(6,4),(7,3),(8,2),(9,2),(10,3)]:
            pyxel.rect(mx + dx*2, my + dy*2, 2, 2, 8)
        # Tank
        for dx in [8, 9]:
            pyxel.rect(mx + dx*2, my, 2, 2, 2)
        pyxel.rect(mx+20, my+2, 2, 2, 2)
        pyxel.rect(mx+16, my+2, 4, 1, 7)
        # Sitz
        pyxel.rect(mx+14, my+1, 4, 1, 13)
        # Lenker
        pyxel.rect(mx+24, my, 1, 3, 6)
        pyxel.rect(mx+22, my, 4, 1, 7)
        # Vorderrad
        for dx, dy in [(12,4),(13,3),(14,4)]:
            pyxel.rect(mx + dx*2, my + dy*2, 2, 2, 5)
        pyxel.rect(mx+26, my+6, 2, 2, 13)
        pyxel.pset(mx+26, my+7, 7)
        # Gabel
        pyxel.rect(mx+24, my+4, 1, 3, 6)
        pyxel.rect(mx+26, my+4, 1, 3, 6)
        # Auspuff
        pyxel.rect(mx+2, my+9, 18, 1, 7)
        pyxel.rect(mx,   my+9,  2, 1, 6)
        # Auswahlrahmen
        pyxel.rectb(mx-2, my-2, 34, 14, c)
        pyxel.text(mx, my+13, "MOTORRAD", c)

    def draw_menu(self):
        pyxel.cls(0)
        pyxel.text(47, 8, "FAHRZEUG WAHLEN", 7)
        pyxel.line(20, 16, 140, 16, 5)

        self.draw_auto_pixel(15, 24, self.menu_selection == 0)
        self.draw_bike_pixel(90, 24, self.menu_selection == 1)

        if self.menu_selection == 0:
            pyxel.text(15, 39, "*", 10)
        else:
            pyxel.text(90, 39, "*", 10)

        pyxel.line(0, 82, 160, 82, 5)
        pyxel.text(20, 86, "< >  WAHLEN   ENTER  START", 6)

    # ── Spiel ───────────────────────────────────────────────────────────────

    def controls(self):
        if self.menu_active:
            self.controls_menu()
            return

        left  = pyxel.btn(pyxel.KEY_LEFT)
        right = pyxel.btn(pyxel.KEY_RIGHT)
        up    = pyxel.btn(pyxel.KEY_UP)
        down  = pyxel.btn(pyxel.KEY_DOWN)

        if self.vehicle == "bike":
            accel    = 0.014
            turn     = 0.0083
            drag     = 0.984
            rot_drag = 0.88
        else:
            accel    = 0.013
            turn     = 0.0079
            drag     = 0.99
            rot_drag = 0.84

        self.vel    += accel    * (down - up)
        self.velDir += turn     * (right - left)
        self.vel    *= drag
        self.velDir *= rot_drag
        self.dir    += self.velDir
        self.x      += self.vel * sin(self.dir - 80.11061)
        self.y      += self.vel * cos(self.dir - 80.11061)

        if left and not right:
            self.turn_state = -1
        elif right and not left:
            self.turn_state = 1
        else:
            self.turn_state = 0

        self.is_accelerating = bool(up)

        self.anim_timer += 1
        if self.anim_timer >= 6:
            self.anim_timer = 0
            self.anim_frame = (self.anim_frame + 1) % 2

        self.bob_timer += 1

        self.exhaust_timer += 1
        if self.is_accelerating and self.exhaust_timer >= 3:
            self.exhaust_timer = 0
            self.exhaust_particles.append({
                "x": 79 + randint(-2, 2),
                "y": 91 + randint(-1, 1),
                "life": randint(6, 12),
                "col": 7 if randint(0, 1) else 13
            })

        for p in self.exhaust_particles:
            p["y"] += 1
            p["life"] -= 1
        self.exhaust_particles = [p for p in self.exhaust_particles if p["life"] > 0]

    def draw(self):
        if self.menu_active:
            self.draw_menu()
            return

        pyxel.cls(6)
        pyxel.rect(0, 0, 160, 10, 5)
        pyxel.rect(0, 10, 160, 15, 12)

        self.multiplier = 64
        for y in range(60):
            self.multiplier *= (100 - self.multiplier) / 100
            self.castX = self.x + 4 * sin(self.dir - 80.11061) + 2.25 * (self.multiplier * sin(self.dir - 90))
            self.castY = self.y + 4 * cos(self.dir - 80.11061) + 2.25 * (self.multiplier * cos(self.dir - 90))
            for x in range(160):
                pyxel.bltm(x, y + 40, 0, int(self.castY * 30), int(self.castX * 30), 1, 1)
                self.castX += (self.multiplier / 80) * sin(self.dir)
                self.castY += (self.multiplier / 80) * cos(self.dir)

        speed = abs(self.vel)
        bob_amp  = 1.5 if speed > 0.05 else 0.5
        bob_freq = 0.18 if speed > 0.05 else 0.07
        bob_y = int(bob_amp * sin(self.bob_timer * bob_freq))
        lean_x = self.turn_state * 2

        if self.turn_state == 0:
            sprite_sy = 32
            flip_w    = 32
        elif self.turn_state == 1:
            sprite_sy = 64
            flip_w    = 32
        else:
            sprite_sy = 64
            flip_w    = -32

        if self.vehicle == "bike":
            sprite_sy += 64   # eigene Bike-Zeilen

        shake_x = randint(-1, 1) if self.is_accelerating and speed > 0.1 else 0

        for p in self.exhaust_particles:
            pyxel.pset(p["x"] + shake_x, p["y"] + bob_y, p["col"])

        pyxel.blt(
            64 + lean_x + shake_x,
            65 + bob_y,
            0, 0, sprite_sy,
            flip_w, 32, 15
        )

        label = "MOTORRAD" if self.vehicle == "bike" else "AUTO"
        pyxel.text(2, 2, label, 7)

game()