import pygame
import sys
import random

# 初始化 pygame
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 400, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("是男人就上一百层 (完整版+血条表现)")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 100, 255)
YELLOW = (255, 255, 0)
GOLD = (255, 215, 0)
PURPLE = (180, 0, 255)
CYAN = (0, 255, 255)
GRAY = (100, 100, 100)

# 玩家类
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((30, 30))
        self.image.fill(BLUE)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH // 2
        self.rect.bottom = HEIGHT - 50
        self.vel_y = 0
        self.gravity = 0.8
        self.jump_power = -15
        
        self.jump_count = 0      
        self.max_jumps = 2       
        self.is_on_ground = False 
        
        # 生命值
        self.hp = 3
        self.max_hp = 3
        
        # [新增] 受伤闪烁与无敌时间
        self.hurt_timer = 0
        
        # 道具状态
        self.has_shield = False
        self.magnet_timer = 0

    def update(self):
        self.vel_y += self.gravity
        self.rect.y += self.vel_y

        # [新增] 更新受伤闪烁倒计时
        if self.hurt_timer > 0:
            self.hurt_timer -= 1

        if self.rect.top > HEIGHT:
            return "GAME_OVER"
        if self.rect.top < 0:
            self.rect.top = 0
            self.vel_y = 0
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH

    def jump(self):
        if self.jump_count < self.max_jumps:
            self.vel_y = self.jump_power
            self.jump_count += 1
            self.is_on_ground = False

    def take_damage(self):
        """受伤方法：增加无敌闪烁时间"""
        if self.has_shield:
            self.has_shield = False
            return False
        
        if self.hurt_timer > 0:  # 无敌期间免疫伤害
            return False

        self.hp -= 1
        self.hurt_timer = 30  # 0.5秒无敌闪烁时间 (60fps)
        
        if self.hp <= 0:
            return True
        return False

    def reset(self):
        self.rect.centerx = WIDTH // 2
        self.rect.bottom = HEIGHT - 50
        self.vel_y = 0
        self.jump_count = 0      
        self.is_on_ground = True 
        self.hp = self.max_hp
        self.hurt_timer = 0
        self.has_shield = False
        self.magnet_timer = 0

# 普通平台类
class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, color=GREEN):
        super().__init__()
        self.image = pygame.Surface((width, height))
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

# 弹簧类
class Spring(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((40, 15))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.bounce_power = -25

# 金币类
class Coin(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((20, 20), pygame.SRCALPHA)
        pygame.draw.circle(self.image, GOLD, (10, 10), 10)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y

# 道具类
class PowerUp(pygame.sprite.Sprite):
    def __init__(self, x, y, color, effect_type):
        super().__init__()
        self.image = pygame.Surface((25, 25), pygame.SRCALPHA)
        pygame.draw.circle(self.image, color, (12, 12), 12)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y
        self.effect_type = effect_type

# 主游戏类
class Game:
    def __init__(self):
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, 36)
        self.running = True
        self.score = 0
        self.coins_collected = 0
        
        # [新增] 扣血提示UI状态
        self.damage_text_timer = 0
        
        self.player = Player()
        
        self.platforms = pygame.sprite.Group()
        self.springs = pygame.sprite.Group()
        self.coins = pygame.sprite.Group()
        self.powerups = pygame.sprite.Group()
        self.all_sprites = pygame.sprite.Group()
        
        self.all_sprites.add(self.player)
        self.generate_initial_platforms()

    def generate_initial_platforms(self):
        base_platform = Platform(WIDTH // 2 - 50, HEIGHT - 50, 100, 10)
        self.platforms.add(base_platform)
        self.all_sprites.add(base_platform)
        
        for _ in range(10):
            self.add_new_platform()

    def add_new_platform(self):
        width = random.randint(60, 120)
        x = random.randint(0, WIDTH - width)
        highest_y = min(p.rect.y for p in self.platforms)
        y = highest_y - random.randint(60, 100)
        
        color = GREEN
        if random.random() < 0.2:
            color = RED
            
        platform = Platform(x, y, width, 10, color)
        self.platforms.add(platform)
        self.all_sprites.add(platform)
        
        if random.random() < 0.15 and color == GREEN:
            spring_x = x + (width // 2) - 20
            spring_y = y - 15
            spring = Spring(spring_x, spring_y)
            self.springs.add(spring)
            self.all_sprites.add(spring)
            
        if random.random() < 0.4 and color == GREEN:
            coin_x = x + (width // 2)
            coin_y = y - 40
            coin = Coin(coin_x, coin_y)
            self.coins.add(coin)
            self.all_sprites.add(coin)
            
        if random.random() < 0.1 and color == GREEN:
            effect = random.choice(['magnet', 'shield', 'rocket'])
            if effect == 'magnet':
                p_color = RED
            elif effect == 'shield':
                p_color = CYAN
            else:
                p_color = PURPLE
                
            p_x = x + (width // 2)
            p_y = y - 70
            powerup = PowerUp(p_x, p_y, p_color, effect)
            self.powerups.add(powerup)
            self.all_sprites.add(powerup)

    def handle_collisions(self):
        # 1. 平台碰撞
        if self.player.vel_y > 0:
            hits = pygame.sprite.spritecollide(self.player, self.platforms, False)
            if hits:
                if self.player.rect.bottom <= hits[0].rect.top + 10:
                    self.player.rect.bottom = hits[0].rect.top
                    self.player.vel_y = 0
                    self.player.jump_count = 0
                    self.player.is_on_ground = True
                    
                    if hits[0].image.get_at((0,0)) == RED:
                        is_dead = self.player.take_damage()
                        if is_dead:
                            return "GAME_OVER"
                        elif self.player.hurt_timer == 30: 
                            # [修改] 只有在刚刚扣血的那一帧，才把平台变绿并触发提示
                            hits[0].image.fill(GREEN)
                            self.damage_text_timer = 40  # 显示 -1 HP 提示
                        
        # 2. 弹簧碰撞
        if self.player.vel_y > 0:
            spring_hits = pygame.sprite.spritecollide(self.player, self.springs, False)
            if spring_hits:
                if self.player.rect.bottom <= spring_hits[0].rect.top + 15:
                    self.player.rect.bottom = spring_hits[0].rect.top
                    self.player.vel_y = spring_hits[0].bounce_power
                    self.player.jump_count = 0
                    self.player.is_on_ground = False
        
        # 3. 金币碰撞
        coin_hits = pygame.sprite.spritecollide(self.player, self.coins, True)
        if coin_hits:
            self.coins_collected += len(coin_hits)
            self.score += len(coin_hits) * 10
                    
        # 4. 道具碰撞
        pu_hits = pygame.sprite.spritecollide(self.player, self.powerups, True)
        for pu in pu_hits:
            if pu.effect_type == 'magnet':
                self.player.magnet_timer = 300
            elif pu.effect_type == 'shield':
                self.player.has_shield = True
            elif pu.effect_type == 'rocket':
                self.player.vel_y = -40
                self.player.jump_count = 0
                
        return "PLAYING"

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.player.rect.x -= 5
        if keys[pygame.K_RIGHT]:
            self.player.rect.x += 5

        # 磁铁效果
        if self.player.magnet_timer > 0:
            self.player.magnet_timer -= 1
            for coin in self.coins:
                dx = self.player.rect.centerx - coin.rect.centerx
                dy = self.player.rect.centery - coin.rect.centery
                coin.rect.x += dx // 10
                coin.rect.y += dy // 10

        result = self.player.update()
        if result == "GAME_OVER":
            return "GAME_OVER"

        collision_result = self.handle_collisions()
        if collision_result == "GAME_OVER":
            return "GAME_OVER"

        # [新增] 更新扣血提示倒计时
        if self.damage_text_timer > 0:
            self.damage_text_timer -= 1

        current_max_score = max(-p.rect.y for p in self.platforms) // 10
        if current_max_score > self.score:
            self.score = current_max_score

        if self.player.rect.top < HEIGHT // 3:
            shift = HEIGHT // 3 - self.player.rect.top
            self.player.rect.y += shift
            for sprite in self.all_sprites:
                if sprite != self.player:
                    sprite.rect.y += shift

        for platform in self.platforms:
            if platform.rect.top > HEIGHT:
                self.platforms.remove(platform)
                self.all_sprites.remove(platform)
                self.add_new_platform()
                
        for spring in self.springs:
            if spring.rect.top > HEIGHT:
                self.springs.remove(spring)
                self.all_sprites.remove(spring)
                
        for coin in self.coins:
            if coin.rect.top > HEIGHT:
                self.coins.remove(coin)
                self.all_sprites.remove(coin)
                
        for pu in self.powerups:
            if pu.rect.top > HEIGHT:
                self.powerups.remove(pu)
                self.all_sprites.remove(pu)

        return "PLAYING"

    def draw(self):
        screen.fill(BLACK)
        
        # [新增] 绘制动态血条 UI
        hp_bar_x, hp_bar_y = 10, 10
        hp_bar_width, hp_bar_height = 100, 15
        
        # 1. 绘制血条背景（灰色）
        pygame.draw.rect(screen, GRAY, (hp_bar_x, hp_bar_y, hp_bar_width, hp_bar_height))
        
        # 2. 绘制当前血量（根据血量比例变色）
        current_hp_width = int((self.player.hp / self.player.max_hp) * hp_bar_width)
        hp_color = RED if self.player.hp == 1 else GREEN
        pygame.draw.rect(screen, hp_color, (hp_bar_x, hp_bar_y, current_hp_width, hp_bar_height))
        
        # 3. 绘制血条边框
        pygame.draw.rect(screen, WHITE, (hp_bar_x, hp_bar_y, hp_bar_width, hp_bar_height), 2)

        self.all_sprites.draw(screen)
        
        # [新增] 受伤闪烁表现：在无敌时间内，玩家身上叠加一层半透明红色
        if self.player.hurt_timer > 0 and self.player.hurt_timer % 6 < 3:
            hurt_overlay = pygame.Surface((30, 30), pygame.SRCALPHA)
            hurt_overlay.fill((255, 0, 0, 150))
            screen.blit(hurt_overlay, self.player.rect)

        # [新增] 扣血提示文字
        if self.damage_text_timer > 0:
            dmg_text = self.font.render("-1 HP", True, RED)
            screen.blit(dmg_text, (WIDTH // 2 - 30, HEIGHT // 3))

        score_text = self.font.render(f"Score: {self.score}", True, WHITE)
        screen.blit(score_text, (10, 35))
        
        coin_text = self.font.render(f"Coins: {self.coins_collected}", True, GOLD)
        screen.blit(coin_text, (10, 65))
        
        status_text = ""
        if self.player.has_shield:
            status_text += "🛡️ "
        if self.player.magnet_timer > 0:
            status_text += "🧲 "
        if status_text:
            status_label = self.font.render(status_text, True, CYAN)
            screen.blit(status_label, (WIDTH - 100, 10))
        
        jump_left = self.player.max_jumps - self.player.jump_count
        jump_text = self.font.render(f"Jumps: {jump_left}", True, (200, 200, 200))
        screen.blit(jump_text, (WIDTH - 120, 45))
        
        pygame.display.flip()

    def run(self):
        while self.running:
            self.clock.tick(60)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        self.player.jump()

            result = self.update()
            self.draw()

            if result == "GAME_OVER":
                game_over_text = self.font.render("GAME OVER!", True, RED)
                screen.blit(game_over_text, (WIDTH // 2 - 80, HEIGHT // 2 - 40))
                
                final_score_text = self.font.render(f"Score: {self.score} | Coins: {self.coins_collected}", True, WHITE)
                screen.blit(final_score_text, (WIDTH // 2 - 150, HEIGHT // 2))
                
                restart_text = self.font.render("Press R to Restart", True, (200, 200, 200))
                screen.blit(restart_text, (WIDTH // 2 - 100, HEIGHT // 2 + 40))
                
                pygame.display.flip()
                
                waiting = True
                while waiting:
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            self.running = False
                            waiting = False
                        if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
                            self.__init__()
                            waiting = False

        pygame.quit()
        sys.exit()

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