from machine import Pin, SPI, Timer, PWM
from ssd1306 import SSD1306_SPI
import dino_bitmaps as bm
import framebuf
import random
import time

# Инициализация SPI и дисплея
spi = SPI(0, baudrate=1000000, mosi=Pin(3), sck=Pin(2))
#oled = SSD1306_SPI(128, 64, spi, Pin(27),Pin(26), Pin(28))
oled = SSD1306_SPI(128, 64, spi, Pin(6), Pin(5), Pin(7))
#oled = SSD1306_SPI(128, 64, spi, Pin(6), Pin(5), Pin(7))

# Определяем пин для подключения динамика
buzzer = machine.PWM(machine.Pin(29))


# Функция для отрисовки битмапов
def draw_bitmap(x, y, bitmap, w, h):
    fb = framebuf.FrameBuffer(bitmap, w, h, framebuf.MONO_VLSB)
    oled.blit(fb, x, y)
    
# Функция для воспроизведения звука на динамике
def play_sound(frequency, duration):
    buzzer.freq(frequency)  # Устанавливаем частоту звука
    buzzer.duty_u16(1000)   # Устанавливаем громкость (небольшое значение для тихого звука)
    time.sleep(duration)
    buzzer.duty_u16(0)      # Выключаем звук

# Настройка кнопок
ok_button = Pin(15, Pin.IN, Pin.PULL_UP)
# Определяем пин 27 как выход
vibro_pin = machine.Pin(27, machine.Pin.OUT)

terrane_list = [bm.Terrane1, bm.Terrane2,  bm.Terrane3,
                bm.Terrane4,  bm.Terrane5,  bm.Terrane6]

# Главная игра
def dinosaur_game(best_score):

    while True:
        game_score = 0
        dino_x, dino_y = 5, 45  # координаты динозавра
        terrane_x, terrane_y = 0, 54 # координаты земли
        cloud_x, cloud_y = -32, 0 # координаты облака
        cactus_x, cactus_y = 0, 47  # координаты кактуса
        bird_x, bird_y = -64, 32  # координаты птицы
        cactus_type = 0  # тип кактуса
        dino_mode = 0  # указывает на какой ноге стоит динозавр (0 - на правой, 1 - на левой)
        terrane_speed = 3  # начальная скорость движения
        bird_mode = 0  # вид птицы (0 - крылья вверх, 1 - крылья вниз)
        bird_step = 0  # шаг анимации птицы
        jump_y = 0  # высота прыжка
        jump_speed = 0  # скорость прыжка
        delay = 0  # задержка анимации
        bird_delay = 0  # задержка анимации птицы
        terrane_1 = bm.Terrane3
        terrane_2 = bm.Terrane6
        vibro_pin.value(0)

        while True:
            oled.fill(0)
            delay += 1
            bird_delay += 1

            # Обработка прыжка
            if ok_button.value() == 0 and jump_y == 0:
                jump_speed = -8
                play_sound(2000, 0.1)  # Звуковой эффект прыжка
            

            # Прыжок динозавра
            if jump_speed != 0 or jump_y != 0:
                jump_y += jump_speed
                jump_speed += 1
                if jump_y > 0:
                    jump_y = 0
                    jump_speed = 0

            # Переключение режимов динозавра
            if delay > 4:
                dino_mode = not dino_mode
                delay = 0

            # Отрисовка земли
            draw_bitmap(terrane_x, terrane_y, terrane_1, 128, 10)
            draw_bitmap(terrane_x + 128, terrane_y, terrane_2, 128, 10)
            
            # Отрисовка облака
            draw_bitmap(cloud_x, cloud_y, bm.Cloud, 32, 10)

            # Отрисовка динозавра
            if jump_y < 0 and jump_speed < 0:
                draw_bitmap(dino_x, dino_y + jump_y, bm.DinoTailDown, 16, 16)
            elif jump_y < 0:
                draw_bitmap(dino_x, dino_y + jump_y, bm.DinoStandBoth, 16, 16)
            elif dino_mode:
                draw_bitmap(dino_x, dino_y + jump_y, bm.DinoStandL, 16, 16)
            else:
                draw_bitmap(dino_x, dino_y + jump_y, bm.DinoStandR, 16, 16)

            # Переключение режимов птицы
            if bird_delay > 6:
                bird_mode = not bird_mode
                bird_delay = 0

            # Отрисовка птицы
            if bird_x != 0:
                bird_step += 1
                if bird_mode:
                    draw_bitmap(bird_x, bird_y, bm.BirdL, 24, 16)
                else:
                    draw_bitmap(bird_x, bird_y, bm.BirdR, 24, 16)

            # Отрисовка кактуса
            if cactus_x != 0:
                if cactus_type == 0:
                    draw_bitmap(cactus_x, cactus_y, bm.CactusSmall, 16, 16)
                else:
                    draw_bitmap(cactus_x, cactus_y, bm.CactusBig, 24, 16)

            if (game_score//1000)%2 > 0:
                oled.invert(1)  # дневной режим
            else:
                oled.invert(0)
            oled.show()

            # Проверка столкновений
            if cactus_x < 12 and cactus_x > 0 and jump_y == 0:
                draw_bitmap(dino_x, dino_y - jump_y, bm.DinoStandDie, 16, 16)
                oled.show()
                vibro_pin.value(1)
                break

            """
            if bird_x < 12 and bird_x > 0 and (jump_y < bird_y or jump_y > bird_y + 12):
                draw_bitmap(dino_x, dino_y - jump_y, bm.DinoStandDie, 16, 16)
                oled.show()
                break
            """

            # Движение земли
            terrane_x -= terrane_speed
            if terrane_x < -128:
                terrane_x = 0
                terrane_1 = terrane_2
                terrane_2 = random.choice(terrane_list)
                

            # Движение кактуса
            cactus_x -= terrane_speed
            if cactus_x < -32:
                cactus_x = random.randint(128, 256)
                cactus_type = random.randint(0, 1)
            if cactus_x in range(bird_x - 64, bird_x + 64):
                cactus_x = -64
                
            # Движение облака
            cloud_x -= int(terrane_speed/2)
            if cloud_x < -32:
                cloud_x = random.randint(128, 1024)
                cloud_y = random.randint(0, 16)

            # Движение птицы
            bird_x -= terrane_speed
            if bird_x < -24:
                bird_x = random.randint(128, 1024)
                bird_y = random.randint(0, 32)
            if bird_x in range(cactus_x - 64, cactus_x + 64):
                bird_x = -64

            time.sleep(0.05)
            game_score += 1

            # Увеличение сложности игры
            if game_score % 100 == 0:
                terrane_speed += 1

        if game_score > best_score:
            best_score = game_score
            
        vibro_pin.value(1)
        time.sleep(1)
        vibro_pin.value(0)
        draw_bitmap(52, 24, bm.RepeatButton, 29, 23)
        oled.show()
        while True:
            if ok_button.value() == 0:
                time.sleep(0.2)
                break

best_score = 0  # Здесь может быть загружен лучший результат из памяти
# Запуск игры
dinosaur_game(best_score)
