#!!! Создаём окно игры и подлодку

from tkinter import *

#Окно
HEIGHT = 500
WIDTH = 800
window = Tk()
window.title('Bubble Blaster')

#Холст
c = Canvas(window, width=WIDTH, height=HEIGHT, bg='darkblue')
c.pack()


#Подлодка-игрок
ship_id = c.create_polygon(5, 5, 5, 25, 30, 15, fill='red') #красный треугльник
ship_id2 = c.create_oval(0, 0, 30, 30, outline='red') #красный круг без заливки
SHIP_R = 15 #Радиус (размер) подлодки
MID_X = WIDTH / 2 #В этих двух переменных -
MID_Y = HEIGHT / 2 #координаты середины экрана
c.move(ship_id, MID_X, MID_Y) #Перемещает обе части подлодки
c.move(ship_id2, MID_X, MID_Y) #в середину экрана


#!!! Управление подлодкой

SHIP_SPD = 10 #Расстояние на которое сдвигается подлодка при нажатии клавиши
def move_ship(event):
    if event.keysym == 'Up':
        c.move(ship_id, 0, -SHIP_SPD) #Двигает обе части подлодки вверх
        c.move(ship_id2, 0, -SHIP_SPD)
    elif event.keysym == 'Down':
        c.move(ship_id, 0, SHIP_SPD)
        c.move(ship_id2, 0, SHIP_SPD)
    elif event.keysym == 'Left':
        c.move(ship_id, -SHIP_SPD, 0)
        c.move(ship_id2, -SHIP_SPD, 0)
    elif event.keysym == 'Right':
        c.move(ship_id, SHIP_SPD, 0)
        c.move(ship_id2, SHIP_SPD, 0)
c.bind_all('<Key>', move_ship) #Указывает, что надо вызывать функцию move_ship при нажатии любой клавиши.


#!!! Пузыри

from random import randint

bub_id = list() # Создаёт пустые списки для хранения имени (bub_id),
bub_r = list() # радиуса (bub_r) и
bub_speed = list() # скорости (bub_speed) каждого пузыря.

MIN_BUB_R = 10 # Минимальный радиус пузыря: 10,
MAX_BUB_R = 30 # максимальный: 30.
MAX_BUB_SPD = 10 # Максимальная скорость пузыря.
GAP = 100

def create_bubble():
    x = WIDTH + GAP # Задаёт позицию пузыря (GAP нужен, чтобы пузырь точно был за
# видимым экраном)
    y = randint(0, HEIGHT) # на холсте
    
    r = randint(MIN_BUB_R, MAX_BUB_R) # Выбирает случайный радиус пузыря от
                                      # минимального до максимального значения  
    id1 = c.create_oval(x-r, y-r, x+r, y+r, outline='white') # Рисуем пузыри
    
    bub_id.append(id1) # Добавляет имя,
    bub_r.append(r)    # радиус
    bub_speed.append(randint(1, MAX_BUB_SPD)) # и скорость пузыря в списки.


#!!! Движение пузырей

def move_bubbles():
    for i in range(len(bub_id)): # По очереди берёт каждый пузырь из списка
        c.move(bub_id[i], -bub_speed[i], 0) # Двигает пузырь с его скоростью

def get_coords(id_num):
    pos = c.coords(id_num)
    x = (pos[0] + pos[2])/2 # Вычисляет X-координату середины пузыря
    y = (pos[1] + pos[3])/2 # Вычисляет Y-координату середины пузыря
    return x, y

from time import sleep, time # Загружает нужные функции из модуля Time
BUB_CHANGE = 10
#MAIN GAME LOOP ГЛАВНЫЙ ЦИКЛ ИГРЫ!!!
while True:
    if randint(1, BUB_CHANGE) == 1:# Выбирает случайное число от 1 до 10. Если случай-
# ное число = 1, создаёт новый пузырь (в среднем это 1 случай из 10, так что пузырей
# будет не слишком много)
        
        create_bubble() # Вызывает функцию
    move_bubbles() # Вызывает функцию Двигает пузыри
    clean_up_bubs() # Удаляет пузыри, уплывшие за экран.
    window.update() # Обновляет окно, чтобы перерисовывать пузыри в новых позициях
    sleep(0.01) # Замедляет игру, чтобы играть было не слишком сложно


#!!! Пузыри лопаются

def del_bubble(i): # Удаляет пузырь, имя которого в i
    del bub_r[i] # Удаляет пузырь из списка радиусов
    del bub_speed[i] # и скоростей
    c.delete(bub_id[i]) # Удаляет пузырь с холста
    del bub_id[i] # Удаляет пузырь из списка имён

def clean_up_bubs(): # Удаляет пузыри, уплывшие за пределы холста
    for i in range(len(bub_id)-1, -1, -1): # Обратный цикл по списку пузырей -
# чтобы избежать ошибки работы for при удалении пузырей
        x, y = get_coords(bub_id[i]) # Находит координаты пузыря
        if x < -GAP:
            del_bubble(i) # Если пузырь уплыл за экран, его нужно удалить, иначе он будет
# замедлять игру (-GAP, чтобы пузырь уплыл за экран полностью, а потом там пропал)           



