Загрузка данных


import tkinter as tk
import random

# Константы
WIDTH = 800
HEIGHT = 600
PLAYER_SIZE = 50
ASTEROID_SIZE = 40
BULLET_SIZE = 10
PLAYER_SPEED = 8
ASTEROID_SPEED = 4
BULLET_SPEED = 12

class Game:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("Космический защитник")
        self.canvas = tk.Canvas(self.window, width=WIDTH, height=HEIGHT, bg='black')
        self.canvas.pack()
        
        # Счет
        self.score = 0
        self.score_label = tk.Label(self.window, text=f"Счет: {self.score}", font=("Arial", 16), fg='white', bg='black')
        self.score_label.pack()
        
        # Игрок
        self.player = self.canvas.create_rectangle(
            WIDTH//2 - PLAYER_SIZE//2, HEIGHT - 70,
            WIDTH//2 + PLAYER_SIZE//2, HEIGHT - 20,
            fill='blue'
        )
        
        # Списки объектов
        self.asteroids = []
        self.bullets = []
        
        # Флаги для плавного движения
        self.left_pressed = False
        self.right_pressed = False
        self.space_pressed = False
        self.shoot_delay = 0
        self.shoot_cooldown = 10
        
        # Управление - ВАЖНО! фокус на канвас
        self.canvas.focus_set()
        self.canvas.bind('<KeyPress-Left>', self.key_press)
        self.canvas.bind('<KeyRelease-Left>', self.key_release)
        self.canvas.bind('<KeyPress-Right>', self.key_press)
        self.canvas.bind('<KeyRelease-Right>', self.key_release)
        self.canvas.bind('<KeyPress-space>', self.key_press)
        self.canvas.bind('<KeyRelease-space>', self.key_release)
        
        # Игровой цикл
        self.is_running = True
        self.spawn_counter = 0
        
        self.update()
        self.window.mainloop()
    
    def key_press(self, event):
        print(f"Клавиша нажата: {event.keysym}")  # Проверка в консоли
        if event.keysym == 'Left':
            self.left_pressed = True
        elif event.keysym == 'Right':
            self.right_pressed = True
        elif event.keysym == 'space':
            self.space_pressed = True
    
    def key_release(self, event):
        if event.keysym == 'Left':
            self.left_pressed = False
        elif event.keysym == 'Right':
            self.right_pressed = False
        elif event.keysym == 'space':
            self.space_pressed = False
    
    def move_player(self):
        x1, y1, x2, y2 = self.canvas.coords(self.player)
        
        if self.left_pressed and x1 > 0:
            self.canvas.move(self.player, -PLAYER_SPEED, 0)
        
        if self.right_pressed and x2 < WIDTH:
            self.canvas.move(self.player, PLAYER_SPEED, 0)
    
    def shoot(self):
        if self.space_pressed and self.shoot_delay <= 0:
            x1, y1, x2, y2 = self.canvas.coords(self.player)
            bullet = self.canvas.create_rectangle(
                x1 + PLAYER_SIZE//2 - BULLET_SIZE//2, y1,
                x1 + PLAYER_SIZE//2 + BULLET_SIZE//2, y1 - 20,
                fill='yellow'
            )
            self.bullets.append(bullet)
            self.shoot_delay = self.shoot_cooldown
            print("Выстрел!")  # Проверка в консоли
        elif self.shoot_delay > 0:
            self.shoot_delay -= 1
    
    def spawn_asteroid(self):
        x = random.randint(20, WIDTH - 20)
        size = ASTEROID_SIZE
        colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink', 'cyan']
        color = random.choice(colors)
        asteroid = self.canvas.create_polygon(
            x + size//2, -size,
            x + size//3, -size//3,
            x, 0,
            x + size//2, -size//4,
            x + size, 0,
            x + size*2//3, -size//3,
            fill=color
        )
        self.asteroids.append(asteroid)
    
    def update(self):
        if not self.is_running:
            return
        
        # Движение игрока
        self.move_player()
        
        # Стрельба
        self.shoot()
        
        # Спавн астероидов
        self.spawn_counter += 1
        if self.spawn_counter >= 20:
            self.spawn_counter = 0
            self.spawn_asteroid()
        
        # Движение астероидов
        for asteroid in self.asteroids[:]:
            self.canvas.move(asteroid, 0, ASTEROID_SPEED)
            coords = self.canvas.coords(asteroid)
            if coords:
                star_y_max = max(coords[1::2])
                if star_y_max > HEIGHT:
                    self.canvas.delete(asteroid)
                    self.asteroids.remove(asteroid)
        
        # Движение пуль
        for bullet in self.bullets[:]:
            self.canvas.move(bullet, 0, -BULLET_SPEED)
            x1, y1, x2, y2 = self.canvas.coords(bullet)
            if y2 < 0:
                self.canvas.delete(bullet)
                self.bullets.remove(bullet)
        
        # Проверка столкновений
        self.check_collisions()
        
        # Запуск следующего кадра
        self.window.after(33, self.update)
    
    def check_collisions(self):
        player_coords = self.canvas.coords(self.player)
        
        for bullet in self.bullets[:]:
            bullet_coords = self.canvas.coords(bullet)
            for asteroid in self.asteroids[:]:
                asteroid_coords = self.canvas.coords(asteroid)
                
                if asteroid_coords and bullet_coords:
                    # Проверка попадания
                    bullet_x = (bullet_coords[0] + bullet_coords[2]) / 2
                    bullet_y = (bullet_coords[1] + bullet_coords[3]) / 2
                    
                    star_x_min = min(asteroid_coords[0::2])
                    star_x_max = max(asteroid_coords[0::2])
                    star_y_min = min(asteroid_coords[1::2])
                    star_y_max = max(asteroid_coords[1::2])
                    
                    if star_x_min <= bullet_x <= star_x_max and star_y_min <= bullet_y <= star_y_max:
                        self.canvas.delete(bullet)
                        self.canvas.delete(asteroid)
                        if bullet in self.bullets:
                            self.bullets.remove(bullet)
                        if asteroid in self.asteroids:
                            self.asteroids.remove(asteroid)
                        self.score += 1
                        self.score_label.config(text=f"Счет: {self.score}")
                        break
        
        for asteroid in self.asteroids:
            asteroid_coords = self.canvas.coords(asteroid)
            if asteroid_coords and player_coords:
                player_x = (player_coords[0] + player_coords[2]) / 2
                player_y = (player_coords[1] + player_coords[3]) / 2
                
                star_x_min = min(asteroid_coords[0::2])
                star_x_max = max(asteroid_coords[0::2])
                star_y_min = min(asteroid_coords[1::2])
                star_y_max = max(asteroid_coords[1::2])
                
                if star_x_min <= player_x <= star_x_max and star_y_min <= player_y <= star_y_max:
                    self.game_over()
                    return
    
    def game_over(self):
        self.is_running = False
        self.canvas.create_text(
            WIDTH//2, HEIGHT//2,
            text=f"ИГРА ОКОНЧЕНА\nСчет: {self.score}\nНажмите R для рестарта",
            fill='white',
            font=("Arial", 30),
            justify='center'
        )
        self.canvas.bind('<KeyPress-r>', self.restart)
    
    def restart(self, event):
        self.canvas.delete('all')
        self.__init__()

if __name__ == "__main__":
    game = Game()