吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 924|回复: 19
上一主题 下一主题
收起左侧

[原创工具] Python开发的俄罗斯方块游戏(霓虹炫彩带音效)

[复制链接]
跳转到指定楼层
楼主
xhlbudd 发表于 2026-5-1 21:52 回帖奖励
最近在教舅舅家上初二的儿子Python编程,每次教完基本语法,都会用一个小游戏来帮助他提高兴趣。今天为大家带来Python开发的俄罗斯方块游戏,使用pygame 2.5.2 (SDL 2.28.3, Python 3.12.6)开发,一共1338行代码。带霓虹炫彩和音效,自己玩了挺多遍,体验还不错,欢迎大家下载试玩。下载链接如下(带exe格式的游戏约27MB,源代码和音乐素材):
链接: https://pan.baidu.com/s/11RkBSKlwdWIpcA34JvwFJw?pwd=52pj
提取码: 52pj

同时把源代码分享如下,请大家多多指点:
[Python] 纯文本查看 复制代码
import pygame
import random
import math
import os
import sys
from typing import List, Tuple, Optional, Dict, Any
from pygame import gfxdraw
import json

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

# 获取当前文件所在目录
folder_name = os.path.dirname(__file__)

# 加载背景音乐
bg_music = os.path.join(folder_name, '丛林.ogg')
try:
    pygame.mixer.music.load(bg_music)
    pygame.mixer.music.play(-1)
    pygame.mixer.music.set_volume(0.3)  # 降低背景音乐音量
except Exception as e:
    print(f"加载背景音乐失败: {e}")

# 屏幕尺寸
SCREEN_WIDTH = 1100
SCREEN_HEIGHT = 900
GRID_SIZE = 35
GRID_WIDTH = 10
GRID_HEIGHT = 20
SIDEBAR_WIDTH = 300
HEADER_HEIGHT = 100

# 色彩方案 - 霓虹未来风
COLORS = {
    'bg_dark': (10, 10, 20),
    'bg_grid': (20, 20, 35),
    'game_area_line': (230, 230, 230, 100), 
    'grid_line': (40, 40, 60, 100),
    'text_primary': (240, 240, 255),
    'text_secondary': (180, 180, 220),
    'text_accent': (100, 220, 255),
    'panel_bg': (25, 25, 45, 200),
    'button_bg': (50, 50, 80),
    'button_hover': (70, 70, 110),
    'shadow': (0, 0, 0, 150),
    'glow': (100, 200, 255, 50)
}

# 方块颜色 (霓虹色)
BLOCK_COLORS = [
    (0, 240, 240),    # I - 青色
    (30, 144, 255),   # J - 亮蓝
    (255, 165, 0),    # L - 橙色
    (255, 255, 0),    # O - 黄色
    (50, 205, 50),    # S - 绿色
    (186, 85, 211),   # T - 紫色
    (255, 69, 0)      # Z - 红色
]

# 方块发光颜色
BLOCK_GLOW = [
    (100, 255, 255, 100),   # I
    (100, 180, 255, 100),   # J
    (255, 200, 100, 100),   # L
    (255, 255, 100, 100),   # O
    (100, 255, 100, 100),   # S
    (200, 100, 255, 100),   # T
    (255, 100, 100, 100)    # Z
]

# 方块形状定义
SHAPES = [
    [[1, 1, 1, 1]],                              # I
    [[1, 0, 0], [1, 1, 1]],                      # J
    [[0, 0, 1], [1, 1, 1]],                      # L
    [[1, 1], [1, 1]],                            # O
    [[0, 1, 1], [1, 1, 0]],                      # S
    [[0, 1, 0], [1, 1, 1]],                      # T
    [[1, 1, 0], [0, 1, 1]]                       # Z
]

# 方块初始位置
SHAPE_START_POS = [3, 0]

# 字体
def load_font(size, bold=False):
    """加载字体,支持多种回退方案"""
    fonts = [
        "Microsoft YaHei UI", "simhei", "simsun", "Segoe UI", "Arial", "Helvetica", 
        "DroidSansFallback", "sans-serif"
    ]
    
    for font_name in fonts:
        try:
            if bold:
                return pygame.font.SysFont(font_name, size, bold=True)
            else:
                return pygame.font.SysFont(font_name, size)
        except:
            continue
    
    return pygame.font.Font(None, size)

# 粒子系统
class Particle:
    """粒子特效"""
    def __init__(self, x, y, color, particle_type="sparkle"):
        self.x = x
        self.y = y
        self.color = color
        self.type = particle_type
        self.life = 1.0
        
        if particle_type == "sparkle":
            self.size = random.randint(2, 6)
            self.speed_x = random.uniform(-2, 2)
            self.speed_y = random.uniform(-3, -1)
            self.decay = random.uniform(0.02, 0.05)
            self.gravity = 0.2
        elif particle_type == "trail":
            self.size = random.randint(1, 3)
            self.speed_x = random.uniform(-0.5, 0.5)
            self.speed_y = random.uniform(-0.2, 0.2)
            self.decay = random.uniform(0.01, 0.03)
            self.gravity = 0.05
    
    def update(self):
        self.x += self.speed_x
        self.y += self.speed_y
        self.speed_y += self.gravity
        self.life -= self.decay
        return self.life > 0
    
    def draw(self, surface):
        alpha = int(self.life * 255)
        if self.type == "sparkle":
            # 绘制发光粒子
            s = pygame.Surface((self.size * 2, self.size * 2), pygame.SRCALPHA)
            gfxdraw.filled_circle(s, self.size, self.size, self.size, 
                                (*self.color[:3], alpha))
            gfxdraw.aacircle(s, self.size, self.size, self.size, 
                           (*self.color[:3], alpha))
            surface.blit(s, (int(self.x) - self.size, int(self.y) - self.size))
        else:
            pygame.draw.circle(surface, (*self.color[:3], alpha), 
                             (int(self.x), int(self.y)), self.size)

# 方块类
class Tetromino:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.shape_idx = random.randint(0, len(SHAPES) - 1)
        self.color_idx = self.shape_idx
        self.rotation = 0
        self.last_move_time = pygame.time.get_ticks()
        self.move_delay = 600
        self.drop_time = pygame.time.get_ticks()
        self.last_rotate_time = 0
        self.ghost_y = 0
        
        # 旋转状态
        self.rotate_state = 0
        self.rotate_progress = 0
        self.rotate_target = 0
        
        # 移动效果
        self.move_offset = 0
        self.wobble = 0
    
    @property
    def shape(self):
        shape = SHAPES[self.shape_idx]
        rotated = shape
        for _ in range(self.rotation % 4):
            rotated = list(zip(*reversed(rotated)))
        return rotated
    
    def calculate_ghost(self, grid):
        """计算阴影位置"""
        ghost = Tetromino(self.x, self.y)
        ghost.shape_idx = self.shape_idx
        ghost.rotation = self.rotation
        ghost.color_idx = self.color_idx
        
        while not ghost.collision(grid):
            ghost.y += 1
        ghost.y -= 1
        
        return ghost.y
    
    def rotate(self, grid):
        """旋转方块"""
        old_rotation = self.rotation
        self.rotation = (self.rotation + 1) % 4
        
        # 尝试墙壁踢
        if self.collision(grid):
            # 向右移动尝试
            self.x += 1
            if self.collision(grid):
                self.x -= 2
                if self.collision(grid):
                    self.x += 1
                    # 向左移动尝试
                    if self.x > 0:
                        self.x -= 1
                        if self.collision(grid):
                            self.x += 1
                    self.rotation = old_rotation
                    return False
        
        self.last_rotate_time = pygame.time.get_ticks()
        return True
    
    def move(self, dx, dy, grid):
        """移动方块"""
        self.x += dx
        self.y += dy
        
        if self.collision(grid):
            self.x -= dx
            self.y -= dy
            return False
        
        # 移动效果
        if dx != 0:
            self.move_offset = dx * 3
        
        return True
    
    def hard_drop(self, grid):
        """硬降到底部"""
        distance = 0
        while self.move(0, 1, grid):
            distance += 1
        return distance
    
    def collision(self, grid):
        """碰撞检测"""
        shape = self.shape
        for y, row in enumerate(shape):
            for x, cell in enumerate(row):
                if cell:
                    board_x = self.x + x
                    board_y = self.y + y
                    
                    # 检查x坐标是否在网格内
                    if board_x < 0 or board_x >= GRID_WIDTH:
                        return True
                    
                    # 检查y坐标是否超出底部
                    if board_y >= GRID_HEIGHT:
                        return True
                    
                    # 检查是否与已固定的方块碰撞(只检查在网格内的位置)
                    if board_y >= 0 and grid[board_y][board_x] is not None:
                        return True
        return False
    
    def draw(self, surface, x_offset, y_offset, is_ghost=False, particles=None):
        """绘制方块"""
        shape = self.shape
        block_size = GRID_SIZE
        glow_size = block_size + 6
        
        for y, row in enumerate(shape):
            for x, cell in enumerate(row):
                if cell:
                    # 计算位置
                    pos_x = x_offset + (self.x + x) * block_size
                    pos_y = y_offset + (self.y + y) * block_size
                    
                    # 添加移动偏移
                    if self.move_offset != 0:
                        pos_x += self.move_offset
                        self.move_offset *= 0.8
                        if abs(self.move_offset) < 0.5:
                            self.move_offset = 0
                    
                    # 添加摆动效果
                    if self.wobble != 0:
                        wobble_offset = math.sin(self.wobble) * 2
                        pos_y += wobble_offset
                        self.wobble *= 0.9
                        if abs(self.wobble) < 0.1:
                            self.wobble = 0
                    
                    if is_ghost:
                        # 绘制阴影方块
                        self._draw_ghost_block(surface, pos_x, pos_y, block_size)
                    else:
                        # 绘制主方块
                        self._draw_main_block(surface, pos_x, pos_y, block_size, particles)
        
        # 添加方块粒子
        if particles is not None and not is_ghost:
            for y, row in enumerate(shape):
                for x, cell in enumerate(row):
                    if cell and random.random() < 0.1:
                        pos_x = x_offset + (self.x + x) * block_size + block_size // 2
                        pos_y = y_offset + (self.y + y) * block_size + block_size // 2
                        particles.append(Particle(pos_x, pos_y, BLOCK_GLOW[self.color_idx], "trail"))
    
    def _draw_ghost_block(self, surface, x, y, size):
        """绘制阴影方块"""
        # 外发光
        glow_surf = pygame.Surface((size + 8, size + 8), pygame.SRCALPHA)
        color = (*BLOCK_COLORS[self.color_idx][:3], 80)
        pygame.draw.rect(glow_surf, color, (0, 0, size + 8, size + 8), 
                        border_radius=4)
        surface.blit(glow_surf, (x - 4, y - 4))
        
        # 内透明方块
        inner_surf = pygame.Surface((size - 4, size - 4), pygame.SRCALPHA)
        color = (*BLOCK_COLORS[self.color_idx][:3], 30)
        pygame.draw.rect(inner_surf, color, (0, 0, size - 4, size - 4), 
                        border_radius=3)
        surface.blit(inner_surf, (x + 2, y + 2))
        
        # 边框
        pygame.draw.rect(surface, (*BLOCK_COLORS[self.color_idx][:3], 100), 
                        (x, y, size, size), 1, border_radius=3)
    
    def _draw_main_block(self, surface, x, y, size, particles):
        """绘制主方块"""
        color = BLOCK_COLORS[self.color_idx]
        glow_color = BLOCK_GLOW[self.color_idx]
        
        # 底部阴影
        shadow_offset = 3
        shadow_surf = pygame.Surface((size, size), pygame.SRCALPHA)
        pygame.draw.rect(shadow_surf, (0, 0, 0, 100), 
                        (shadow_offset, shadow_offset, size, size), 
                        border_radius=5)
        surface.blit(shadow_surf, (x, y))
        
        # 主方块
        pygame.draw.rect(surface, color, (x, y, size, size), 
                        border_radius=5)
        
        # 3D效果 - 高光
        highlight_surf = pygame.Surface((size, size), pygame.SRCALPHA)
        # 左上高光
        pygame.draw.polygon(highlight_surf, (255, 255, 255, 60), 
                           [(0, 0), (size, 0), (0, size)])
        # 右下阴影
        pygame.draw.polygon(highlight_surf, (0, 0, 0, 30), 
                           [(size, 0), (0, size), (size, size)])
        surface.blit(highlight_surf, (x, y))
        
        # 内发光
        inner_size = size - 6
        inner_surf = pygame.Surface((inner_size, inner_size), pygame.SRCALPHA)
        pygame.draw.rect(inner_surf, (*color[:3], 100), 
                        (0, 0, inner_size, inner_size), border_radius=3)
        surface.blit(inner_surf, (x + 3, y + 3))
        
        # 发光边框
        pygame.draw.rect(surface, (255, 255, 255, 150), 
                        (x, y, size, size), 2, border_radius=5)
        
        # 高光点
        highlight_size = 8
        highlight_surf = pygame.Surface((highlight_size, highlight_size), pygame.SRCALPHA)
        pygame.draw.circle(highlight_surf, (255, 255, 255, 150), 
                          (highlight_size//2, highlight_size//2), highlight_size//2)
        surface.blit(highlight_surf, (x + 5, y + 5))
        
        # 添加粒子效果
        if particles is not None and random.random() < 0.05:
            particles.append(Particle(
                x + size//2, y + size//2, 
                glow_color, "sparkle"
            ))

# 游戏主类
class TetrisGame:
    def __init__(self):
        # 初始化屏幕
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 
                                             pygame.DOUBLEBUF | pygame.HWSURFACE)
        pygame.display.set_caption("&#127918; 俄罗斯方块霓虹特别版")
        
        # 设置图标
        try:
            icon_surf = pygame.Surface((32, 32))
            icon_surf.fill(BLOCK_COLORS[0])
            pygame.display.set_icon(icon_surf)
        except:
            pass
        
        self.clock = pygame.time.Clock()
        self.font_large = load_font(48, True)
        self.font_medium = load_font(28)
        self.font_small = load_font(20)
        
        # 计算游戏区域位置
        self.grid_left = (SCREEN_WIDTH - SIDEBAR_WIDTH - GRID_WIDTH * GRID_SIZE) // 2
        self.grid_top = HEADER_HEIGHT + 20
        
        # 游戏状态
        self.reset_game()
        
        # 创建半透明表面
        self.panel_surf = pygame.Surface((SIDEBAR_WIDTH - 40, SCREEN_HEIGHT - 100), 
                                        pygame.SRCALPHA)
        self.panel_surf.fill(COLORS['panel_bg'])
        
        # 背景动画
        self.bg_particles = []
        self.bg_stars = []
        self._init_background()
        
        # 音效
        self.sounds = self._init_sounds()
        
        # 游戏状态
        self.state = "playing"  # playing, paused, gameover
        self.last_state_change = 0
        
        # 动画
        self.animations = []
        
        # 调试信息
        self.debug_info = []
        
    def reset_game(self):
        """重置游戏状态"""
        self.grid = [[None for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
        self.current_piece = Tetromino(GRID_WIDTH // 2 - 1, 0)
        self.next_piece = Tetromino(0, 0)
        self.hold_piece = None
        self.can_hold = True
        
        self.game_over = False
        self.score = 0
        self.level = 1
        self.lines_cleared = 0
        self.total_pieces = 0
        self.combo = 0
        self.last_clear_time = 0
        
        self.particles = []
        self.clear_effects = []
        
        # 计算阴影
        self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
    
    def _init_background(self):
        """初始化背景"""
        # 创建星空背景
        for _ in range(100):
            x = random.randint(0, SCREEN_WIDTH)
            y = random.randint(0, SCREEN_HEIGHT)
            size = random.randint(1, 3)
            speed = random.uniform(0.1, 0.5)
            self.bg_stars.append({
                'x': x, 'y': y, 'size': size, 'speed': speed,
                'brightness': random.uniform(0.5, 1.0)
            })
    
    def _init_sounds(self):
        """初始化音效"""
        sounds = {}
        try:
            # 单行消除音效
            clear_sound_path = os.path.join(folder_name, 'clear.ogg')
            if os.path.exists(clear_sound_path):
                sounds['clear'] = pygame.mixer.Sound(clear_sound_path)
                sounds['clear'].set_volume(0.5)
                print(f"&#10003; 加载单行消除音效: {clear_sound_path}")
            else:
                print(f"&#10007; 找不到单行消除音效: {clear_sound_path}")
            
            # 多行消除/连击音效
            combo_sound_path = os.path.join(folder_name, 'combo.ogg')
            if os.path.exists(combo_sound_path):
                sounds['combo'] = pygame.mixer.Sound(combo_sound_path)
                sounds['combo'].set_volume(0.6)
                print(f"&#10003; 加载连击音效: {combo_sound_path}")
            else:
                print(f"&#10007; 找不到连击音效: {combo_sound_path}")
                
        except Exception as e:
            print(f"加载音效时出错: {e}")
            print("游戏将继续运行,但没有音效")
        
        return sounds
    
    def spawn_new_piece(self):
        """生成新方块"""
        self.current_piece = self.next_piece
        self.current_piece.x = GRID_WIDTH // 2 - 1
        self.current_piece.y = 0
        self.next_piece = Tetromino(0, 0)
        self.can_hold = True
        
        # 计算新方块的阴影
        self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
        
        # 检查游戏是否结束
        if self.current_piece.collision(self.grid):
            self.game_over = True
            self.state = "gameover"
            return False
        
        self.total_pieces += 1
        return True
    
    def hold_current_piece(self):
        """暂存当前方块"""
        if not self.can_hold:
            return
        
        if self.hold_piece is None:
            self.hold_piece = Tetromino(0, 0)
            self.hold_piece.shape_idx = self.current_piece.shape_idx
            self.hold_piece.color_idx = self.current_piece.color_idx
            self.spawn_new_piece()
        else:
            # 交换当前方块和暂存方块
            temp_idx = self.current_piece.shape_idx
            temp_color = self.current_piece.color_idx
            
            self.current_piece.shape_idx = self.hold_piece.shape_idx
            self.current_piece.color_idx = self.hold_piece.color_idx
            self.current_piece.rotation = 0
            self.current_piece.x = GRID_WIDTH // 2 - 1
            self.current_piece.y = 0
            
            self.hold_piece.shape_idx = temp_idx
            self.hold_piece.color_idx = temp_color
        
        self.can_hold = False
        self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
    
    def clear_lines(self):
        """清除已满的行"""
        lines_to_clear = []
        
        # 调试:打印网格状态
        self.debug_info = []
        for y in range(GRID_HEIGHT):
            row_count = sum(1 for cell in self.grid[y] if cell is not None)
            if row_count > 0:
                self.debug_info.append(f"行{y}: {row_count}/10")
                if row_count == GRID_WIDTH:
                    lines_to_clear.append(y)
        
        if not lines_to_clear:
            self.combo = 0
            return 0
        
        # 计算连击
        current_time = pygame.time.get_ticks()
        if current_time - self.last_clear_time < 2000:  # 2秒内
            self.combo += 1
        else:
            self.combo = 1
        self.last_clear_time = current_time
        
        # 创建消除特效
        for line in lines_to_clear:
            self._create_clear_effect(line)
        
        # 播放消除音效
        cleared = len(lines_to_clear)
        self._play_clear_sound(cleared)
        
        # 创建多行消除特效
        if cleared >= 2:
            self._create_multi_line_effect(cleared, lines_to_clear)
        
        # 计分
        self.lines_cleared += cleared
        
        # 计分规则
        points_per_line = [0, 100, 300, 500, 800]
        base_points = points_per_line[cleared] * self.level
        
        # 连击加成
        combo_bonus = self.combo * 50 * self.level
        
        # 全清奖励
        is_all_clear = all(cell is None for row in self.grid for cell in row)
        all_clear_bonus = 2000 if is_all_clear else 0
        
        self.score += base_points + combo_bonus + all_clear_bonus
        
        # 升级
        self.level = self.lines_cleared // 10 + 1
        self.current_piece.move_delay = max(50, 600 - (self.level - 1) * 50)
        
        # 移除行
        for line in sorted(lines_to_clear, reverse=True):
            del self.grid[line]
            self.grid.insert(0, [None for _ in range(GRID_WIDTH)])
        
        return cleared
    
    def _play_clear_sound(self, lines_cleared):
        """播放消除音效"""
        if not self.sounds:
            return
        
        try:
            if lines_cleared == 1:
                # 单行消除
                if 'clear' in self.sounds:
                    self.sounds['clear'].play()
            elif lines_cleared >= 2:
                # 多行消除/连击
                if 'combo' in self.sounds:
                    # 根据消除行数调整音量和音高
                    sound = self.sounds['combo']
                    
                    # 计算音量 - 消除行数越多音量越大
                    volume = min(0.8, 0.5 + (lines_cleared - 1) * 0.1)
                    sound.set_volume(volume)
                    
                    # 尝试改变音高
                    try:
                        # 简单的音高调整:通过播放速度
                        from pygame import mixer
                        # 重新创建音效以实现音高变化
                        original_array = pygame.sndarray.array(sound)
                        if original_array is not None:
                            # 计算音高因子 - 消除行数越多音高越高
                            pitch_factor = 1.0 + (lines_cleared - 2) * 0.1
                            
                            # 创建新的音效
                            new_sound = pygame.mixer.Sound(original_array)
                            new_sound.set_volume(volume)
                            new_sound.play()
                    except:
                        # 如果音高调整失败,直接播放
                        sound.play()
                        
        except Exception as e:
            print(f"播放音效时出错: {e}")
    
    def _create_clear_effect(self, line):
        """创建行消除特效"""
        for x in range(GRID_WIDTH):
            if self.grid[line][x] is not None:
                color_idx = self.grid[line][x]
                center_x = self.grid_left + x * GRID_SIZE + GRID_SIZE // 2
                center_y = self.grid_top + line * GRID_SIZE + GRID_SIZE // 2
                
                # 创建粒子
                for _ in range(15):
                    angle = random.uniform(0, math.pi * 2)
                    speed = random.uniform(2, 5)
                    particle = Particle(
                        center_x, center_y,
                        BLOCK_GLOW[color_idx],
                        "sparkle"
                    )
                    particle.speed_x = math.cos(angle) * speed
                    particle.speed_y = math.sin(angle) * speed
                    particle.gravity = 0.1
                    particle.decay = random.uniform(0.01, 0.03)
                    self.clear_effects.append(particle)
                
                # 创建爆炸动画
                for _ in range(5):
                    size = random.randint(20, 40)
                    self.animations.append({
                        'type': 'explosion',
                        'x': center_x,
                        'y': center_y,
                        'size': size,
                        'max_size': size * 2,
                        'color': BLOCK_COLORS[color_idx],
                        'life': 1.0,
                        'decay': 0.05
                    })
    
    def _create_multi_line_effect(self, lines_cleared, lines_to_clear):
        """创建多行消除特效"""
        center_x = SCREEN_WIDTH // 2
        center_y = SCREEN_HEIGHT // 2
        
        # 根据消除行数设置不同的颜色和文字
        if lines_cleared == 2:
            text = f"DOUBLE!"
            color = (100, 200, 255)  # 蓝色
            size = 50
        elif lines_cleared == 3:
            text = f"TRIPLE!"
            color = (100, 255, 100)  # 绿色
            size = 60
        elif lines_cleared == 4:
            text = f"TETRIS!"
            color = (255, 100, 100)  # 红色
            size = 70
        else:
            text = f"COMBO x{lines_cleared}!"
            color = (255, 255, 100)  # 黄色
            size = 80
        
        # 创建多行消除动画
        self.animations.append({
            'type': 'multi_line',
            'text': text,
            'x': center_x,
            'y': center_y,
            'size': size,
            'color': color,
            'life': 1.0,
            'decay': 0.02
        })
        
        # 添加粒子特效
        for _ in range(30 * lines_cleared):
            angle = random.uniform(0, math.pi * 2)
            speed = random.uniform(3, 8)
            particle = Particle(
                center_x, center_y,
                (*color, 200),
                "sparkle"
            )
            particle.speed_x = math.cos(angle) * speed
            particle.speed_y = math.sin(angle) * speed
            particle.gravity = 0.1
            particle.decay = random.uniform(0.01, 0.03)
            self.clear_effects.append(particle)
    
    def lock_piece(self):
        """锁定当前方块 - 修复版本"""
        shape = self.current_piece.shape
        placed_blocks = 0
        
        # 先检查所有方块的位置
        for y, row in enumerate(shape):
            for x, cell in enumerate(row):
                if cell:
                    # 计算方块在网格中的实际位置
                    board_x = self.current_piece.x + x
                    board_y = self.current_piece.y + y
                    
                    # 确保位置在网格范围内
                    if (0 <= board_x < GRID_WIDTH and 
                        0 <= board_y < GRID_HEIGHT):
                        # 检查这个位置是否已经被占用
                        if self.grid[board_y][board_x] is None:
                            self.grid[board_y][board_x] = self.current_piece.color_idx
                            placed_blocks += 1
                        else:
                            # 这个位置已经被占用,记录错误
                            print(f"错误: 位置 ({board_x}, {board_y}) 已被占用!")
                            print(f"当前方块位置: ({self.current_piece.x}, {self.current_piece.y})")
                            print(f"方块形状: {shape}")
        
        # 确保至少放置了一个方块
        if placed_blocks == 0:
            print("警告: 没有放置任何方块!")
        
        # 添加锁定粒子
        for y, row in enumerate(shape):
            for x, cell in enumerate(row):
                if cell:
                    board_x = self.current_piece.x + x
                    board_y = self.current_piece.y + y
                    if (0 <= board_x < GRID_WIDTH and 
                        0 <= board_y < GRID_HEIGHT):
                        center_x = self.grid_left + board_x * GRID_SIZE + GRID_SIZE // 2
                        center_y = self.grid_top + board_y * GRID_SIZE + GRID_SIZE // 2
                        for _ in range(5):
                            self.particles.append(Particle(
                                center_x, center_y,
                                BLOCK_GLOW[self.current_piece.color_idx],
                                "sparkle"
                            ))
        
        cleared = self.clear_lines()
        if cleared > 0:
            # 添加连击特效
            if self.combo > 1:
                self._create_combo_effect()
        
        if not self.spawn_new_piece():
            self.game_over = True
    
    def _create_combo_effect(self):
        """创建连击特效"""
        center_x = SCREEN_WIDTH // 2
        center_y = SCREEN_HEIGHT // 2
        
        # 连击文字
        combo_text = f"COMBO x{self.combo}!"
        
        # 根据连击次数设置不同的颜色
        if self.combo == 2:
            color = (100, 200, 255)  # 蓝色
            size = 40
        elif self.combo == 3:
            color = (100, 255, 100)  # 绿色
            size = 45
        elif self.combo == 4:
            color = (255, 100, 100)  # 红色
            size = 50
        elif self.combo >= 5:
            color = (255, 255, 100)  # 黄色
            size = 55
        else:
            color = (255, 100, 255)  # 紫色
            size = 40
        
        self.animations.append({
            'type': 'combo',
            'text': combo_text,
            'x': center_x,
            'y': center_y - 100,  # 在屏幕上方显示,避免与多行消除重叠
            'size': size + self.combo * 2,
            'color': color,
            'life': 1.0,
            'decay': 0.02
        })
        
        # 播放连击音效
        if self.combo > 1 and 'combo' in self.sounds:
            try:
                # 连击次数越多,音量越大
                volume = min(1.0, 0.5 + (self.combo - 1) * 0.1)
                self.sounds['combo'].set_volume(volume)
                self.sounds['combo'].play()
            except:
                pass
    
    def update(self):
        """更新游戏状态"""
        current_time = pygame.time.get_ticks()
        
        # 更新背景星星
        for star in self.bg_stars:
            star['y'] += star['speed']
            if star['y'] > SCREEN_HEIGHT:
                star['y'] = 0
                star['x'] = random.randint(0, SCREEN_WIDTH)
        
        # 更新粒子
        for particle in self.particles[:]:
            if not particle.update():
                self.particles.remove(particle)
        
        for particle in self.clear_effects[:]:
            if not particle.update():
                self.clear_effects.remove(particle)
        
        # 更新动画
        for anim in self.animations[:]:
            anim['life'] -= anim.get('decay', 0.05)
            if anim['life'] <= 0:
                self.animations.remove(anim)
            else:
                if anim['type'] == 'explosion':
                    anim['size'] += 5
                elif anim['type'] in ['combo', 'multi_line']:
                    anim['y'] -= 2
                    # 让文字逐渐变大然后缩小
                    if anim['life'] > 0.5:
                        anim['size'] += 0.5
                    else:
                        anim['size'] -= 0.5
        
        # 自动下落
        if not self.game_over and self.state == "playing":
            if current_time - self.current_piece.drop_time > self.current_piece.move_delay:
                if not self.current_piece.move(0, 1, self.grid):
                    self.lock_piece()
                self.current_piece.drop_time = current_time
                self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
    
    def draw(self):
        """绘制游戏画面"""
        # 绘制背景
        self.screen.fill(COLORS['bg_dark'])
        
        # 绘制星空
        for star in self.bg_stars:
            brightness = int(star['brightness'] * 255)
            color = (brightness, brightness, brightness)
            pygame.draw.circle(self.screen, color, 
                             (int(star['x']), int(star['y'])), star['size'])
        
        # 绘制标题
        title = self.font_large.render("俄罗斯方块霓虹版", True, COLORS['text_accent'])
        title_shadow = self.font_large.render("俄罗斯方块霓虹版", True, (0, 0, 0))
        
        self.screen.blit(title_shadow, (SCREEN_WIDTH//2 - title.get_width()//2 + 2, 32))
        self.screen.blit(title, (SCREEN_WIDTH//2 - title.get_width()//2, 30))
        
        # 绘制游戏区域
        self._draw_game_area()
        
        # 绘制侧边栏
        self._draw_sidebar()
        
        # 绘制特效
        self._draw_effects()
        
        # 绘制调试信息
        self._draw_debug_info()
        
        # 绘制游戏状态
        if self.state == "paused":
            self._draw_pause_screen()
        elif self.state == "gameover":
            self._draw_game_over_screen()
        
        pygame.display.flip()
    
    def _draw_game_area(self):
        """绘制游戏区域"""
        # 绘制游戏区域背景
        game_area = pygame.Surface((GRID_WIDTH * GRID_SIZE + 20, 
                                  GRID_HEIGHT * GRID_SIZE + 20), pygame.SRCALPHA)
        game_area.fill((0, 0, 0, 100))
        pygame.draw.rect(game_area, COLORS['game_area_line'], 
                        (0, 0, GRID_WIDTH * GRID_SIZE + 20, GRID_HEIGHT * GRID_SIZE + 20), 
                        2, border_radius=10)
        self.screen.blit(game_area, (self.grid_left - 10, self.grid_top - 10))
        
        # 绘制网格背景
        grid_bg = pygame.Surface((GRID_WIDTH * GRID_SIZE, GRID_HEIGHT * GRID_SIZE), 
                               pygame.SRCALPHA)
        grid_bg.fill((*COLORS['bg_grid'][:3], 100))
        self.screen.blit(grid_bg, (self.grid_left, self.grid_top))
        
        # 绘制网格线
        for x in range(GRID_WIDTH + 1):
            pygame.draw.line(self.screen, COLORS['grid_line'],
                           (self.grid_left + x * GRID_SIZE, self.grid_top),
                           (self.grid_left + x * GRID_SIZE, 
                            self.grid_top + GRID_HEIGHT * GRID_SIZE))
        
        for y in range(GRID_HEIGHT + 1):
            pygame.draw.line(self.screen, COLORS['grid_line'],
                           (self.grid_left, self.grid_top + y * GRID_SIZE),
                           (self.grid_left + GRID_WIDTH * GRID_SIZE, 
                            self.grid_top + y * GRID_SIZE))
        
        # 绘制已固定的方块
        self._draw_fixed_blocks()
        
        # 绘制阴影方块
        if not self.game_over and self.state == "playing":
            ghost = Tetromino(self.current_piece.x, self.current_piece.y)
            ghost.shape_idx = self.current_piece.shape_idx
            ghost.rotation = self.current_piece.rotation
            ghost.color_idx = self.current_piece.color_idx
            ghost.y = self.current_piece.ghost_y
            ghost.draw(self.screen, self.grid_left, self.grid_top, True)
        
        # 绘制当前方块
        if not self.game_over and self.state == "playing":
            self.current_piece.draw(self.screen, self.grid_left, self.grid_top, 
                                  particles=self.particles)
    
    def _draw_fixed_blocks(self):
        """绘制已固定的方块"""
        for y in range(GRID_HEIGHT):
            for x in range(GRID_WIDTH):
                if self.grid[y][x] is not None:
                    color_idx = self.grid[y][x]
                    pos_x = self.grid_left + x * GRID_SIZE
                    pos_y = self.grid_top + y * GRID_SIZE
                    
                    # 绘制方块
                    color = BLOCK_COLORS[color_idx]
                    pygame.draw.rect(self.screen, color, 
                                   (pos_x, pos_y, GRID_SIZE, GRID_SIZE), 
                                   border_radius=4)
                    
                    # 3D效果
                    pygame.draw.rect(self.screen, (255, 255, 255, 50), 
                                   (pos_x, pos_y, GRID_SIZE, GRID_SIZE), 2, border_radius=4)
                    
                    # 内发光
                    inner_size = GRID_SIZE - 6
                    inner_surf = pygame.Surface((inner_size, inner_size), pygame.SRCALPHA)
                    pygame.draw.rect(inner_surf, (*color[:3], 150), 
                                   (0, 0, inner_size, inner_size), border_radius=2)
                    self.screen.blit(inner_surf, (pos_x + 3, pos_y + 3))
    
    def _draw_sidebar(self):
        """绘制侧边栏"""
        sidebar_x = SCREEN_WIDTH - SIDEBAR_WIDTH + 20
        
        # 绘制面板背景
        panel = pygame.Surface((SIDEBAR_WIDTH - 40, SCREEN_HEIGHT - 100), pygame.SRCALPHA)
        panel.fill(COLORS['panel_bg'])
        pygame.draw.rect(panel, COLORS['text_secondary'], 
                        (0, 0, SIDEBAR_WIDTH - 40, SCREEN_HEIGHT - 100), 2, border_radius=10)
        self.screen.blit(panel, (sidebar_x, 80))
        
        y_offset = 100
        
        # 分数
        self._draw_panel_text(f"分数: {self.score:,}", sidebar_x + 20, y_offset)
        y_offset += 50
        
        # 等级
        self._draw_panel_text(f"等级: {self.level}", sidebar_x + 20, y_offset)
        y_offset += 50
        
        # 已消除行数
        self._draw_panel_text(f"消除行数: {self.lines_cleared}", sidebar_x + 20, y_offset)
        y_offset += 50
        
        # 连击
        if self.combo > 1:
            combo_text = self.font_small.render(f"连击: x{self.combo}", True, 
                                              (255, 100, 100))
            self.screen.blit(combo_text, (sidebar_x + 20, y_offset))
            y_offset += 40
        
        # 下一个方块
        self._draw_panel_text("下一个:", sidebar_x + 20, y_offset)
        y_offset += 40
        
        # 绘制下一个方块预览
        self._draw_next_piece_preview(sidebar_x + 50, y_offset)
        y_offset += 120
        
        # 暂存方块
        self._draw_panel_text("暂存:", sidebar_x + 20, y_offset)
        y_offset += 40
        
        # 绘制暂存方块
        self._draw_hold_piece_preview(sidebar_x + 50, y_offset)
        y_offset += 120
        
        # 操作说明
        self._draw_controls(sidebar_x + 20, y_offset)
    
    def _draw_panel_text(self, text, x, y, color=None):
        """绘制面板文本"""
        if color is None:
            color = COLORS['text_primary']
        text_surface = self.font_small.render(text, True, color)
        self.screen.blit(text_surface, (x, y))
    
    def _draw_next_piece_preview(self, x, y):
        """绘制下一个方块预览"""
        preview_surf = pygame.Surface((120, 100), pygame.SRCALPHA)
        preview_surf.fill((0, 0, 0, 50))
        pygame.draw.rect(preview_surf, COLORS['text_secondary'], 
                        (0, 0, 120, 100), 2, border_radius=8)
        
        # 绘制下一个方块
        shape = self.next_piece.shape
        shape_width = len(shape[0]) if shape else 0
        shape_height = len(shape)
        
        preview_x = (120 - shape_width * 20) // 2
        preview_y = (100 - shape_height * 20) // 2
        
        for sy, row in enumerate(shape):
            for sx, cell in enumerate(row):
                if cell:
                    block_x = preview_x + sx * 20
                    block_y = preview_y + sy * 20
                    color = BLOCK_COLORS[self.next_piece.color_idx]
                    pygame.draw.rect(preview_surf, color, 
                                   (block_x, block_y, 18, 18), border_radius=3)
                    pygame.draw.rect(preview_surf, (255, 255, 255, 150), 
                                   (block_x, block_y, 18, 18), 1, border_radius=3)
        
        self.screen.blit(preview_surf, (x, y))
    
    def _draw_hold_piece_preview(self, x, y):
        """绘制暂存方块预览"""
        preview_surf = pygame.Surface((120, 100), pygame.SRCALPHA)
        preview_surf.fill((0, 0, 0, 50))
        pygame.draw.rect(preview_surf, COLORS['text_secondary'], 
                        (0, 0, 120, 100), 2, border_radius=8)
        
        if self.hold_piece:
            shape = self.hold_piece.shape
            shape_width = len(shape[0]) if shape else 0
            shape_height = len(shape)
            
            preview_x = (120 - shape_width * 20) // 2
            preview_y = (100 - shape_height * 20) // 2
            
            for sy, row in enumerate(shape):
                for sx, cell in enumerate(row):
                    if cell:
                        block_x = preview_x + sx * 20
                        block_y = preview_y + sy * 20
                        color = BLOCK_COLORS[self.hold_piece.color_idx]
                        pygame.draw.rect(preview_surf, color, 
                                       (block_x, block_y, 18, 18), border_radius=3)
                        pygame.draw.rect(preview_surf, (255, 255, 255, 150), 
                                       (block_x, block_y, 18, 18), 1, border_radius=3)
        
        self.screen.blit(preview_surf, (x, y))
    
    def _draw_controls(self, x, y):
        """绘制操作说明"""
        controls = [
            "by xhlbudd@52pojie",
            "← → : 左右移动",
            "↑   : 旋转",
            "↓   : 加速下落",
            "空格 : 硬降到底部",
            "C   : 暂存方块",
            "P   : 暂停/继续",
            "R   : 重新开始",
            "ESC : 退出游戏"
        ]
        
        for i, text in enumerate(controls):
            color = COLORS['text_accent'] if i == 0 else COLORS['text_secondary']
            text_surf = self.font_small.render(text, True, color)
            self.screen.blit(text_surf, (x, y + i * 25))
    
    def _draw_debug_info(self):
        """绘制调试信息"""
        if self.debug_info:
            debug_y = 50
            for info in self.debug_info[:5]:  # 只显示前5行
                debug_text = self.font_small.render(info, True, (255, 255, 0))
                self.screen.blit(debug_text, (20, debug_y))
                debug_y += 25
    
    def _draw_effects(self):
        """绘制特效"""
        # 绘制粒子
        for particle in self.particles:
            particle.draw(self.screen)
        
        for particle in self.clear_effects:
            particle.draw(self.screen)
        
        # 绘制动画
        for anim in self.animations:
            if anim['type'] == 'explosion':
                self._draw_explosion(anim)
            elif anim['type'] == 'combo':
                self._draw_combo_text(anim)
            elif anim['type'] == 'multi_line':
                self._draw_multi_line_text(anim)
    
    def _draw_explosion(self, anim):
        """绘制爆炸特效"""
        alpha = int(anim['life'] * 255)
        size = anim['size']
        
        # 创建爆炸表面
        explosion = pygame.Surface((size * 2, size * 2), pygame.SRCALPHA)
        
        # 绘制多个同心圆
        for i in range(3):
            radius = int(size * (1 - i * 0.3))
            color = (*anim['color'][:3], alpha // (i + 1))
            pygame.draw.circle(explosion, color, (size, size), radius)
        
        self.screen.blit(explosion, (anim['x'] - size, anim['y'] - size))
    
    def _draw_combo_text(self, anim):
        """绘制连击文字"""
        alpha = int(anim['life'] * 255)
        font = load_font(int(anim['size']), True)
        
        text = font.render(anim['text'], True, (*anim['color'], alpha))
        text_shadow = font.render(anim['text'], True, (0, 0, 0, alpha))
        
        text_rect = text.get_rect(center=(anim['x'], anim['y']))
        shadow_rect = text_shadow.get_rect(center=(anim['x'] + 3, anim['y'] + 3))
        
        self.screen.blit(text_shadow, shadow_rect)
        self.screen.blit(text, text_rect)
    
    def _draw_multi_line_text(self, anim):
        """绘制多行消除文字"""
        alpha = int(anim['life'] * 255)
        font = load_font(int(anim['size']), True)
        
        # 绘制文字
        text = font.render(anim['text'], True, (*anim['color'], alpha))
        text_shadow = font.render(anim['text'], True, (0, 0, 0, alpha))
        
        text_rect = text.get_rect(center=(anim['x'], anim['y']))
        shadow_rect = text_shadow.get_rect(center=(anim['x'] + 4, anim['y'] + 4))
        
        self.screen.blit(text_shadow, shadow_rect)
        self.screen.blit(text, text_rect)
        
        # 绘制发光效果
        if alpha > 100:
            glow_size = int(anim['size'] * 1.5)
            glow_font = load_font(glow_size, True)
            glow_text = glow_font.render(anim['text'], True, (*anim['color'], alpha // 3))
            glow_rect = glow_text.get_rect(center=(anim['x'], anim['y']))
            self.screen.blit(glow_text, glow_rect)
    
    def _draw_pause_screen(self):
        """绘制暂停屏幕"""
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 180))
        self.screen.blit(overlay, (0, 0))
        
        pause_text = self.font_large.render("游戏暂停", True, COLORS['text_accent'])
        pause_shadow = self.font_large.render("游戏暂停", True, (0, 0, 0))
        
        self.screen.blit(pause_shadow, (SCREEN_WIDTH//2 - pause_text.get_width()//2 + 2, 302))
        self.screen.blit(pause_text, (SCREEN_WIDTH//2 - pause_text.get_width()//2, 300))
        
        continue_text = self.font_medium.render("按 P 键继续游戏", True, COLORS['text_primary'])
        self.screen.blit(continue_text, (SCREEN_WIDTH//2 - continue_text.get_width()//2, 380))
    
    def _draw_game_over_screen(self):
        """绘制游戏结束屏幕"""
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        self.screen.blit(overlay, (0, 0))
        
        game_over = self.font_large.render("游戏结束!", True, (255, 100, 100))
        game_over_shadow = self.font_large.render("游戏结束!", True, (0, 0, 0))
        
        self.screen.blit(game_over_shadow, (SCREEN_WIDTH//2 - game_over.get_width()//2 + 2, 252))
        self.screen.blit(game_over, (SCREEN_WIDTH//2 - game_over.get_width()//2, 250))
        
        score_text = self.font_medium.render(f"最终分数: {self.score:,}", True, COLORS['text_primary'])
        self.screen.blit(score_text, (SCREEN_WIDTH//2 - score_text.get_width()//2, 320))
        
        restart_text = self.font_medium.render("按 R 键重新开始", True, COLORS['text_accent'])
        self.screen.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, 380))
    
    def handle_events(self):
        """处理事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    return False
                
                elif event.key == pygame.K_r:
                    self.reset_game()
                    self.state = "playing"
                
                elif event.key == pygame.K_p:
                    if self.state == "playing":
                        self.state = "paused"
                    elif self.state == "paused":
                        self.state = "playing"
                
                if not self.game_over and self.state == "playing":
                    if event.key == pygame.K_c:
                        self.hold_current_piece()
                    
                    elif event.key == pygame.K_LEFT:
                        self.current_piece.move(-1, 0, self.grid)
                        self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
                    
                    elif event.key == pygame.K_RIGHT:
                        self.current_piece.move(1, 0, self.grid)
                        self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
                    
                    elif event.key == pygame.K_UP:
                        self.current_piece.rotate(self.grid)
                        self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
                    
                    elif event.key == pygame.K_DOWN:
                        if self.current_piece.move(0, 1, self.grid):
                            self.current_piece.ghost_y = self.current_piece.calculate_ghost(self.grid)
                    
                    elif event.key == pygame.K_SPACE:
                        distance = self.current_piece.hard_drop(self.grid)
                        if distance > 0:
                            # 添加硬降特效
                            for _ in range(distance * 2):
                                self.particles.append(Particle(
                                    self.grid_left + self.current_piece.x * GRID_SIZE + GRID_SIZE // 2,
                                    self.grid_top + self.current_piece.y * GRID_SIZE + GRID_SIZE // 2,
                                    BLOCK_GLOW[self.current_piece.color_idx],
                                    "sparkle"
                                ))
                        self.lock_piece()
        
        return True
    
    def run(self):
        """运行游戏主循环"""
        print("&#127918; 霓虹俄罗斯方块 已启动!")
        print("=" * 50)
        print("操作说明:")
        print("  ← →   : 左右移动方块")
        print("  ↑     : 旋转方块")
        print("  ↓     : 加速下落")
        print("  空格   : 硬降到底部")
        print("  C     : 暂存当前方块")
        print("  P     : 暂停/继续游戏")
        print("  R     : 重新开始游戏")
        print("  ESC   : 退出游戏")
        print("=" * 50)
        print("游戏特点:")
        print("  &#8226; 霓虹未来风格界面")
        print("  &#8226; 粒子特效和动画")
        print("  &#8226; 阴影预测和暂存功能")
        print("  &#8226; 连击系统和分数加成")
        print("  &#8226; 背景星空动画")
        print("  &#8226; 音效系统(单行/多行消除)")
        print("  &#8226; 多行消除特效(DOUBLE/TRIPLE/TETRIS)")
        print("  &#8226; 调试信息显示(左上角)")
        print("=" * 50)
        
        running = True
        while running:
            running = self.handle_events()
            self.update()
            self.draw()
            self.clock.tick(60)
        
        pygame.quit()
        sys.exit()

# 主程序入口
if __name__ == "__main__":
    # 检查依赖
    try:
        import pygame
    except ImportError:
        print("错误: 需要安装 pygame 库")
        print("请运行: pip install pygame")
        sys.exit(1)
    
    # 运行游戏
    game = TetrisGame()
    game.run()

游戏截图.png (166.3 KB, 下载次数: 0)

游戏截图

游戏截图

免费评分

参与人数 7吾爱币 +13 热心值 +6 收起 理由
junlangzhang2 + 1 + 1 谢谢@Thanks!
cxxp + 1 + 1 您有没有原创的小游戏的代码,想买个。做毕业设计作品 微 O50838
hurric + 1 蓝奏连接在11楼
jmxxzpc + 1 + 1 谢谢@Thanks!
tbk416 + 1 + 1 感谢分享
wblylh + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
风之暇想 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| xhlbudd 发表于 2026-5-4 12:55 |楼主
XIAOYU2028 发表于 2026-5-4 05:39
能打包成安卓手机版吗?非常感谢!

谢谢建议,我找时间学习一下,如何打包成安卓版~~
推荐
 楼主| xhlbudd 发表于 2026-5-3 22:38 |楼主
wblylh 发表于 2026-5-3 21:19
能把教的过程写下来吗?每次都用什么项目练习。

一般都会先讲基础语法,如顺序、选择、循环;字符串、列表、字典、元组、集合;函数,类等等。每个知识点都用一些比较简短生动的例子,然后用一个Pygame开发的游戏做综合训练,一边玩游戏,一边改代码,用“控制变量法”,让小朋友感受Python代码是如何控制游戏里的逻辑、精灵等等。
沙发
wblylh 发表于 2026-5-3 21:19
能把教的过程写下来吗?每次都用什么项目练习。
4#
XIAOYU2028 发表于 2026-5-4 05:39
能打包成安卓手机版吗?非常感谢!
6#
wblylh 发表于 2026-5-4 19:23
xhlbudd 发表于 2026-5-3 22:38
一般都会先讲基础语法,如顺序、选择、循环;字符串、列表、字典、元组、集合;函数,类等等。每个知识点 ...

我在自学Python,这些顺序、选择、循环;字符串、列表、字典、元组、集合;函数,类等都跟着学了。但是刚接触pygame还是不怎么会用,要是有你这些从简到难的例子就好了,不然难度弄错顺序,学的挺难受。
7#
 楼主| xhlbudd 发表于 2026-5-4 21:45 |楼主
wblylh 发表于 2026-5-4 19:23
我在自学Python,这些顺序、选择、循环;字符串、列表、字典、元组、集合;函数,类等都跟着学了。但是刚 ...

B站有很多教程很好,直接搜索“Pygame教程”就可以~~
8#
pentium 发表于 2026-5-5 09:08
感谢分享,支持源代码的。
9#
1056756242 发表于 2026-5-5 15:04
经典游戏好玩
10#
lovepanda13 发表于 2026-5-5 18:38
卧槽牛逼啊
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-5-7 12:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表