# Pyxel Studio

import pyxel
import random

class Game:
    def __init__(self):
        pyxel.init(160, 200, title="Slime Sky Fall")
        pyxel.load("res.pyxres")
        # Spieler
        self.x = 80
        self.y = 20
        self.w = 8
        self.h = 8
        self.speed = 2
        self.fall_speed = 0
        if self.y >= 172:
            self.y = 172
        # Status
        self.timer = 0
        self.max_time = 30 * 20
        self.game_over = False
        self.win = False
        self.ground_visible = False

        # Explosionen (visuell)
        self.explosions = []

        # 💣 Bomben-Explosionen (Gameplay!)
        self.bomb_blasts = []

        # Hindernisse
        self.obstacles = []
        for _ in range(10):
            self.spawn_obstacle()

        # Käfig
        self.cage_x = 70
        self.cage_y = 170
        self.cage_open = False

        pyxel.run(self.update, self.draw)

    def spawn_obstacle(self):
        x = random.randint(0, 150)
        y = random.randint(210, 400)
        typ = random.choice(["plane", "balloon", "bomb"])

        if typ == "plane":
            size = 2
            speed = 1
        else:
            size = 1
            speed = random.uniform(1.5, 3)

        self.obstacles.append([x, y, typ, speed, size])

    def update(self):
        if self.game_over or self.win:
            if pyxel.btnp(pyxel.KEY_R):
                self.__init__()
            return

        self.timer += 1

        # Bewegung
        if pyxel.btn(pyxel.KEY_LEFT):
            self.x -= self.speed
        if pyxel.btn(pyxel.KEY_RIGHT):
            self.x += self.speed

        self.x = max(0, min(152, self.x))

        # Hindernisse
        for obs in self.obstacles:
            obs[1] -= obs[3]

            # 💣 zufällige Explosion
            if obs[2] == "bomb" and random.random() < 0.005:
                bx = obs[0] + 4
                by = obs[1] + 4
                self.bomb_blasts.append([bx, by, 16, 0])  # Radius = 16 (doppelt)
                obs[1] = -50  # verschwindet

            if obs[1] < -40:
                obs[0] = random.randint(0, 150)
                obs[1] = random.randint(210, 300)
                obs[2] = random.choice(["plane", "balloon", "bomb"])

                if obs[2] == "plane":
                    obs[4] = 3
                    obs[3] = 0.8
                else:
                    obs[4] = 1
                    obs[3] = random.uniform(1.5, 3)

        # 💥 Normale Kollision
        for obs in self.obstacles:
            x, y, typ, _, size = obs

            if typ == "plane":
                w, h = 19, 10
                hitbox_offset_x = 3   # ignore nose
                hitbox_offset_y = 2
                w -= 6
                h -= 4
            else:
                w, h = 8, 8
                padding = 2

            if (self.x < x + w and
                self.x + self.w > x and
                self.y < y + h and
                self.y + self.h > y):
                self.create_explosion(self.x + 4, self.y + 4)
                self.game_over = True

        # 💣 Explosion trifft Spieler (Kreis-Kollision)
        for blast in self.bomb_blasts:
            bx, by, radius, frame = blast

            dx = (self.x + 4) - bx
            dy = (self.y + 4) - by

            if dx * dx + dy * dy < radius * radius:
                self.create_explosion(self.x + 4, self.y + 4)
                self.game_over = True

        # Bomben-Explosionen updaten
        for blast in self.bomb_blasts:
            blast[3] += 1
        self.bomb_blasts = [b for b in self.bomb_blasts if b[3] < 20]

        # visuelle Explosionen
        for exp in self.explosions:
            exp[2] += 1
        self.explosions = [e for e in self.explosions if e[2] < 20]

        # Boden
        if self.timer > self.max_time:
            self.ground_visible = True

        if self.ground_visible:
            self.fall_speed += 0.2
            self.y += self.fall_speed

            if self.y >= 172:
                self.y = 172
                self.fall_speed = 0

        # Sieg
        if self.ground_visible:
            if (self.x < self.cage_x + 12 and
                self.x + self.w > self.cage_x and
                self.y < self.cage_y + 10 and
                self.y + self.h > self.cage_y):

                self.win = True
                self.cage_open = True

    def create_explosion(self, x, y):
        if typ == "plane":
            vx = random.choice([-1.5, -1, 1, 1.5])
        else:
            vx = 0
        self.explosions.append([x, y, 0])

    def draw(self):
        pyxel.cls(12)
        
  

        # Spieler
        if not self.game_over:
            pyxel.blt(self.x,self.y,0,0,0,16,16,0)

        # Hindernisse
        for obs in self.obstacles:
            x, y, typ, _, size = obs

            if typ == "plane":
                s = size
                pyxel.blt(x,y,1,0,0,19,10,0)

            elif typ == "balloon":
                pyxel.circ(x + 4, y + 4, 4, 8)
                pyxel.line(x + 4, y + 8, x + 4, y + 12, 0)

            elif typ == "bomb":
                pyxel.circ(x + 4, y + 4, 4, 0)
                pyxel.circ(x + 4, y + 4, 2, 8)

        # 💣 Bomben-Explosionen anzeigen
        for blast in self.bomb_blasts:
            x, y, radius, frame = blast
            pyxel.circb(x, y, radius, 10)
            pyxel.circb(x, y, radius-3, 8)
            shake_x = random.randint(-2,2)
            shake_y = random.randint(-2,2)

        # 💥 kleine Explosion
        for exp in self.explosions:
            x, y, frame = exp
            pyxel.circ(x, y, frame, 10)

        # Timer
        remaining = max(0, (self.max_time - self.timer) // 60)
        pyxel.text(5, 5, f"{remaining}s", 1)

        # Boden + Käfig
        if not self.ground_visible:
            for obs in self.obstacles:
                obs[1] -= obs[3]

            if obs[2] == "bomb" and random.random() < 0.005:
                bx = obs[0] + 4
                by = obs[1] + 4
                self.bomb_blasts.append([bx, by, 16, 0])
                obs[1] = -50

            if obs[1] < -40:
                obs[0] = random.randint(0, 150)
                obs[1] = random.randint(210, 300)
                obs[2] = random.choice(["plane", "balloon", "bomb"])
                
        if self.ground_visible:
            pyxel.rect(0, 180, 160, 20, 3)

            if not self.cage_open:
                pyxel.blt(self.cage_x, self.cage_y, 2, 0, 0, 16, 16, 0)
                pyxel.text(self.cage_x - 6, self.cage_y - 6, "HELP!", 7)
            else:
                pyxel.text(35, 100, "YOU SAVED THEM!", 11)

        # Game Over
        if self.game_over:
            pyxel.text(50, 100, "GAME OVER", 8)
            pyxel.text(40, 110, "Press R to restart", 7)

        # Win
        if self.win:
            pyxel.text(45, 120, "YOU WIN!", 11)
            pyxel.text(40, 130, "Press R to restart", 7)


Game()