import pygame
import random

pygame.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Моя Pygame Игра")

score = 0
hp = 20

def fillTransparent(surface, color):
    new_surface = surface.copy()
    pxarray = pygame.PixelArray(new_surface)
    for x in range(new_surface.get_width()):
        for y in range(new_surface.get_height()):
            if pxarray[x, y][3] == 0:
                pxarray = (color[0], color[1], color[2])
    del pxarray
    return new_surface

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface([50, 50]) #убрать
        self.rect = self.image.get_rect() #убрать
        self.image.fill((0, 255, 0)) #убрать
        # raw = pygame.image.load("сюда путь").convert_alpha()
        # colored = fillTransparent(raw, (0, 255, 0))
        # self.image = pygame.transform.scale(colored, (50, 50))
        # self.rect = self.image.get_rect() #это надо вернуть
        self.rect.x = x
        self.rect.y = y
        self.change_x = 0
        self.change_y = 0
        self.speed = 6
    def update(self):
        self.rect.x += self.change_x
        self.rect.y += self.change_y
    def go_left(self):
        self.change_x = -self.speed
    def go_right(self):
        self.change_x = self.speed
    def go_up(self):
        self.change_y = -self.speed
    def go_down(self):
        self.change_y = self.speed
    def stopx(self):
        self.change_x = 0
    def stopy(self):
        self.change_y = 0

class Coin(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface([20, 20]) #убрать
        self.image.fill((0, 255, 0)) #убрать
        self.rect = self.image.get_rect() #убрать
        # picC1 = pygame.image.load("здесь путь").convert_alpha()
        # picC2 = pygame.image.load("здесь путь").convert_alpha()
        # picC3 = pygame.image.load("здесь путь").convert_alpha()
        # self.image = picC1
        self.rect.x = x
        self.rect.y = y
        self.state = "1"
        self.lastchange = pygame.time.get_ticks()
        timenow = pygame.time.get_ticks()
        timefromlastchange = timenow - self.lastchange
        if self.state == "1" and timefromlastchange >= 500:
            self.state = "2"
            self.lastchange = timenow
            # self.image = picC2
        elif self.state == "2" and timefromlastchange >= 500:
            self.state = "3"
            self.lastchange = timenow
            # self.image = picC3
        elif self.state == "3" and timefromlastchange >= 500:
            self.state = "1"
            self.lastchange = timenow
            # self.image = picC1

class heal(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface([20, 20]) #убрать
        self.image.fill((255, 0, 0)) #убрать
        self.rect = self.image.get_rect() #убрать
        # pich1 = pygame.image.load("здесь путь").convert_alpha()
        # pich2 = pygame.image.load("здесь путь").convert_alpha()
        # pich3 = pygame.image.load("здесь путь").convert_alpha()
        # self.image = pich1
        self.rect.x = x
        self.rect.y = y
        self.state = "1"
        self.lastchange = pygame.time.get_ticks()
        timenow = pygame.time.get_ticks()
        timefromlastchange = timenow - self.lastchange
        if self.state == "1" and timefromlastchange >= 500:
            self.state = "2"
            self.lastchange = timenow
            # self.image = pich2
        elif self.state == "2" and timefromlastchange >= 500:
            self.state = "3"
            self.lastchange = timenow
            # self.image = pich3
        elif self.state == "3" and timefromlastchange >= 500:
            self.state = "1"
            self.lastchange = timenow
            # self.image = pich1

class speedup(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface([20, 20]) #убрать
        self.image.fill((0, 0, 255)) #убрать
        self.rect = self.image.get_rect() #убрать
        # pics1 = pygame.image.load("здесь путь").convert_alpha()
        # pics2 = pygame.image.load("здесь путь").convert_alpha()
        # pics3 = pygame.image.load("здесь путь").convert_alpha()
        # self.image = pics1
        self.rect.x = x
        self.rect.y = y
        self.state = "1"
        self.lastchange = pygame.time.get_ticks()
        timenow = pygame.time.get_ticks()
        timefromlastchange = timenow - self.lastchange
        if self.state == "1" and timefromlastchange >= 500:
            self.state = "2"
            self.lastchange = timenow
            # self.image = pics2
        elif self.state == "2" and timefromlastchange >= 500:
            self.state = "3"
            self.lastchange = timenow
            # self.image = pics3
        elif self.state == "3" and timefromlastchange >= 500:
            self.state = "1"
            self.lastchange = timenow
            # self.image = pics1

class enemy(pygame.sprite.Sprite):
    def __init__(self, x, y, target, color):
        super().__init__()
        self.image = pygame.Surface([50, 50]) #убрать
        self.image.fill(color) #убрать
        self.rect = self.image.get_rect() #убрать
        # raw1 = pygame.image.load("сюда путь").convert_alpha()
        # colored1 = fillTransparent(raw, (0, 255, 0))
        # raw2 = pygame.image.load("сюда путь").convert_alpha()
        # colored2 = fillTransparent(raw, (0, 255, 0))
        # raw3 = pygame.image.load("сюда путь").convert_alpha()
        # colored3 = fillTransparent(raw, (0, 255, 0))
        # self.image = pygame.transform.scale(colored, (50, 50))
        # self.rect = self.image.get_rect() #это надо вернуть
        self.rect.x = x
        self.rect.y = y
        self.speed = 3
        self.target = target
        self.lastchange = pygame.time.get_ticks()
        self.state = "normal"
        self.shake = 2
    def update(self):
        dx = self.target.rect.x - self.rect.x
        dy = self.target.rect.y - self.rect.y
        distance = max(1, (dx ** 2 + dy ** 2) ** 0.5)
        self.rect.x += int(self.speed * dx / distance)
        self.rect.y += int(self.speed * dy / distance)
        timenow = pygame.time.get_ticks()
        timefromlastchange = timenow - self.lastchange
        if self.state == "normal" and timefromlastchange >= 4000:
            self.state = "stop"
            self.lastchange = timenow
            self.speed = 0
            #self.rect = colored2.get_rect(center=self.rect.center)
            self.stoporigin = self.rect.center
        elif self.state == "stop" and timefromlastchange >= 2000:
            self.state = "enraged"
            self.lastchange = timenow
            self.speed = 5
            #self.rect = colored3.get_rect(center=self.rect.center)
            if self.stoporigin != None:
                self.rect.center = self.stoporigin
                self.stoporigin = None
        elif self.state == "enraged" and timefromlastchange >= 4000:
            self.state = "normal"
            self.lastchange = timenow
            self.speed = 3
            #self.rect = colored1.get_rect(center=self.rect.center)
        if self.state == "stop":
            if self.stoporigin != None:
                offsetx = random.randint(-self.shake, self.shake)
                offsety = random.randint(-self.shake, self.shake)
                self.rect.center = (self.stoporigin[0] + offsetx, self.stoporigin[1] + offsety)




player = Player(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)  #starting location

all_sprites = pygame.sprite.Group()
all_sprites.add(player)
enemy1 = enemy(0, 0, player, (255, 0, 0))
all_sprites.add(enemy1)
enemygroup = pygame.sprite.Group()
enemygroup.add(enemy1)
coin = Coin(random.randrange(0, SCREEN_WIDTH), random.randrange(0, SCREEN_HEIGHT))
all_sprites.add(coin)
coingroup = pygame.sprite.Group()
coingroup.add(coin)
healgroup = pygame.sprite.Group()
healwasthistick = 0
speedupgroup = pygame.sprite.Group()
speedup1 = speedup(random.randrange(0, SCREEN_WIDTH), random.randrange(0, SCREEN_HEIGHT))
speedupgroup.add(speedup1)
all_sprites.add(speedup1)
speedupwasthistick = 0
momentspeedup = pygame.time.get_ticks() - 6000

running = True
clock = pygame.time.Clock()

spawnenemy = pygame.USEREVENT + 1
pygame.time.set_timer(spawnenemy, random.randint(7000, 10000))
spawnCoin = pygame.USEREVENT + 2
pygame.time.set_timer(spawnCoin, 1500)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == spawnenemy:
            enemy1 = enemy(random.randrange(0, SCREEN_WIDTH, SCREEN_WIDTH - 1), random.randrange(0, SCREEN_HEIGHT, SCREEN_HEIGHT - 1),
                           player, (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
            all_sprites.add(enemy1)
            enemygroup.add(enemy1)
        if event.type == spawnCoin:
            coin1 = Coin(random.randrange(0, SCREEN_WIDTH), random.randrange(0, SCREEN_HEIGHT))
            all_sprites.add(coin1)
            coingroup.add(coin1)
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.go_left()
            if event.key == pygame.K_RIGHT:
                player.go_right()
            if event.key == pygame.K_DOWN:
                player.go_down()
            if event.key == pygame.K_UP:
                player.go_up()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT and player.change_x < 0:
                player.stopx()
            if event.key == pygame.K_RIGHT and player.change_x > 0:
                player.stopx()
            if event.key == pygame.K_UP and player.change_y < 0:
                player.stopy()
            if event.key == pygame.K_DOWN and player.change_y > 0:
                player.stopy()
    if player.rect.x < 0:
        player.rect.x = 0
    if player.rect.x > SCREEN_WIDTH - player.rect.width:
        player.rect.x = SCREEN_WIDTH - player.rect.width
    if player.rect.y < 0:
        player.rect.y = 0
    if player.rect.y > SCREEN_HEIGHT - player.rect.height:
        player.rect.y = SCREEN_HEIGHT - player.rect.height
    collectedcoins = pygame.sprite.spritecollide(player, coingroup, True)
    score += len(collectedcoins)
    collectedheals = pygame.sprite.spritecollide(player, healgroup, True)
    hp += len(collectedheals) * 4
    collectedspeedups = pygame.sprite.spritecollide(player, speedupgroup, True)
    if len(collectedspeedups) > 0:
        momentspeedup = pygame.time.get_ticks()
    now = pygame.time.get_ticks()
    if now - momentspeedup < 5000:
        player.speed = 10
    elif now - momentspeedup > 5000:
        player.speed = 6
    if hp > 15:
        player.image.fill((0, 255, 0))
    elif 8 <= hp <= 14:
        player.image.fill((0, 0, 255))
    elif 1 <= hp < 8:
        player.image.fill((255, 0, 0))
    elif hp <= 0:
        running = False
    if score % 6 == 0 and score != 0:
        if healwasthistick == 0:
            med = heal(random.randrange(0, 255), random.randrange(0, 255))
            healgroup.add(med)
            all_sprites.add(med)
            healwasthistick = 1
    if score % 6 == 1 and score != 0:
            healwasthistick = 0
    if score % 10 == 0 and score != 0:
        if speedupwasthistick == 0:
            speedup1 = speedup(random.randrange(0, 255), random.randrange(0, 255))
            speedupgroup.add(speedup1)
            all_sprites.add(speedup1)
            speedupwasthistick = 1
    if score % 10 == 1 and score != 0:
            speedupwasthistick = 0

    if pygame.sprite.spritecollide(player, enemygroup, True):
        hp -= 7
        if hp > 15:
            player.image.fill((0, 255, 0))
        elif 8 <= hp <= 14:
            player.image.fill((0, 0, 255))
        elif 1 <= hp < 8:
            player.image.fill((255, 0, 0))
        elif hp <= 0:
            running = False

    all_sprites.update()
    font = pygame.font.Font(None, 36)
    scoresurface = font.render(str(score), True, (255, 255, 255))
    hpsurface = font.render(str(hp), True, (255, 255, 255))
    screen.fill((119, 119, 143))
    screen.blit(scoresurface, (10, 10))
    screen.blit(hpsurface, (SCREEN_WIDTH - 30, 10))
    all_sprites.draw(screen)

    pygame.display.flip()


    clock.tick(60)

pygame.quit()
