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. 游戏目标是在限时和限步数内达到目标分数

相关推荐
麻雀飞吧6 小时前
先判断工具用来学习、开发还是执行
人工智能·python
人邮异步社区6 小时前
学习Python的最佳学习路径是什么?
python·程序员
Navigator_Z8 小时前
LeetCode //C - 1252. Cells with Odd Values in a Matrix
c语言·算法·leetcode
troy1289 小时前
Python 基础语法(九):Django/Flask/FastAPI 三大 Web 框架详细对比解析
python·jupyter·django·flask·github·fastapi
jzshmyt9 小时前
我用 Python 从零“生成“了一个宇宙,然后让它观察自己(v14)
人工智能·pytorch·python·numpy·matplotlib·空间计算·scipy
是隼人10 小时前
buuctf-pwn [NewStarCTF 2023 公开赛道]stack migration(64位栈迁移)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
用户83562907805111 小时前
使用 Python 将 DOCX 转换为 Markdown
后端·python
小玮看世界11 小时前
[Python]ADAS工程实战(三):多传感器扇区统计疑难点全解——归一化、跨边界、去重与置信度
python
TomEval12 小时前
【测AI】第02篇:Python 环境搭建与基础语法速通
人工智能·python·功能测试·aigc
归去来 兮12 小时前
LangChain从入门到精通
python·langchain·langgraph