使用DeepSeek定制Python小游戏——以“俄罗斯方块”为例
前言
本来想再发几个小游戏后在整理一下流程的,但是今天试了一下这个俄罗斯方块的游戏结果发现本来修改的好好的的,结果后面越改越乱,前面的版本也没保存,根据AI修改他是在几个版本改来改去,想着要求还是不能这么高。我是采用DeepSeek+Pycharm+Lingma来操作的。
贪吃蛇(含Python源码)-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/147660127?spm=1001.2014.3001.5501
外星人入侵(python)_外星人入侵python源代码-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/135963588?spm=1001.2014.3001.5501
DeepSeek部分
对于DeepSeek我是直接询问“Python可以设计哪些简单的小游戏”,然后根据推荐的游戏挑选直接感兴趣的,比如可以询问“用Python代码实现俄罗斯方块小游戏”,于是就生成了以下的代码,因为我是选择了联网搜索,所以肯定会借鉴其他博主代码:
import pygame
import random# 初始化 Pygame
pygame.init()# 游戏窗口尺寸和颜色
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
COLORS = [(0, 255, 255), # I 型(青色)(255, 165, 0), # L 型(橙色)(0, 0, 255), # J 型(蓝色)(255, 255, 0), # O 型(黄色)(0, 255, 0), # S 型(绿色)(255, 0, 255), # T 型(紫色)(255, 0, 0) # Z 型(红色)
]# 方块形状定义(4x4 矩阵)
SHAPES = [[[1, 1, 1, 1]], # I 型[[1, 0, 0], [1, 1, 1]], # L 型[[0, 0, 1], [1, 1, 1]], # J 型[[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 型
]# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")# 游戏区域矩阵(0表示空)
game_area = [[0] * GRID_WIDTH for _ in range(GRID_HEIGHT)]# 当前方块和位置
current_shape = None
current_pos = [0, 0]
current_color = None
score = 0def new_shape():"""生成新方块"""global current_shape, current_pos, current_colorcurrent_shape = random.choice(SHAPES)current_color = random.choice(COLORS)current_pos = [GRID_WIDTH // 2 - len(current_shape[0]) // 2, 0]def check_collision(shape, pos):"""检查方块是否与边界或已有方块碰撞"""for y, row in enumerate(shape):for x, cell in enumerate(row):if cell:px = pos[0] + xpy = pos[1] + yif px < 0 or px >= GRID_WIDTH or py >= GRID_HEIGHT:return Trueif py >= 0 and game_area[py][px]:return Truereturn Falsedef merge_shape():"""将当前方块合并到游戏区域"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:game_area[current_pos[1] + y][current_pos[0] + x] = current_colordef clear_lines():"""消除满行并更新分数"""global scorelines_to_clear = [i for i, row in enumerate(game_area) if all(cell != 0 for cell in row)]for i in lines_to_clear:del game_area[i]game_area.insert(0, [0] * GRID_WIDTH)score += len(lines_to_clear) * 100def rotate_shape():"""旋转当前方块(顺时针)"""global current_shaperotated = list(zip(*current_shape[::-1]))if not check_collision(rotated, current_pos):current_shape = rotateddef draw_grid():"""绘制游戏区域"""for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = game_area[y][x]if color:pygame.draw.rect(screen, color, (x*GRID_SIZE, y*GRID_SIZE, GRID_SIZE-1, GRID_SIZE-1))def draw_current_shape():"""绘制当前下落的方块"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:px = (current_pos[0] + x) * GRID_SIZEpy = (current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, current_color, (px, py, GRID_SIZE-1, GRID_SIZE-1))def game_loop():clock = pygame.time.Clock()fall_time = 0fall_speed = 500 # 下落间隔(毫秒)new_shape()running = Truewhile running:screen.fill(BLACK)current_time = pygame.time.get_ticks()# 处理输入事件for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:current_pos[0] -= 1if check_collision(current_shape, current_pos):current_pos[0] += 1if event.key == pygame.K_RIGHT:current_pos[0] += 1if check_collision(current_shape, current_pos):current_pos[0] -= 1if event.key == pygame.K_DOWN:current_pos[1] += 1if check_collision(current_shape, current_pos):current_pos[1] -= 1if event.key == pygame.K_UP:rotate_shape()if event.key == pygame.K_SPACE: # 快速下落while not check_collision(current_shape, current_pos):current_pos[1] += 1current_pos[1] -= 1# 自动下落if current_time - fall_time > fall_speed:current_pos[1] += 1if check_collision(current_shape, current_pos):current_pos[1] -= 1merge_shape()clear_lines()new_shape()if check_collision(current_shape, current_pos):running = False # 游戏结束fall_time = current_time# 绘制界面draw_grid()draw_current_shape()pygame.display.update()clock.tick(60)# 游戏结束提示font = pygame.font.Font(None, 74)text = font.render(f'Game Over! Score: {score}', True, WHITE)screen.blit(text, (WINDOW_WIDTH//2 - 200, WINDOW_HEIGHT//2 - 50))pygame.display.update()pygame.time.wait(3000)if __name__ == "__main__":game_loop()pygame.quit()
如果直接运行当然会存在一些的问题,比如这个右侧是空白的,但是方块无法移动过去。
Pycharm+Lingma部分
我主要是用的这个插件进行修改代码,一方面可以让他对代码进行优化,另一方面还能询问可以增加什么特色的功能。
比如我想增加历史最高分的模块以及右侧可以用来显示下一个方块的相关信息,本来一切都向着好方向修改,结果却越改越乱,下面的代码用DeepSeek应该是修改不了,所以建议新增功能还是一个个功能的增加测试,不然不清楚哪里有问题,还需要慢慢调试,对于要修改的地方可以通过Ctrl+F来搜索进行快速定位,对于代码报错或者警告的信息也可以询问Lingma进行修改,甚至可以进行直接替换(但是感觉不保险,怕乱改)。
以下的代码存在着很多问题,但是又不想删除(毕竟改了一下午),所以也放出来的,有感兴趣的大佬可以看一下,目前存在的问题是游戏无法结束,他触碰到上底后会在下底增加方块,还有这个生存模式根据DeepSeek的操作应该是要增加障碍,还有这个不同颜色方块的功能,应该就是突然增加太多了导致代码出问题了。
# -*- coding: utf-8 -*-
import pygame
import random
import os
from typing import List, Tuple, Optional# 初始化 Pygame
pygame.init()
os.environ['PYGAME_FREETYPE'] = '1' # 启用更好字体渲染# 新增最高分文件路径
HIGHSCORE_FILE = "tetris_highscore.txt"# 在文件开头添加字体常量
FONT_CONFIG = {"simhei": {"path": "simhei.ttf","sizes": {"title": 36, "subtitle": 28, "normal": 24}},"backup": {"name": "arial","sizes": {"title": 36, "subtitle": 28, "normal": 24}}
}# 修改字体加载函数
def load_font(font_type: str, size_type: str):"""统一字体加载函数(优化版)"""# 直接使用系统字体名称try:return pygame.font.SysFont("simhei", FONT_CONFIG["simhei"]["sizes"][size_type])except Exception as e:print(f"系统字体加载失败: {e}")try:return pygame.font.Font(None, FONT_CONFIG["backup"]["sizes"][size_type])except:return pygame.font.SysFont(FONT_CONFIG["backup"]["name"],FONT_CONFIG["backup"]["sizes"][size_type])def load_highscore():"""加载历史最高分"""try:if os.path.exists(HIGHSCORE_FILE):with open(HIGHSCORE_FILE, 'r') as f:return int(f.read().strip() or 0)return 0except Exception as e:print(f"读取最高分失败: {e}")return 0def save_highscore(score):"""保存最高分"""with open(HIGHSCORE_FILE, 'w') as f:f.write(str(score))# 游戏窗口尺寸和颜色
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
DARK_GRAY = (40, 40, 40) # 游戏区域背景色
COLORS = [(0, 255, 255), # I 型(青色)(255, 165, 0), # L 型(橙色)(0, 0, 255), # J 型(蓝色)(255, 255, 0), # O 型(黄色)(0, 255, 0), # S 型(绿色)(255, 0, 255), # T 型(紫色)(255, 0, 0) # Z 型(红色)
]
# 特殊方块颜色
SPECIAL_COLORS = [(255, 100, 100), # 爆炸红:消除整行(100, 255, 100), # 加速绿:下落速度x2(100, 100, 255) # 护盾蓝:免疫下一次碰撞
]
COLORS += SPECIAL_COLORS# 方块形状定义(4x4 矩阵)
SHAPES = [[[1, 1, 1, 1]], # I 型[[1, 0, 0], [1, 1, 1]], # L 型[[0, 0, 1], [1, 1, 1]], # J 型[[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 型
]
# 新增游戏状态常量
GAME_STATES = {'START': 0,'MODE_SELECT': 1, # 新增模式选择状态'PLAYING': 2,'GAME_OVER': 3
}# 修改游戏界面布局参数(新增右侧信息面板)
INFO_PANEL_WIDTH = 200 # 右侧信息面板宽度
GAME_PANEL_WIDTH = GRID_WIDTH * GRID_SIZE # 300
# 游戏界面宽度
WINDOW_WIDTH = GAME_PANEL_WIDTH + INFO_PANEL_WIDTH
# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")# 游戏区域矩阵(0表示空)
game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]# 当前方块和位置
current_shape: Optional[List[List[int]]] = None
current_pos = [0, 0]
current_color: Optional[Tuple[int, int, int]] = None
# 在全局变量声明区域添加:
next_shape: Optional[List[List[int]]] = None
next_color: Optional[Tuple[int, int, int]] = None
score = 0
# 新增全局变量
game_mode = 0 # 0-经典模式 1-生存模式
obstacle_timer = 0
special_effect = None
effect_duration = 0# 修改new_shape函数(添加下一个方块生成)
def new_shape():global current_shape, current_pos, current_color, next_shape, next_colorif not hasattr(new_shape, "_initialized"):current_shape = random.choice(SHAPES)current_color = random.choice(COLORS)next_shape = random.choice(SHAPES)next_color = random.choice(COLORS)new_shape._initialized = Trueelse:current_shape = next_shapecurrent_color = next_colornext_shape = random.choice(SHAPES)next_color = random.choice(COLORS)if random.random() < 0.2 and current_color not in SPECIAL_COLORS:current_color = random.choice(SPECIAL_COLORS)# 修复点1:计算方块总高度shape_height = len(current_shape)# 修复点2:调整生成位置计算逻辑 ▼base_offset = -shape_height # 确保整个方块在屏幕外# 生存模式额外上移(原逻辑错误导致坐标计算为负值不够)if game_mode == 1:base_offset = -shape_height - 2 # 调整为-2格缓冲current_pos = [GRID_WIDTH // 2 - len(current_shape[0]) // 2,base_offset # Y坐标修正]def check_collision(shape, pos):"""统一碰撞检测(移除模式判断)"""# 修改点1:block → shapefor y in range(len(shape)): # ← 修改这里# 修改点2:block.shape → shapefor x in range(len(shape[y])): # ← 修改这里# 修改点3:cell → shape[y][x]if shape[y][x]: # ← 修改这里(原cell未定义)px = pos[0] + xpy = pos[1] + y# 边界检测if px < 0 or px >= GRID_WIDTH:return Trueif py >= GRID_HEIGHT: # 底部边界return True# 有效区域检测(包含顶部边界)if py >= 0 and game_area[py][px] is not None:return Truereturn Falsedef merge_shape():"""将当前方块合并到游戏区域"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:game_area[current_pos[1] + y][current_pos[0] + x] = current_colordef clear_lines():"""消除满行并更新分数"""global score, fall_speed, game_arealines_to_clear = [i for i, row in enumerate(game_area) if all(cell is not None for cell in row)]# 删除并补充新行(保持总行数不变)for _ in lines_to_clear:del game_area[0] # 删除顶部行(原逻辑错误:删除指定索引行)game_area.append([None] * GRID_WIDTH) # 在底部补充新行score += len(lines_to_clear) * 100fall_speed = max(50, 500 - (score // 100) * 50) # 每得100分加快50msdef rotate_shape():"""旋转当前方块(顺时针)"""global current_shaperotated = [list(row) for row in zip(*current_shape[::-1])] # 转换为列表的列表if not check_collision(rotated, current_pos):current_shape = rotateddef draw_grid():"""绘制游戏区域(增加维度保护)"""assert len(game_area) == GRID_HEIGHT, \f"游戏区域行数异常:{len(game_area)}(应保持{GRID_HEIGHT}行)"assert all(len(row) == GRID_WIDTH for row in game_area), \"游戏区域列数异常"for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = game_area[y][x]# 加颜色有效性验证(必须为三元组且数值合法)if color is not None and isinstance(color, tuple) and len(color) == 3:pygame.draw.rect(screen, color, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))def draw_current_shape():"""绘制当前下落的方块"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:px = (current_pos[0] + x) * GRID_SIZEpy = (current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, current_color, (px, py, GRID_SIZE - 1, GRID_SIZE - 1))# 新增右侧信息面板绘制函数
def draw_info_panel(score, highscore, next_shape, next_color, mode, effect):# 绘制右侧面板背景pygame.draw.rect(screen, BLACK, (GAME_PANEL_WIDTH, 0, INFO_PANEL_WIDTH, WINDOW_HEIGHT))# 统一字体加载(修改关键部分)main_font = load_font("simhei", "normal") # 使用预设的24号字small_font = load_font("simhei", "subtitle") # 使用28号字# 修改显示文本为中文# 显示下一个方块标题(修正坐标计算)title_text = main_font.render("下一个方块", True, WHITE)title_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - title_text.get_width()) // 2screen.blit(title_text, (title_x, 30)) # 原100改为30避免重叠# 分数显示修正(使用统一字体)score_text = main_font.render(f"当前分数:{score}", True, WHITE)screen.blit(score_text, (GAME_PANEL_WIDTH + 10, 300)) # 原使用Font(None)处# 显示最高分highscore_text = main_font.render(f"最高纪录:{highscore}", True, WHITE)screen.blit(highscore_text, (GAME_PANEL_WIDTH + 10, 350))# 计算预览方块位置(居中显示)preview_size = len(next_shape[0]) * GRID_SIZEstart_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - preview_size) // 2start_y = 100# 绘制预览方块for y, row in enumerate(next_shape):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, next_color, (start_x + x * GRID_SIZE,start_y + y * GRID_SIZE,GRID_SIZE - 1, GRID_SIZE - 1))# 添加模式显示mode_text = main_font.render( # 使用已定义的main_fontf"模式:{'生存' if mode else '经典'}",True,(255, 0, 0) if mode else (0, 255, 0))screen.blit(mode_text, (GAME_PANEL_WIDTH + 10, 400))# 显示当前特效if effect:effect_mapping = {'speed': '加速', 'shield': '护盾'}effect_text = main_font.render( # 使用已定义的main_fontf"特效:{effect_mapping.get(effect, '未知')}",True,(255, 255, 0))screen.blit(effect_text, (GAME_PANEL_WIDTH + 10, 450))# 新增开始界面
def show_start_screen(highscore):# 添加中文字体支持try:title_font = pygame.font.SysFont("SimHei", 36)text_font = pygame.font.SysFont("SimHei", 24)except:try:title_font = pygame.font.Font("msyh.ttc", 36)text_font = pygame.font.Font("msyh.ttc", 24)except:title_font = pygame.font.Font(None, 36)text_font = pygame.font.Font(None, 24)screen.fill(BLACK)title = title_font.render("俄罗斯方块", True, WHITE)title_rect = title.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 70))screen.blit(title, title_rect)font = pygame.font.Font(None, 32)prompt = title_font.render("按任意键开始游戏", True, WHITE)prompt_rect = prompt.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(prompt, prompt_rect)highscore_text = title_font.render(f"当前最高分: {highscore}", True, (200, 200, 200))highscore_rect = highscore_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 90))screen.blit(highscore_text, highscore_rect)pygame.display.update()waiting = Truewhile waiting:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()return Falseif event.type in (pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN):waiting = Falsereturn True# 新增模式选择界面(在show_start_screen函数后添加)
def show_mode_menu():screen.fill(BLACK)# 加载中文字体的正确方式font = load_font("simhei", "subtitle") # 28号字desc_font = load_font("simhei", "normal") # 24号字# 打印调试信息print(f"当前使用字体: {font}")print("可用系统字体:", pygame.font.get_fonts())# 绘制标题title = font.render("选择游戏模式", True, (255, 255, 0))title_rect = title.get_rect(center=(WINDOW_WIDTH // 2, 60))screen.blit(title, title_rect)# 模式按钮参数modes = [{"text": "经典模式","desc": "标准俄罗斯方块规则","key": "1","color": (0, 255, 255),"rect": pygame.Rect(WINDOW_WIDTH // 2 - 180, 120, 360, 60)},{"text": "生存模式","desc": "每30秒生成障碍行","key": "2","color": (255, 0, 0),"rect": pygame.Rect(WINDOW_WIDTH // 2 - 180, 210, 360, 60)}]# 绘制模式选项for mode in modes:# 按钮背景pygame.draw.rect(screen, (30, 30, 30), mode["rect"], border_radius=10)# 模式名称text_surf = font.render(f"{mode['key']}. {mode['text']}", True, mode["color"])text_rect = text_surf.get_rect(left=mode["rect"].left + 20, centery=mode["rect"].centery - 15)screen.blit(text_surf, text_rect)# 模式描述desc_surf = desc_font.render(mode["desc"], True, (200, 200, 200))desc_rect = desc_surf.get_rect(left=mode["rect"].left + 20, centery=mode["rect"].centery + 15)screen.blit(desc_surf, desc_rect)# 绘制提示文字prompt = desc_font.render("使用数字键选择 或 鼠标点击选择", True, (150, 150, 150))prompt_rect = prompt.get_rect(center=(WINDOW_WIDTH // 2, 320))screen.blit(prompt, prompt_rect)pygame.display.update()while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_1: return 0if event.key == pygame.K_2: return 1if event.type == pygame.MOUSEBUTTONDOWN:mouse_pos = pygame.mouse.get_pos()for idx, mode in enumerate(modes):if mode["rect"].collidepoint(mouse_pos):return idx # 0或1对应模式def game_loop():'''游戏主循环'''global score, game_area, current_shape, current_pos, current_color, next_shape, next_colorglobal game_mode, obstacle_timer, special_effect, effect_duration# 初始化游戏状态current_state = GAME_STATES['START']highscore = load_highscore()running = Trueclock = pygame.time.Clock()fall_time = pygame.time.get_ticks()fall_speed = 10 # 下落间隔(毫秒)while running:current_time = pygame.time.get_ticks()# 状态处理if current_state == GAME_STATES['PLAYING']:assert len(game_area) == GRID_HEIGHT, "游戏区域行数异常"assert all(len(row) == GRID_WIDTH for row in game_area), "游戏区域列数异常"if current_state == GAME_STATES['START']:if not show_start_screen(highscore):returncurrent_state = GAME_STATES['MODE_SELECT']if current_state == GAME_STATES['MODE_SELECT']:game_mode = show_mode_menu()game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]score = 0if game_mode == 1:game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]obstacle_timer = pygame.time.get_ticks()for _ in range(3):obstacle_row = [DARK_GRAY if random.random() < 0.3 else None for _ in range(GRID_WIDTH)]game_area.insert(0, obstacle_row)del game_area[-1]if hasattr(new_shape, "_initialized"):del new_shape._initializednew_shape()new_shape()current_state = GAME_STATES['PLAYING']# 事件处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:current_pos[0] -= 1if check_collision(current_shape, current_pos):current_pos[0] += 1if event.key == pygame.K_RIGHT:current_pos[0] += 1if check_collision(current_shape, current_pos):current_pos[0] -= 1if event.key == pygame.K_DOWN:current_pos[1] += 1if check_collision(current_shape, current_pos):current_pos[1] -= 1if event.key == pygame.K_UP:rotate_shape()if event.key == pygame.K_SPACE: # 快速下落while not check_collision(current_shape, current_pos):current_pos[1] += 1current_pos[1] -= 1draw_current_shape()pygame.display.update()# 自动下落逻辑if current_time - fall_time > (fall_speed if special_effect != 'speed' else fall_speed // 2):current_pos[1] += 1fall_time = current_timeif check_collision(current_shape, current_pos):current_pos[1] -= 1# 经典模式立即合并if game_mode == 0:merge_shape()clear_lines()new_shape()# 生存模式特殊处理else:if (current_pos[1] + len(current_shape)) > 0: # 底部进入可见区域merge_shape()clear_lines()new_shape()# 生存模式障碍生成if game_mode == 1:if current_time - obstacle_timer > 30000:new_row = [DARK_GRAY if random.random() < 0.7 else None for _ in range(GRID_WIDTH)]game_area.insert(0, new_row)del game_area[-1]obstacle_timer = current_time# 统一结束判断if check_collision(current_shape, current_pos) and special_effect != 'shield':# 经典模式:触顶即结束if game_mode == 0 and current_pos[1] < 0:running = False# 生存模式:完全进入后碰撞才结束elif game_mode == 1 and (current_pos[1] + len(current_shape)) >= 0:running = False# 特效处理if special_effect and effect_duration > 0:effect_duration -= clock.get_time()if effect_duration <= 0:special_effect = None# 绘制界面screen.fill(DARK_GRAY)draw_grid()draw_current_shape()draw_info_panel(score, highscore, next_shape, next_color, game_mode, special_effect)pygame.display.update()clock.tick(60)# 游戏结束处理if not running:if score > highscore:save_highscore(score)highscore = scorescreen.fill(BLACK)try:font = pygame.font.SysFont("simhei", 48)except:font = pygame.font.Font(None, 48)game_over_text = font.render("游戏结束", True, (255, 0, 0))text_rect = game_over_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 30))screen.blit(game_over_text, text_rect)score_text = font.render(f"最终得分: {score}", True, WHITE)score_rect = score_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(score_text, score_rect)pygame.display.update()pygame.time.wait(3000)current_state = GAME_STATES['GAME_OVER']if current_state == GAME_STATES['GAME_OVER']:if not show_start_screen(highscore):running = Falseelse:current_state = GAME_STATES['START']if __name__ == "__main__":game_loop()pygame.quit()
修改后的代码
我测试了几次,主要之前出现的问题就是
- 游戏无法正常结束,当方块触碰到上方越界后,方块从最下方更新。
- 方块没有正常清除,当本行方块填满后他整体上移,而不是清除的效果。
- 游戏无法正常开始,方块下移的速度太快,开始游戏后直接结束了。
- 方块预览和实际出现的方块之间没有关系。
修改后游戏具备一下的特色功能:
下一个方块预览
- 在右侧信息面板实时显示即将出现的方块形状与颜色
- 实现方法:通过 draw_info_panel 方法中的预览方块绘制逻辑
速度递增机制
- 得分每增加50分下落速度提升25ms(最大速度50ms)
- 代码体现:self.fall_speed = max(50, 500 - (self.score // 50) * 25)
智能位置修正
- 旋转时若超出边界自动尝试左右平移(rotate_shape 方法)
- 特征:最多平移至边界,若仍碰撞则取消旋转
- 优势:减少无效旋转操作挫败感
本地高分记录,使用 tetris_highscore.txt 文件存储历史最高分 功能点:
- 启动时自动读取 (load_highscore)
- 破纪录时自动保存 (save_highscore)
三维检测体系,check_collision 方法实现:
- 底部越界检测 (py >= GRID_HEIGHT)
- 侧边越界检测 (px < 0 or px >= GRID_WIDTH)
- 方块重叠检测 (game_area[py][px] is not None)
# -*- coding: utf-8 -*-
import pygame
import random
import os# 初始化 Pygame
pygame.init()
os.environ['PYGAME_FREETYPE'] = '1'# 常量定义
HIGHSCORE_FILE = "tetris_highscore.txt"
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
INFO_PANEL_WIDTH = 200
GAME_PANEL_WIDTH = GRID_WIDTH * GRID_SIZE
WINDOW_WIDTH = GAME_PANEL_WIDTH + INFO_PANEL_WIDTH# 颜色定义
COLORS = [(0, 255, 255), # I型(255, 165, 0), # L型(0, 0, 255), # J型(255, 255, 0), # O型(0, 255, 0), # S型(255, 0, 255), # T型(255, 0, 0) # Z型
]
BLACK = (0, 0, 0)
DARK_GRAY = (40, 40, 40)
WHITE = (255, 255, 255)# 方块形状定义
SHAPES = [[[1, 1, 1, 1]],[[1, 0, 0], [1, 1, 1]],[[0, 0, 1], [1, 1, 1]],[[1, 1], [1, 1]],[[0, 1, 1], [1, 1, 0]],[[0, 1, 0], [1, 1, 1]],[[1, 1, 0], [0, 1, 1]]
]# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")def load_font(size):try:return pygame.font.SysFont("simhei", size)except:return pygame.font.Font(None, size)def load_highscore():try:if os.path.exists(HIGHSCORE_FILE):with open(HIGHSCORE_FILE, 'r') as f:return int(f.read().strip() or 0)return 0except:return 0def save_highscore(score):with open(HIGHSCORE_FILE, 'w') as f:f.write(str(score))class GameState:def __init__(self):self.reset()def reset(self):self.game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]self.score = 0self.highscore = load_highscore()# 仅初始化next_shapeself.next_shape = random.choice(SHAPES)self.next_color = random.choice(COLORS)self.fall_speed = 500self.running = Trueself.initialize_shapes() # 在此方法中生成current_shapedef initialize_shapes(self):self.current_shape = self.next_shape # 继承next_shapeself.current_color = self.next_color# 生成新next_shapeself.next_shape = random.choice(SHAPES)self.next_color = random.choice(COLORS)self.reset_position()def reset_position(self):shape_height = len(self.current_shape)self.current_pos = [GRID_WIDTH // 2 - len(self.current_shape[0]) // 2,-shape_height + 1 # 完全在游戏区域外生成]# 如果初始位置就碰撞,说明游戏结束if self.check_collision(self.current_shape, self.current_pos):self.game_over()def check_collision(self, shape, pos):for y in range(len(shape)):for x in range(len(shape[y])):if shape[y][x]:px = pos[0] + xpy = pos[1] + yif py >= GRID_HEIGHT:return Trueif px < 0 or px >= GRID_WIDTH:return Trueif py >= 0 and self.game_area[py][px] is not None:return Truereturn Falsedef rotate_shape(self):original_shape = self.current_shapeoriginal_pos = self.current_pos.copy()# 尝试旋转rotated = [list(row) for row in zip(*original_shape[::-1])]self.current_shape = rotated# 旋转后位置修正while self.check_collision(self.current_shape, self.current_pos):if self.current_pos[0] < 0:self.current_pos[0] += 1 # 右移else:self.current_pos[0] -= 1 # 左移if self.current_pos[0] < 0 or self.current_pos[0] >= GRID_WIDTH:self.current_shape = original_shape # 还原形状self.current_pos = original_posbreakdef merge_shape(self):for y, row in enumerate(self.current_shape):for x, cell in enumerate(row):if cell:px = self.current_pos[0] + x # 计算实际网格坐标py = self.current_pos[1] + y# 添加双重边界检查if 0 <= px < GRID_WIDTH and 0 <= py < GRID_HEIGHT:self.game_area[py][px] = self.current_colordef clear_lines(self):# 获取待消除行索引(从下往上检测)lines_to_clear = [i for i, row in enumerate(self.game_area) if all(cell is not None for cell in row)]if lines_to_clear:# 从下往上删除已满行(避免索引错位)for idx in reversed(lines_to_clear):del self.game_area[idx]# 在顶部补充新空行(数量=消除行数)new_rows = [[None] * GRID_WIDTH for _ in lines_to_clear]self.game_area = new_rows + self.game_area# 更新分数和速度self.score += len(lines_to_clear) * 100self.fall_speed = max(50, 500 - (self.score // 50) * 25) # 更平缓的速度变化def draw_grid(self):for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = self.game_area[y][x]# 添加颜色类型安全检查if isinstance(color, tuple) and len(color) == 3:pygame.draw.rect(screen, color,(x * GRID_SIZE, y * GRID_SIZE,GRID_SIZE - 1, GRID_SIZE - 1))def draw_current_shape(self):for y, row in enumerate(self.current_shape):for x, cell in enumerate(row):if cell:px = (self.current_pos[0] + x) * GRID_SIZEpy = (self.current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, self.current_color,(px, py, GRID_SIZE - 1, GRID_SIZE - 1))def draw_info_panel(self):font = load_font(24)pygame.draw.rect(screen, BLACK, (GAME_PANEL_WIDTH, 0, INFO_PANEL_WIDTH, WINDOW_HEIGHT))# 下一个方块title = font.render("下一个方块", True, WHITE)screen.blit(title, (GAME_PANEL_WIDTH + 10, 30))# 预览方块start_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - len(self.next_shape[0]) * GRID_SIZE) // 2start_y = 100for y, row in enumerate(self.next_shape):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, self.next_color,(start_x + x * GRID_SIZE, start_y + y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))# 分数显示score_text = font.render(f"分数: {self.score}", True, WHITE)screen.blit(score_text, (GAME_PANEL_WIDTH + 10, 300))highscore_text = font.render(f"最高分: {self.highscore}", True, WHITE)screen.blit(highscore_text, (GAME_PANEL_WIDTH + 10, 350))def handle_input(self):for event in pygame.event.get():if event.type == pygame.QUIT:self.running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:self.current_pos[0] -= 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[0] += 1elif event.key == pygame.K_RIGHT:self.current_pos[0] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[0] -= 1elif event.key == pygame.K_DOWN:self.current_pos[1] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] -= 1elif event.key == pygame.K_UP:self.rotate_shape()elif event.key == pygame.K_SPACE:while not self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] += 1self.current_pos[1] -= 1def game_over(self):if self.score > self.highscore:save_highscore(self.score)screen.fill(BLACK)font = load_font(48)text = font.render("游戏结束", True, (255, 0, 0))text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 30))screen.blit(text, text_rect)score_text = font.render(f"得分: {self.score}", True, WHITE)score_rect = score_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(score_text, score_rect)pygame.display.update()pygame.time.wait(3000)self.running = Falsedef run(self):clock = pygame.time.Clock()fall_time = pygame.time.get_ticks()while self.running:current_time = pygame.time.get_ticks()self.handle_input()# 自动下落if current_time - fall_time > self.fall_speed:self.current_pos[1] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] -= 1self.merge_shape()self.clear_lines()self.initialize_shapes() # 生成新方块# 游戏结束检测if self.check_collision(self.current_shape, self.current_pos):self.game_over()fall_time = current_time# 绘制界面screen.fill(DARK_GRAY)self.draw_grid()self.draw_current_shape()self.draw_info_panel()pygame.display.update()clock.tick(60)if __name__ == "__main__":game = GameState()game.run()pygame.quit()
总结
- 先使用DeepSeek生成可以执行的代码
- 使用Lingma优化代码
- 使用Lingma增加特色功能(建议不要一次性增加多个模块,可以一个个模块进行增加调试,对相对满意的模块可以先进行保存)
- 可以通过Ctrl+F调出搜索界面实现快速定位,可以询问Lingma解决警告和报错信息。
当然有Python基础的当然可以理解一下代码的逻辑然后进行修改,但是像我这种什么都不懂的同学就只能以AI为主,通过人工辅助询问一些问题来开发自己的小游戏,个人感觉非常消耗时间,最后如果有什么问题可以在评论区留言,欢迎各位大佬来批评指正!!!
相关文章:
使用DeepSeek定制Python小游戏——以“俄罗斯方块”为例
前言 本来想再发几个小游戏后在整理一下流程的,但是今天试了一下这个俄罗斯方块的游戏结果发现本来修改的好好的的,结果后面越改越乱,前面的版本也没保存,根据AI修改他是在几个版本改来改去,想着要求还是不能这么高。…...
Linux中安装mysql8,转载及注意事项
一、先前往官网下载mysql8 下载地址: https://dev.mysql.com/downloads/选择Linux 二、删除Linux中的mysql(如果有的话),上传安装包 1、先查看mysql是否存在,命令如下: rpm -qa|grep -i mysql如果使用这…...
网站即时备份,网站即时备份的方法有哪些
网站数据的安全性与业务连续性直接关系到企业的核心竞争力。无论是因硬件故障、人为误操作、网络攻击还是自然灾害,数据丢失或服务中断都可能带来难以估量的损失。因此,网站即时备份成为保障业务稳定性的关键技术手段。 一、核心即时备份技术方案 云服…...
LVM扩容小计
文章目录 [toc]当前磁盘使用问题分析关键问题定位推荐解决方案方案一:扩展根分区(LVM 动态扩容)方案二:清理磁盘空间(紧急临时处理) 当前磁盘使用问题分析 根据你的磁盘信息,根文件系统 (/) 已…...
【2025软考高级架构师】——案例分析总结(13)
摘要 本文对2025年软考高级架构师的考纲及案例分析进行了总结。内容涵盖系统规划、架构设计、系统建模、安全架构、可靠性分析、大数据架构等多方面知识点,还涉及软件质量特性、系统流程图与数据流图、嵌入式系统架构、分布式系统设计等考查内容,详细列…...
Redis ⑨-Jedis | Spring Redis
Jedis 通过 Jedis 可以连接 Redis 服务器。 通过 Maven 引入 Jedis 依赖。 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><versi…...
aidermacs开源程序使用 Aider 在 Emacs 中进行 AI 配对编程
一、软件介绍 文末提供程序和源码下载 Aidermacs 通过集成 Aider(最强大的开源 AI 配对编程工具之一)为 Emacs 带来了 AI 驱动的开发。如果您缺少 Cursor,但更喜欢生活在 Emacs 中,Aidermacs 提供了类似的 AI 功能,同…...
HarmonyOS NEXT——DevEco Studio的使用(还没写完)
一、IDE环境的搭建 Windows环境 运行环境要求 为保证DevEco Studio正常运行,建议电脑配置满足如下要求: 操作系统:Windows10 64位、Windows11 64位 内存:16GB及以上 硬盘:100GB及以上 分辨率:1280*8…...
使用PageHelper实现分页查询(详细)
一:需求分析与设计 1.1 产品原型 (1)分页展示,每页展示10条数据,根据员工姓名进行搜索 (2)业务规则 1.2 接口设计 (1)操作:查询,请求方式…...
神经网络基础-从零开始搭建一个神经网络
一、什么是神经网络 人工神经网络(Articial Neural Network,简写为ANN)也称为神经网络(NN),是一种模仿生物神经网络和功能的计算模型,人脑可以看做是一个生物神经网络,由众多的神经元连接而成,…...
数据库原理与应用实验二 题目七
利用sql建立教材数据库,并定义以下基本表: 学生(学号,年龄,性别,系名) 教材(编号,书名,出版社编号,价格) 订购(学号,书号,数量) 出版社(编号,名称,地址) 1定义主码、外码、和价格、数量的取值范围。 2 在三个表中输入若干记录,注意如果输入违反完整…...
如何在 CentOS 7 命令行连接 Wi-Fi?如何在 Linux 命令行连接 Wi-Fi?
如何在 CentOS 7 命令行连接 Wi-Fi?如何在 Linux 命令行连接 Wi-Fi? 摘要 本教程覆盖如何在多种 Linux 发行版下通过命令行连接 Wi-Fi,包括: CentOS 7、Ubuntu、Debian、Arch Linux、Fedora、Alpine Linux、Kali Linux、OpenSU…...
【学习笔记】 强化学习:实用方法论
作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程,深度学习领域研究生必读教材),开始深度学习领域学习,深入全面的理解深度学习的理论知识。 之前的文章参考下面的链接…...
ElasticSearch深入解析(十):字段膨胀(Mapping 爆炸)问题的解决思路
文章目录 一、核心原理:动态映射的双刃剑1. 动态映射的工作机制2. 映射爆炸的触发条件3. 底层性能损耗 二、典型场景与案例分析1. 日志系统:动态标签引发的灾难2. 物联网数据:设备属性的无序扩展 三、系统性解决方案1. 架构层优化2. 配置层控…...
react18基础速成
1、项目搭建 npx create-react-app my-react-app(项目名) cd 项目名进入项目目录 终端输入 npm start 启动项目 浏览器查看 项目搭建成功 2、JSX JavaScript语法和HTML语法写在一起就是JSX语法 jsx只能返回一个根元素,即最外层的div&a…...
18、状态库:中央魔法仓库——React 19 Zustand集成
一、量子熔炉的诞生 "Zustand是记忆水晶的量子纠缠体,让状态流无需魔杖驱动即可自洽!"霍格沃茨炼金术研究院的工程师挥动魔杖,Zustand 的原子化状态流在空中交织成星轨矩阵。 ——基于《魔法国会》第2025号协议,Zustan…...
PyCharm中全局搜索无效
发现是因为与搜狗快捷键冲突了,把框选的那个勾选去掉或设置为其他键就好了...
【Hive入门】Hive与Spark SQL深度集成:执行引擎性能全面对比与调优分析
目录 引言 1 Hive执行引擎架构演进 1.1 Hive执行引擎发展历程 1.2 执行引擎架构对比 1.2.1 MapReduce引擎架构 1.2.2 Tez引擎架构 1.2.3 Spark引擎架构 2 执行引擎切换与配置指南 2.1 引擎切换配置方法 2.1.1 全局配置 2.1.2 会话级配置 2.2 资源管理配置 2.2.1 T…...
【算法基础】快速排序算法 - JAVA
一、算法基础 1.1 什么是快速排序 快速排序(Quick Sort)是一种高效的分治排序算法,由英国计算机科学家Tony Hoare于1960年提出。它的核心思想是: 选择一个基准元素(pivot)将数组分成两部分:小…...
Ubuntu 24.04 通过 update-alternatives 切换GCC版本
在 Ubuntu 中编译项目, 会遇到项目依赖于某个特定版本 GCC 的情况, 例如 Ubuntu 24.04 的默认 GCC 版本是 13, 但是有一些项目需要 GCC11才能正常编译, 在 Ubuntu 24.04 默认的环境下编译会报错. 这时候可以通过 update-alternatives 切换GCC版本. all 展示全部 用--all参数会…...
Linux中的时间同步
一、时间同步服务扩展总结 1. 时间同步的重要性 多主机协作需求:在分布式系统、集群、微服务架构中,时间一致性是日志排序、事务顺序、数据一致性的基础。 安全协议依赖:TLS/SSL证书、Kerberos认证等依赖时间有效性,时间偏差可能…...
数据赋能(209)——质量管理——时效性原则
概述 数据时效性原则在数据收集、处理、分析和应用的过程中确保数据在特定时间范围内保持其有效性和相关性,为决策提供准确、及时的依据。在快速变化的市场环境中,数据时效性对于企业的竞争力和决策效率具有决定性的影响。 原则定义 数据时效性原则&a…...
AnimateCC教学:照片旋转飞舞并爆炸....
1.核心代码: <!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>旋转照片演示</title><script src="https://code.createjs.com/1.0.0/createjs.min.js"></script><script src="http…...
腾讯混元-DiT 文生图
1 混元-DiT所需的模型大小一共是41G https://huggingface.co/Tencent-Hunyuan/HunyuanDiT https://colab.research.google.com/ HunyuanDiT_jupyter.ipynb %cd /content !GIT_LFS_SKIP_SMUDGE1 git clone -b dev https://github.com/camenduru/HunyuanDiT %cd /content/Hun…...
优化高搜索量还是低竞争关键词?SEO策略解析
在2025年的SEO环境中,关键词研究仍然是优化网站排名的基石。然而,一个常见的问题困扰着SEO从业者:在使用谷歌关键词规划师(Google Keyword Planner)进行关键词研究时,是否应该优先选择月搜索量较高的关键词…...
对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础
文章目录 一、数字签名方案1.1 ECDSA:基于椭圆曲线的数字签名算法1.2 EdDSA:Edwards曲线数字签名算法1.3 RSA-PSS:带有概率签名方案的RSA1.4 数字签名方案对比 二、密钥交换协议2.1 Diffie-Hellman密钥交换2.2 ECDH:椭圆曲线Diffi…...
在MySQL中建索引时需要注意哪些事项?
在 MySQL 中建立索引是优化查询性能的重要手段,但不当的索引设计可能导致资源浪费、性能下降甚至拖慢写入速度。 所以我们我们首先要判断对于一个字段或者一些字段要不要建立索引。 适合建立索引的字段通常是: 主键字段:MySQL 会自动为主键…...
dstack 是 Kubernetes 和 Slurm 的开源替代方案,旨在简化 ML 团队跨顶级云、本地集群和加速器的 GPU 分配和 AI 工作负载编排
一、软件介绍 文末提供程序和源码下载 dstack 是 Kubernetes 和 Slurm 的开源替代方案,旨在简化顶级云和本地集群中 ML 团队的 GPU 分配和 AI 工作负载编排。 二、Accelerators 加速器 dstack 支持 NVIDIA 开箱即用的 、 AMD 、 Google TPU 和 Intel Gaudi 加速器…...
Linux 的 epoll 与 Windows 的 IOCP 详解
如果你在搞网络编程或者高性能服务器,一定要搞懂这两个模型——它们都是用来解决“多路复用”问题的工具,让你同时处理大量的网络连接变得高效又可控。 一、什么是“多路复用”? 简单说,就是你手里有很多任务(比如很多客户端的请求),但系统的核心(线程或者进程)资源…...
C# 方法(控制流和方法调用)
本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 控制流 方法包含了组成程序的…...
Webug4.0靶场通关笔记11- 第15关任意文件下载与第16关MySQL配置文件下载
目录 一、文件下载 二、第15关 任意文件下载 1.打开靶场 2.源码分析 3.渗透实战 三、第16关 MySQL配置文件下载 1.打开靶场 2.源码分析 3.渗透实战 (1)Windows系统 (2)Linux系统 四、渗透防御 一、文件下载 本文通过…...
More Effective C++学习笔记
条款1 指针与引用的区别 条款2 尽量使用C风格的类型转换 条款3 不要对数组使用多态 条款4 避免无用的缺省构造函数 条款5 谨慎定义类型转换函数 条款6 自增(increment)、自减(decrement)操作符前缀形式与后缀形式的区别 条款7 不要重载“&&”,“||”, 或“,” 条款8 理…...
如何设计抗Crosstalk能力强的PCB镀穿孔
一个高速PCB通道通常包含芯片SerDes IP、走线、穿层Via、连接器和Cable。 其中内层走线对于Crosstalk影响甚微(请参考什么? Stripline的FEXT为0! Why? ),而Via与连接器由于其参考路径较差的关系,…...
多线程系列三:这就是线程的状态?
1.认识线程的状态 NEW:Thread对象已经创建好了,但还没有调用start方法在系统中创建线程 RUNNABLE:就绪状态,表示这个线程正在CPU上执行,或准备就绪,随时可以去CPU上执行 BLOCKED:表示由于锁竞争…...
生成对抗网络(GAN, Generative Adversarial Network)
定义:一种通过对抗训练让两个神经网络(生成器与判别器)相互博弈的深度学习模型,用于生成逼真的数据(如图像、音频、文本等)。 一、核心思想:对抗博弈 GAN的核心是让两个神…...
用可视化学习逆置法
1.逆置法思路 目标:将这个彩色数组向右旋转3步 🔴1 → 🟠2 → 🟡3 → 🟢4 → 🔵5 → 🟣6 → ⚪7我们希望得到 🔵5 → 🟣6 → ⚪7 → 🔴1 → 🟠…...
家用服务器 Ubuntu 服务器配置与 Cloudflare Tunnel 部署指南
Ubuntu 服务器配置与 Cloudflare Tunnel 部署指南 本文档总结了我们讨论的所有内容,包括 Ubuntu 服务器配置、硬盘扩容、静态 IP 设置以及 Cloudflare Tunnel 的部署步骤。 目录 硬盘分区与扩容设置静态 IPCloudflare Tunnel 部署SSH 通过 Cloudflare Tunnel常见…...
【C++篇】类和对象(上)
目录 类的定义格式: 内敛函数: 类与struct的区别: 类的访问权限: 类域: 类的实例化: 对象大小: 计算对象的大小时,也存在内存对齐(与结构体一样)&…...
ES6/ES11知识点 续一
模板字符串 在 ECMAScript(ES)中,模板字符串(Template Literals)是一种非常强大的字符串表示方式,它为我们提供了比传统字符串更灵活的功能,尤其是在处理动态内容时。模板字符串通过反引号&…...
ES6入门---第二单元 模块二:关于数组新增
一、扩展运算符。。。 1、可以把ul li转变为数组 <script>window.onloadfunction (){let aLi document.querySelectorAll(ul li);let arrLi [...aLi];arrLi.pop();arrLi.push(asfasdf);console.log(arrLi);};</script> </head> <body><ul><…...
使用python加edge-tts实现文字转语音
文章目录 使用python加edge-tts实现文字转语音1. 使用 Python 安装 Edge-TTS2. 进一步优化3. 使用说明3.1 查看语音列表3.2 单语音转换3.3 批量生成所有语音3.4 改进亮点4. 使用教程最终代码文章创作不易使用python加edge-tts实现文字转语音 Edge-TTS(edge-tts Python 模块)本…...
如何用CSS实现HTML元素的旋转效果:从基础到高阶应用
在网页设计中,元素的动态效果能显著提升用户体验,而旋转效果是其中最常用的交互方式之一。CSS的transform属性提供了强大的旋转功能,结合动画(animation)和过渡(transition),开发者可…...
轻量级RTSP服务模块:跨平台低延迟嵌入即用的流媒体引擎
在音视频流媒体系统中,RTSP(Real-Time Streaming Protocol)服务模块通常扮演着“视频分发中心”的角色,它将编码后的音视频内容转为标准的流媒体格式,供客户端(播放器、云端平台、AI模块等)拉流…...
AVInputFormat 再分析
AVInputFormat 是 FFmpeg 中用于描述输入格式(如文件容器、设备流等)的核心结构体,属于 libavformat 库的一部分。其主要功能是定义解封装(demuxing)过程中如何解析不同格式的输入数据。以下是其关键特性与使用方式的总…...
wpf CommandParameter 传递MouseWheelEventArgs参数
在 WPF 中通过 CommandParameter 传递 MouseWheelEventArgs 参数时,需结合 事件到命令的转换机制 和 参数转换器 来实现。以下是具体实现方案及注意事项: 一、核心实现方法 1. 使用 EventToCommand 传递原始事件参数 通过 Interaction.Tr…...
摆脱养生误区泥沼,拥抱科学养生阳光
在养生的道路上,人们总是满怀热忱地追寻健康之道,然而,诸多似是而非的养生误区却如同泥沼一般,让不少人深陷其中,难以自拔。只有奋力摆脱这些误区的束缚,才能拥抱科学养生的温暖阳光,真正实现身…...
FreeRtos实战从入门到精通--任务创建和删除(动态方法)--事了拂衣去,深藏功与名
FreeRtos是之前的一些聪明的工程师写的免费且开源的嵌入式实时操作系统代码,由于我们实际工作中不需要再去写rtos,我们只需要用就行了,所以博主这里只分享项目工程实战相关的内容,具体rtos源码,可以无需理会࿰…...
卷积神经网络进化史:从LeNet-5到现代架构的完整发展脉络
摘要 本文系统梳理卷积神经网络(CNN)从诞生到繁荣的发展历程。从1998年Yann LeCun开创性的LeNet-5出发,重点解析2012年引爆深度学习革命的AlexNet,并详细拆解后续演进的五大技术方向:网络深度化(VGG)、卷积功能强化(ResNet)、检测任务迁移(F…...
《Qt C++ 项目中升级 GCC 版本的完整指南》
Qt C++ 项目中升级 GCC 版本的完整指南 在 Qt C++ 项目中升级 GCC 版本可能会影响编译工具链、Qt 库兼容性以及项目配置。以下是针对不同操作系统的升级步骤和注意事项: 一、为什么需要升级 GCC 版本? C++ 标准支持:新版本 GCC 支持 C++17/20 等新标准特性性能优化:编译速…...
Baklib赋能企业知识管理数字化转型
Baklib驱动知识智慧转化 在数字化浪潮中,企业知识资产的碎片化与低效流转已成为制约业务创新的核心瓶颈。Baklib作为新一代知识中台,通过构建智能化的知识治理体系,将分散的文档、数据与经验转化为可复用的业务智慧。其核心能力体现在多模态…...