C语言实战:用Pygame打造高难度水果消消乐游戏

水果消消乐 - 困难模式

以下是一个基于Python和Pygame的水果消消乐游戏实现,包含困难模式的特点:

复制代码
import pygame
import random
import sys
from pygame.locals import *

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

# 游戏常量
FPS = 60
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
GRID_SIZE = 8
CELL_SIZE = 60
GRID_OFFSET_X = (WINDOW_WIDTH - GRID_SIZE * CELL_SIZE) // 2
GRID_OFFSET_Y = (WINDOW_HEIGHT - GRID_SIZE * CELL_SIZE) // 2 + 20

# 颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BACKGROUND_COLOR = (230, 230, 250)
GRID_COLOR = (200, 200, 220)

# 水果类型
FRUITS = ['apple', 'banana', 'orange', 'pear', 'watermelon', 'strawberry', 'grape']
FRUIT_COLORS = {
    'apple': (255, 50, 50),
    'banana': (255, 255, 100),
    'orange': (255, 165, 0),
    'pear': (150, 255, 150),
    'watermelon': (100, 200, 100),
    'strawberry': (255, 100, 150),
    'grape': (150, 50, 200)
}

# 困难模式设置
TIME_LIMIT = 90  # 90秒时间限制
MOVE_LIMIT = 25  # 25步限制
TARGET_SCORE = 2000  # 目标分数

class Fruit:
    def __init__(self, x, y, type):
        self.x = x
        self.y = y
        self.type = type
        self.color = FRUIT_COLORS[type]
        self.selected = False
        self.scale = 1.0
        self.scale_direction = 1
        
    def draw(self, surface):
        rect = pygame.Rect(
            GRID_OFFSET_X + self.x * CELL_SIZE + 5,
            GRID_OFFSET_Y + self.y * CELL_SIZE + 5,
            CELL_SIZE - 10,
            CELL_SIZE - 10
        )
        
        if self.selected:
            pygame.draw.rect(surface, WHITE, rect, 3)
            
        # 绘制水果(简化版,实际游戏可以用图片)
        pygame.draw.ellipse(surface, self.color, rect)
        
        # 水果动画效果
        if self.scale < 0.95 or self.scale > 1.05:
            self.scale_direction *= -1
        self.scale += 0.005 * self.scale_direction

class Game:
    def __init__(self):
        self.clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        pygame.display.set_caption('水果消消乐 - 困难模式')
        self.font = pygame.font.SysFont('Arial', 24)
        self.big_font = pygame.font.SysFont('Arial', 48)
        
        self.grid = [[None for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]
        self.selected = None
        self.score = 0
        self.time_left = TIME_LIMIT
        self.moves_left = MOVE_LIMIT
        self.game_over = False
        self.win = False
        self.last_time = pygame.time.get_ticks()
        
        # 初始化网格
        self.initialize_grid()
        
    def initialize_grid(self):
        # 确保初始网格没有匹配项
        while True:
            for y in range(GRID_SIZE):
                for x in range(GRID_SIZE):
                    self.grid[y][x] = Fruit(x, y, random.choice(FRUITS))
            
            if not self.check_matches(False):
                break
                
    def draw(self):
        self.screen.fill(BACKGROUND_COLOR)
        
        # 绘制网格背景
        for y in range(GRID_SIZE):
            for x in range(GRID_SIZE):
                rect = pygame.Rect(
                    GRID_OFFSET_X + x * CELL_SIZE,
                    GRID_OFFSET_Y + y * CELL_SIZE,
                    CELL_SIZE,
                    CELL_SIZE
                )
                pygame.draw.rect(self.screen, GRID_COLOR, rect, 1)
        
        # 绘制水果
        for row in self.grid:
            for fruit in row:
                if fruit:
                    fruit.draw(self.screen)
        
        # 绘制游戏信息
        score_text = self.font.render(f'分数: {self.score}', True, BLACK)
        time_text = self.font.render(f'时间: {int(self.time_left)}秒', True, BLACK)
        moves_text = self.font.render(f'剩余步数: {self.moves_left}', True, BLACK)
        target_text = self.font.render(f'目标: {TARGET_SCORE}', True, BLACK)
        
        self.screen.blit(score_text, (20, 20))
        self.screen.blit(time_text, (20, 50))
        self.screen.blit(moves_text, (20, 80))
        self.screen.blit(target_text, (20, 110))
        
        # 游戏结束提示
        if self.game_over:
            if self.win:
                text = self.big_font.render('恭喜获胜!', True, (0, 200, 0))
            else:
                text = self.big_font.render('游戏结束!', True, (200, 0, 0))
            text_rect = text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2))
            self.screen.blit(text, text_rect)
            
            restart_text = self.font.render('按R键重新开始', True, BLACK)
            restart_rect = restart_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 50))
            self.screen.blit(restart_text, restart_rect)
        
        pygame.display.flip()
        
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
                
            if event.type == KEYDOWN:
                if event.key == K_r and self.game_over:
                    self.__init__()  # 重置游戏
                    
            if not self.game_over and event.type == MOUSEBUTTONDOWN:
                x, y = event.pos
                grid_x = (x - GRID_OFFSET_X) // CELL_SIZE
                grid_y = (y - GRID_OFFSET_Y) // CELL_SIZE
                
                if 0 <= grid_x < GRID_SIZE and 0 <= grid_y < GRID_SIZE:
                    if self.selected is None:
                        self.selected = (grid_x, grid_y)
                        self.grid[grid_y][grid_x].selected = True
                    else:
                        prev_x, prev_y = self.selected
                        
                        # 检查是否是相邻的格子
                        if ((abs(grid_x - prev_x) == 1 and grid_y == prev_y) or 
                            (abs(grid_y - prev_y) == 1 and grid_x == prev_x)):
                            
                            # 交换水果
                            self.swap_fruits(prev_x, prev_y, grid_x, grid_y)
                            
                            # 检查是否有匹配
                            matches = self.check_matches()
                            if not matches:
                                # 如果没有匹配,交换回来
                                self.swap_fruits(prev_x, prev_y, grid_x, grid_y)
                            else:
                                # 减少步数
                                self.moves_left -= 1
                                
                        # 取消选择
                        self.grid[prev_y][prev_x].selected = False
                        self.selected = None
    
    def swap_fruits(self, x1, y1, x2, y2):
        self.grid[y1][x1].x, self.grid[y2][x2].x = self.grid[y2][x2].x, self.grid[y1][x1].x
        self.grid[y1][x1].y, self.grid[y2][x2].y = self.grid[y2][x2].y, self.grid[y1][x1].y
        self.grid[y1][x1], self.grid[y2][x2] = self.grid[y2][x2], self.grid[y1][x1]
    
    def check_matches(self, remove=True):
        matches = []
        
        # 检查水平匹配
        for y in range(GRID_SIZE):
            for x in range(GRID_SIZE - 2):
                if (self.grid[y][x] and self.grid[y][x+1] and self.grid[y][x+2] and
                    self.grid[y][x].type == self.grid[y][x+1].type == self.grid[y][x+2].type):
                    match = [(x, y), (x+1, y), (x+2, y)]
                    # 检查更长的匹配
                    for i in range(x+3, GRID_SIZE):
                        if self.grid[y][i] and self.grid[y][i].type == self.grid[y][x].type:
                            match.append((i, y))
                        else:
                            break
                    matches.append(match)
        
        # 检查垂直匹配
        for x in range(GRID_SIZE):
            for y in range(GRID_SIZE - 2):
                if (self.grid[y][x] and self.grid[y+1][x] and self.grid[y+2][x] and
                    self.grid[y][x].type == self.grid[y+1][x].type == self.grid[y+2][x].type):
                    match = [(x, y), (x, y+1), (x, y+2)]
                    # 检查更长的匹配
                    for i in range(y+3, GRID_SIZE):
                        if self.grid[i][x] and self.grid[i][x].type == self.grid[y][x].type:
                            match.append((x, i))
                        else:
                            break
                    matches.append(match)
        
        if remove and matches:
            # 移除匹配的水果并计算分数
            removed = set()
            for match in matches:
                for x, y in match:
                    if (x, y) not in removed:
                        removed.add((x, y))
                        self.score += 10 * len(match)  # 匹配越长分数越高
            
            # 移除水果并填充新水果
            for x, y in sorted(removed, key=lambda pos: pos[1]):
                # 从上方掉落水果
                for dy in range(y, 0, -1):
                    self.grid[dy][x] = self.grid[dy-1][x]
                    if self.grid[dy][x]:
                        self.grid[dy][x].y = dy
                
                # 顶部添加新水果
                self.grid[0][x] = Fruit(x, 0, random.choice(FRUITS))
            
            # 递归检查新的匹配
            self.check_matches()
            
        return len(matches) > 0
    
    def update(self):
        if self.game_over:
            return
            
        # 更新时间
        current_time = pygame.time.get_ticks()
        if current_time - self.last_time > 1000:  # 每秒更新一次
            self.time_left -= 1
            self.last_time = current_time
            
        # 检查游戏结束条件
        if self.time_left <= 0 or self.moves_left <= 0:
            self.game_over = True
            self.win = self.score >= TARGET_SCORE
            
        if self.score >= TARGET_SCORE:
            self.game_over = True
            self.win = True
    
    def run(self):
        while True:
            self.handle_events()
            self.update()
            self.draw()
            self.clock.tick(FPS)

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

困难模式特点

  1. 时间限制:玩家只有90秒时间来完成游戏

  2. 步数限制:最多只能进行25步操作

  3. 高目标分数:需要达到2000分才能获胜

  4. 连锁反应:消除水果后会自动检查新的匹配,增加了策略性

  5. 惩罚机制:无效的交换不会消耗步数,但有效的交换会减少剩余步数

如何运行

  1. 确保安装了Python和Pygame库(pip install pygame

  2. 复制上面的代码到一个.py文件中

  3. 运行该文件

游戏操作说明

  1. 点击一个水果选中它(会显示白色边框)

  2. 点击相邻的水果进行交换

  3. 如果交换后形成3个或更多相同水果的直线,它们会被消除并获得分数

  4. 无效的交换会自动回退

  5. 游戏目标是在限时和限步数内达到目标分数

相关推荐
databook5 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室6 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三7 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试
用户25191624271110 小时前
Python之语言特点
python
刘立军11 小时前
使用pyHugeGraph查询HugeGraph图数据
python·graphql
数据智能老司机14 小时前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机15 小时前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
c8i17 小时前
django中的FBV 和 CBV
python·django
c8i17 小时前
python中的闭包和装饰器
python
这里有鱼汤20 小时前
小白必看:QMT里的miniQMT入门教程
后端·python