球球越障大挑战

import pygame
import random
import sys
import math

# 初始化pygame
pygame.init()
pygame.mixer.init()

# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption(" 球球越障大挑战- 3111")

# 颜色定义
WHITE = (255, 255, 255)
BLUE = (100, 149, 237)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)

# 游戏参数
FPS = 60
clock = pygame.time.Clock()
GRAVITY = 0.5
SCROLL_SPEED = 5
BASE_SPEED = 5
MAX_SPEED = 15
JUMP_FORCE = -12
BOOST_FACTOR = 1.5
BOOST_DURATION = 180  # 3秒(60帧/秒)

# 加载图像和音效
try:
    # 玩家图像
    player_img = pygame.Surface((40, 60), pygame.SRCALPHA)
    pygame.draw.ellipse(player_img, BLUE, (0, 0, 40, 60))
    
    # 障碍物图像
    rock_img = pygame.Surface((50, 50), pygame.SRCALPHA)
    pygame.draw.circle(rock_img, (100, 100, 100), (25, 25), 25)
    
    tree_img = pygame.Surface((60, 100), pygame.SRCALPHA)
    pygame.draw.rect(tree_img, BROWN := (139, 69, 19), (20, 60, 20, 40))
    pygame.draw.polygon(tree_img, GREEN, [(0, 60), (60, 60), (30, 0)])
    
    # 道具图像
    boost_img = pygame.Surface((30, 30), pygame.SRCALPHA)
    pygame.draw.circle(boost_img, YELLOW, (15, 15), 15)
    pygame.draw.line(boost_img, BLACK, (15, 5), (15, 25), 2)
    pygame.draw.line(boost_img, BLACK, (5, 15), (25, 15), 2)
    
    # 背景图像
    bg_img = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
    bg_img.fill((135, 206, 235))  # 天空蓝
    pygame.draw.rect(bg_img, WHITE, (0, SCREEN_HEIGHT//2, SCREEN_WIDTH, SCREEN_HEIGHT//2))  # 雪地
    
    # 音效
    jump_sound = pygame.mixer.Sound(pygame.mixer.SoundType('jump.wav') if pygame.version.vernum[0] >= 2 else None)
    crash_sound = pygame.mixer.Sound(pygame.mixer.SoundType('crash.wav') if pygame.version.vernum[0] >= 2 else None)
    boost_sound = pygame.mixer.Sound(pygame.mixer.SoundType('boost.wav') if pygame.version.vernum[0] >= 2 else None)
except:
    # 如果加载资源失败,使用简单图形代替
    pass

# 玩家类
class Player:
    def __init__(self):
        self.reset()
        self.img = player_img
        self.width = 40
        self.height = 60
        self.rect = pygame.Rect(100, SCREEN_HEIGHT//2 - self.height, self.width, self.height)
        self.jump_power = JUMP_FORCE
        self.is_jumping = False
        self.boost_timer = 0
        self.invincible = 0
        self.rotation = 0
    
    def reset(self):
        self.x = 100
        self.y = SCREEN_HEIGHT//2 - 60
        self.vel_y = 0
        self.boost_timer = 0
        self.invincible = 0
        self.rotation = 0
    
    def update(self, scroll_speed):
        # 重力
        self.vel_y += GRAVITY
        self.y += self.vel_y
        
        # 确保玩家不会超出屏幕底部
        if self.y > SCREEN_HEIGHT - self.height:
            self.y = SCREEN_HEIGHT - self.height
            self.vel_y = 0
            self.is_jumping = False
        
        # 确保玩家不会超出屏幕顶部
        if self.y < 0:
            self.y = 0
            self.vel_y = 0
        
        # 更新矩形位置
        self.rect.y = self.y
        
        # 旋转效果
        if self.is_jumping:
            self.rotation = min(30, max(-30, self.vel_y * 3))
        else:
            self.rotation = 0
        
        # 无敌时间减少
        if self.invincible > 0:
            self.invincible -= 1
        
        # 加速时间减少
        if self.boost_timer > 0:
            self.boost_timer -= 1
    
    def jump(self):
        if not self.is_jumping:
            self.vel_y = self.jump_power
            self.is_jumping = True
            try:
                jump_sound.play()
            except:
                pass
    
    def draw(self, screen):
        # 绘制玩家(带旋转效果)
        rotated_img = pygame.transform.rotate(self.img, self.rotation)
        new_rect = rotated_img.get_rect(center=self.img.get_rect(topleft=(self.x, self.y)).center)
        screen.blit(rotated_img, new_rect.topleft)
        
        # 无敌状态闪烁效果
        if self.invincible > 0 and self.invincible % 10 < 5:
            pygame.draw.rect(screen, (255, 255, 255, 128), new_rect, 2)

# 障碍物类
class Obstacle:
    def __init__(self, x, y, obstacle_type):
        self.x = x
        self.y = y
        self.type = obstacle_type  # 'rock' 或 'tree'
        
        if self.type == 'rock':
            self.width = 50
            self.height = 50
            self.img = rock_img
        else:  # tree
            self.width = 60
            self.height = 100
            self.img = tree_img
        
        self.rect = pygame.Rect(x, y, self.width, self.height)
    
    def update(self, scroll_speed):
        self.x -= scroll_speed
        self.rect.x = self.x
    
    def draw(self, screen):
        screen.blit(self.img, (self.x, self.y))

# 道具类
class PowerUp:
    def __init__(self, x, y, power_type):
        self.x = x
        self.y = y
        self.type = power_type  # 'boost'
        self.width = 30
        self.height = 30
        self.img = boost_img
        self.rect = pygame.Rect(x, y, self.width, self.height)
        self.animation_timer = 0
    
    def update(self, scroll_speed):
        self.x -= scroll_speed
        self.rect.x = self.x
        self.animation_timer = (self.animation_timer + 1) % 60
    
    def draw(self, screen):
        # 闪烁动画
        if self.animation_timer < 45:  # 显示3/4的时间
            size_factor = 1.0 + 0.2 * math.sin(self.animation_timer * 0.1)
            scaled_img = pygame.transform.scale(self.img, 
                                              (int(self.width * size_factor), 
                                               int(self.height * size_factor)))
            screen.blit(scaled_img, 
                       (self.x - (scaled_img.get_width() - self.width) // 2, 
                        self.y - (scaled_img.get_height() - self.height) // 2))

# 游戏状态
player = Player()
obstacles = []
powerups = []
scroll_speed = BASE_SPEED
score = 0
high_score = 0
game_over = False
obstacle_timer = 0
powerup_timer = 0
distance = 0
particles = []

# 粒子效果
class Particle:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.size = random.randint(2, 5)
        self.life = random.randint(20, 40)
        self.vel_x = random.uniform(-2, 2)
        self.vel_y = random.uniform(-2, 0)
    
    def update(self):
        self.x += self.vel_x
        self.y += self.vel_y
        self.life -= 1
        self.size = max(0, self.size - 0.1)
    
    def draw(self, screen):
        alpha = min(255, self.life * 6)
        color_with_alpha = (*self.color, alpha)
        surf = pygame.Surface((self.size*2, self.size*2), pygame.SRCALPHA)
        pygame.draw.circle(surf, color_with_alpha, (self.size, self.size), self.size)
        screen.blit(surf, (int(self.x - self.size), int(self.y - self.size)))

# 游戏主循环
running = True
while running:
    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
                player.jump()
            if event.key == pygame.K_r and game_over:
                # 重置游戏
                player.reset()
                obstacles = []
                powerups = []
                scroll_speed = BASE_SPEED
                score = 0
                distance = 0
                game_over = False
                obstacle_timer = 0
                powerup_timer = 0
    
    if game_over:
        # 显示游戏结束画面
        screen.fill(BLUE)
        
        # 绘制雪地
        pygame.draw.rect(screen, WHITE, (0, SCREEN_HEIGHT//2, SCREEN_WIDTH, SCREEN_HEIGHT//2))
        
        font_large = pygame.font.SysFont(None, 72)
        font_small = pygame.font.SysFont(None, 36)
        
        game_over_text = font_large.render("游戏结束!", True, RED)
        score_text = font_large.render(f"得分: {score}", True, BLACK)
        high_score_text = font_small.render(f"最高分: {high_score}", True, BLACK)
        restart_text = font_small.render("按R键重新开始", True, BLACK)
        
        screen.blit(game_over_text, (SCREEN_WIDTH//2 - game_over_text.get_width()//2, SCREEN_HEIGHT//2 - 100))
        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 + 70))
        screen.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, SCREEN_HEIGHT//2 + 120))
        
        # 绘制特殊标志 3111
        special_text = font_small.render("3111", True, RED)
        screen.blit(special_text, (SCREEN_WIDTH - 60, 20))
        
        pygame.display.flip()
        clock.tick(FPS)
        continue
    
    # 更新游戏状态
    # 更新滚动速度(根据加速状态)
    if player.boost_timer > 0:
        scroll_speed = min(MAX_SPEED, BASE_SPEED * BOOST_FACTOR)
    else:
        scroll_speed = BASE_SPEED
    
    # 更新玩家
    player.update(scroll_speed)
    
    # 更新距离和分数
    distance += scroll_speed / 10
    score = int(distance)
    
    # 生成障碍物
    obstacle_timer += 1
    if obstacle_timer >= 90:  # 每1.5秒生成一个障碍物
        obstacle_timer = 0
        obstacle_type = random.choice(['rock', 'tree'])
        y_pos = SCREEN_HEIGHT - (100 if obstacle_type == 'tree' else 50)
        obstacles.append(Obstacle(SCREEN_WIDTH, y_pos, obstacle_type))
    
    # 生成道具
    powerup_timer += 1
    if powerup_timer >= 300 and random.random() < 0.1:  # 大约每5秒有10%几率生成道具
        powerup_timer = 0
        y_pos = random.randint(SCREEN_HEIGHT//2, SCREEN_HEIGHT - 50)
        powerups.append(PowerUp(SCREEN_WIDTH, y_pos, 'boost'))
    
    # 更新障碍物
    for obstacle in obstacles[:]:
        obstacle.update(scroll_speed)
        
        # 移除屏幕外的障碍物
        if obstacle.x < -obstacle.width:
            obstacles.remove(obstacle)
        
        # 检测碰撞(无敌状态下不检测)
        if player.invincible <= 0 and player.rect.colliderect(obstacle.rect):
            try:
                crash_sound.play()
            except:
                pass
            
            # 创建碰撞粒子效果
            for _ in range(20):
                particles.append(Particle(
                    player.x + player.width//2,
                    player.y + player.height//2,
                    (random.randint(200, 255), random.randint(100, 200), random.randint(100, 200))
                ))
            
            game_over = True
            high_score = max(high_score, score)
    
    # 更新道具
    for powerup in powerups[:]:
        powerup.update(scroll_speed)
        
        # 移除屏幕外的道具
        if powerup.x < -powerup.width:
            powerups.remove(powerup)
        
        # 检测收集
        if player.rect.colliderect(powerup.rect):
            if powerup.type == 'boost':
                player.boost_timer = BOOST_DURATION
                try:
                    boost_sound.play()
                except:
                    pass
                
                # 创建收集粒子效果
                for _ in range(15):
                    particles.append(Particle(
                        powerup.x + powerup.width//2,
                        powerup.y + powerup.height//2,
                        (random.randint(200, 255), random.randint(200, 255), random.randint(0, 100))
                    ))
            
            powerups.remove(powerup)
    
    # 更新粒子
    for particle in particles[:]:
        particle.update()
        if particle.life <= 0:
            particles.remove(particle)
    
    # 绘制
    # 绘制背景
    screen.blit(bg_img, (0, 0))
    
    # 绘制雪地(带视差效果)
    for i in range(5):
        offset = (distance * (i+1)*0.1) % SCREEN_WIDTH
        pygame.draw.rect(screen, WHITE, (offset - SCREEN_WIDTH, SCREEN_HEIGHT//2 + i*20, SCREEN_WIDTH, 20))
        pygame.draw.rect(screen, WHITE, (offset, SCREEN_HEIGHT//2 + i*20, SCREEN_WIDTH, 20))
    
    # 绘制粒子
    for particle in particles:
        particle.draw(screen)
    
    # 绘制障碍物
    for obstacle in obstacles:
        obstacle.draw(screen)
    
    # 绘制道具
    for powerup in powerups:
        powerup.draw(screen)
    
    # 绘制玩家
    player.draw(screen)
    
    # 绘制UI
    font = pygame.font.SysFont(None, 36)
    score_text = font.render(f"分数: {score}", True, BLACK)
    screen.blit(score_text, (20, 20))
    
    # 绘制加速状态
    if player.boost_timer > 0:
        boost_text = font.render(f"加速: {player.boost_timer//60 + 1}s", True, YELLOW)
        screen.blit(boost_text, (20, 60))
    
    # 绘制特殊标志 3111
    special_text = font.render("3111", True, RED)
    screen.blit(special_text, (SCREEN_WIDTH - 60, 20))
    
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
sys.exit()

 

posted @ 2025-06-23 14:22  linlikun  阅读(20)  评论(0)    收藏  举报