游戏开始

游戏过程

游戏结束

点击查看代码
import pygame
import sys
import random

# 初始化pygame
try:
    pygame.init()
    print("Pygame初始化成功")
except Exception as e:
    print(f"Pygame初始化失败: {e}")
    sys.exit()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 400
GROUND_HEIGHT = 350
GRAVITY = 0.8
JUMP_FORCE = -16
GAME_SPEED = 5
OBSTACLE_FREQUENCY_INITIAL = 1500  # 初始障碍物生成频率(ms)

# 颜色定义(地板改为绿色)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
BLUE = (50, 120, 255)
YELLOW = (255, 200, 0)
GREEN = (50, 180, 50)  # 深绿色地板
DARK_GREEN = (30, 150, 30)  # 用于地面纹理

# 创建游戏窗口
try:
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("足球奔跑者")
    print(f"创建游戏窗口成功: {SCREEN_WIDTH}x{SCREEN_HEIGHT}")
except Exception as e:
    print(f"创建游戏窗口失败: {e}")
    sys.exit()

clock = pygame.time.Clock()

# 字体初始化(使用多个备选字体)
try:
    pygame.font.init()
    print("字体系统初始化成功")
    font_options = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Arial", "sans-serif"]
    font = None
    
    for font_name in font_options:
        try:
            font = pygame.font.SysFont(font_name, 36)
            if font:
                print(f"成功加载字体: {font_name}")
                break
        except:
            continue
    
    if not font:
        font = pygame.font.Font(None, 36)  # 使用默认系统字体
        print("使用默认系统字体")
    
    big_font = pygame.font.SysFont(font_options, 72) or pygame.font.Font(None, 72)
except Exception as e:
    print(f"字体初始化失败: {e}")
    font = None
    big_font = None


class Football:
    def __init__(self):
        self.x = 80
        self.y = GROUND_HEIGHT - 30
        self.radius = 30
        self.velocity = 0
        self.is_jumping = False

    def jump(self):
        if not self.is_jumping:
            self.velocity = JUMP_FORCE
            self.is_jumping = True

    def update(self):
        self.velocity += GRAVITY
        self.y += self.velocity

        if self.y >= GROUND_HEIGHT - self.radius:
            self.y = GROUND_HEIGHT - self.radius
            self.velocity = 0
            self.is_jumping = False

    def draw(self):
        # 绘制足球主体
        try:
            pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), self.radius)
            
            # 绘制足球花纹
            pygame.draw.circle(screen, BLACK, (int(self.x), int(self.y)), self.radius, 2)
            pygame.draw.circle(screen, BLACK, (int(self.x - self.radius * 0.3), int(self.y - self.radius * 0.3)), 8)
            pygame.draw.circle(screen, BLACK, (int(self.x + self.radius * 0.3), int(self.y - self.radius * 0.3)), 8)
            pygame.draw.circle(screen, BLACK, (int(self.x - self.radius * 0.3), int(self.y + self.radius * 0.3)), 8)
            pygame.draw.circle(screen, BLACK, (int(self.x + self.radius * 0.3), int(self.y + self.radius * 0.3)), 8)
            pygame.draw.circle(screen, BLACK, (int(self.x), int(self.y - self.radius * 0.6)), 8)
            pygame.draw.circle(screen, BLACK, (int(self.x), int(self.y + self.radius * 0.6)), 8)
            
            # 绘制高光
            pygame.draw.circle(screen, (240, 240, 255), 
                             (int(self.x - self.radius // 3), int(self.y - self.radius // 3)), 
                             self.radius // 4)
        except Exception as e:
            print(f"绘制足球时出错: {e}")

    def get_rect(self):
        return pygame.Rect(
            self.x - self.radius + 5, 
            self.y - self.radius + 5, 
            self.radius * 2 - 10, 
            self.radius * 2 - 10
        )


class Obstacle:
    def __init__(self, x):
        self.x = x
        self.width = random.randint(30, 50)
        self.height = random.randint(40, 70)
        self.y = GROUND_HEIGHT - self.height
        self.color = BLUE
        self.passed = False

    def update(self, speed):
        self.x -= speed

    def draw(self):
        try:
            # 绘制球门柱形状
            pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
            pygame.draw.rect(screen, self.color, (self.x - 10, self.y, 10, self.height // 2))
            pygame.draw.rect(screen, self.color, (self.x + self.width, self.y, 10, self.height // 2))
            pygame.draw.rect(screen, self.color, (self.x - 10, self.y, self.width + 20, 10))
            
            # 绘制网纹
            for i in range(4):
                pygame.draw.line(screen, (200, 200, 255), 
                                (self.x, self.y + i * (self.height // 4)),
                                (self.x + self.width, self.y + i * (self.height // 4)))
        except Exception as e:
            print(f"绘制障碍物时出错: {e}")

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)


def draw_ground():
    try:
        # 绘制绿色地面
        pygame.draw.rect(screen, GREEN, (0, GROUND_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - GROUND_HEIGHT))
        
        # 绘制草坪纹理
        for i in range(0, SCREEN_WIDTH, 20):
            pygame.draw.line(screen, DARK_GREEN, (i, GROUND_HEIGHT), (i, SCREEN_HEIGHT), 2)
            
        # 绘制白色边线
        pygame.draw.line(screen, WHITE, (0, GROUND_HEIGHT), (SCREEN_WIDTH, GROUND_HEIGHT), 3)
    except Exception as e:
        print(f"绘制地面时出错: {e}")


def draw_score(score, high_score):
    if font:
        try:
            score_text = font.render(f"分数: {score}", True, WHITE)
            high_score_text = font.render(f"最高分: {high_score}", True, WHITE)
            screen.blit(score_text, (20, 20))
            screen.blit(high_score_text, (20, 60))
        except Exception as e:
            print(f"绘制分数时出错: {e}")


def draw_game_over(score, high_score):
    if big_font and font:
        try:
            game_over_text = big_font.render("游戏结束!", True, RED)
            score_text = font.render(f"最终分数: {score}", True, WHITE)
            high_score_text = font.render(f"最高分: {high_score}", True, WHITE)
            restart_text = font.render("按 R 键重新开始", True, WHITE)

            screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, SCREEN_HEIGHT // 2 - 80))
            screen.blit(score_text, (SCREEN_WIDTH // 2 - score_text.get_width() // 2, SCREEN_HEIGHT // 2))
            screen.blit(high_score_text, (SCREEN_WIDTH // 2 - high_score_text.get_width() // 2, SCREEN_HEIGHT // 2 + 40))
            screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, SCREEN_HEIGHT // 2 + 100))
        except Exception as e:
            print(f"绘制游戏结束界面时出错: {e}")


def draw_start_screen():
    if big_font and font:
        try:
            title_text = big_font.render("足球奔跑者", True, BLUE)
            screen.blit(title_text, (SCREEN_WIDTH // 2 - title_text.get_width() // 2, 100))

            start_text = font.render("按空格键开始游戏", True, WHITE)
            screen.blit(start_text, (SCREEN_WIDTH // 2 - start_text.get_width() // 2, SCREEN_HEIGHT // 2))

            controls_text = font.render("控制: 空格键跳跃 | R键重新开始", True, WHITE)
            screen.blit(controls_text, (SCREEN_WIDTH // 2 - controls_text.get_width() // 2, SCREEN_HEIGHT // 2 + 50))
        except Exception as e:
            print(f"绘制开始界面时出错: {e}")
    else:
        # 如果字体不可用,绘制简单提示
        try:
            pygame.draw.rect(screen, WHITE, (SCREEN_WIDTH // 2 - 150, SCREEN_HEIGHT // 2 - 50, 300, 100), 2)
            pygame.draw.line(screen, WHITE, 
                            (SCREEN_WIDTH // 2 - 140, SCREEN_HEIGHT // 2 - 30), 
                            (SCREEN_WIDTH // 2 + 140, SCREEN_HEIGHT // 2 - 30))
        except Exception as e:
            print(f"绘制备用开始界面时出错: {e}")


def reset_game():
    football = Football()
    obstacles = []
    score = 0
    game_speed = GAME_SPEED
    last_obstacle_time = pygame.time.get_ticks()
    game_over = False
    game_started = False
    obstacle_frequency = OBSTACLE_FREQUENCY_INITIAL

    return football, obstacles, score, game_speed, last_obstacle_time, game_over, game_started, obstacle_frequency


def main():
    print("游戏主循环开始")
    
    # 初始游戏状态
    football, obstacles, score, game_speed, last_obstacle_time, game_over, game_started, obstacle_frequency = reset_game()
    high_score = 0
    
    # 测试模式 - 强制显示基本元素
    test_mode = False
    frame_count = 0

    while True:
        current_time = pygame.time.get_ticks()
        frame_count += 1
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if not game_started:
                        game_started = True
                        print("游戏开始")
                    elif not game_over:
                        football.jump()

                if event.key == pygame.K_r and game_over:
                    football, obstacles, score, game_speed, last_obstacle_time, game_over, game_started, obstacle_frequency = reset_game()
                    print("游戏重置")
                
                # 切换测试模式
                if event.key == pygame.K_t:
                    test_mode = not test_mode
                    print(f"测试模式: {'开启' if test_mode else '关闭'}")

        # 填充背景色为黑色
        screen.fill(BLACK)

        # 绘制基本游戏元素(即使在黑屏情况下也显示)
        if test_mode:
            # 绘制测试元素
            try:
                # 绘制坐标系
                pygame.draw.line(screen, WHITE, (0, GROUND_HEIGHT), (SCREEN_WIDTH, GROUND_HEIGHT), 2)
                pygame.draw.line(screen, WHITE, (100, 0), (100, SCREEN_HEIGHT), 2)
                
                # 绘制测试文本
                if font:
                    test_text = font.render("测试模式", True, WHITE)
                    screen.blit(test_text, (SCREEN_WIDTH // 2 - test_text.get_width() // 2, 20))
                    
                    fps_text = font.render(f"FPS: {int(clock.get_fps())}", True, WHITE)
                    screen.blit(fps_text, (SCREEN_WIDTH - fps_text.get_width() - 20, 20))
                    
                    frame_text = font.render(f"帧: {frame_count}", True, WHITE)
                    screen.blit(frame_text, (SCREEN_WIDTH - frame_text.get_width() - 20, 60))
            except Exception as e:
                print(f"绘制测试元素时出错: {e}")

        # 正常游戏渲染
        if not test_mode:
            draw_ground()
            football.draw()
            
            for obstacle in obstacles:
                obstacle.draw()
            
            if game_started:
                draw_score(score, high_score)
                
                if game_over:
                    draw_game_over(score, high_score)
            else:
                draw_start_screen()

            # 游戏逻辑
            if game_started and not game_over:
                football.update()

                if current_time - last_obstacle_time > obstacle_frequency:
                    obstacles.append(Obstacle(SCREEN_WIDTH))
                    last_obstacle_time = current_time
                    obstacle_frequency = max(500, OBSTACLE_FREQUENCY_INITIAL - score // 10 * 100)

                for obstacle in obstacles[:]:
                    obstacle.update(game_speed)

                    if obstacle.x + obstacle.width < 0:
                        obstacles.remove(obstacle)
                        continue

                    if not obstacle.passed and obstacle.x < football.x:
                        obstacle.passed = True
                        score += 1
                        if score % 10 == 0:
                            game_speed += 0.5
                            print(f"速度提升: {game_speed}")

                football_rect = football.get_rect()
                for obstacle in obstacles:
                    if football_rect.colliderect(obstacle.get_rect()):
                        game_over = True
                        high_score = max(high_score, score)
                        print(f"游戏结束 - 分数: {score}")

        # 更新显示
        try:
            pygame.display.flip()
        except Exception as e:
            print(f"更新显示时出错: {e}")

        # 控制帧率
        clock.tick(60)


if __name__ == "__main__":
    main()
posted on 2025-06-22 15:17  986614  阅读(66)  评论(0)    收藏  举报