news 2026/7/26 19:41:00

Python Pygame 2D跑酷游戏开发:从零实现游戏循环与精灵系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python Pygame 2D跑酷游戏开发:从零实现游戏循环与精灵系统

1. 项目概述:为什么选择Python开发跑酷游戏?

如果你对游戏开发感兴趣,但又觉得Unity、Unreal这些引擎门槛太高,或者想从更底层的逻辑理解游戏是怎么跑起来的,那么用Python来做一个跑酷游戏,绝对是一个绝佳的入门选择。我刚开始接触游戏编程时,就是从Python的Pygame库入手的,它让我绕开了复杂的图形学数学和引擎架构,直接聚焦在游戏最核心的循环、事件和精灵逻辑上。今天,我就带你从零开始,用Python一步步搭建一个属于你自己的、可以无限奔跑的2D跑酷游戏。

这个项目听起来简单,但它麻雀虽小五脏俱全。你将亲手实现一个完整的游戏循环,处理玩家输入(比如跳跃、下蹲),管理游戏对象(比如角色、障碍物、背景),处理碰撞检测,并实现计分和难度递增。完成之后,你收获的不仅仅是一个能跑的小程序,更是一套理解任何2D游戏开发的基础思维框架。无论你未来是想做更复杂的独立游戏,还是仅仅想培养编程的乐趣和逻辑能力,这个项目都是一个扎实的起点。

2. 核心工具链与开发环境搭建

工欲善其事,必先利其器。在动手写代码之前,我们需要一个稳定、高效的开发环境。对于Python游戏开发,工具链的选择直接影响到你的开发体验和效率。

2.1 Python解释器与包管理器的选择

首先,你需要安装Python。我强烈推荐使用Python 3.8或更高版本,因为它们在性能和库的兼容性上都有很好的表现。直接从Python官网下载安装包是最直接的方式。安装时,请务必勾选“Add Python to PATH”这个选项,这能让你在命令行中直接使用pythonpip命令,省去后续配置环境变量的麻烦。

安装好Python后,pip包管理器会自动可用。但为了更优雅地管理项目依赖,避免不同项目间的库版本冲突,我建议使用虚拟环境。你可以使用Python自带的venv模块:

# 在你的项目目录下,比如 D:\MyGame python -m venv venv

这行命令会在当前目录创建一个名为venv的文件夹,里面包含了一个独立的Python环境。激活它:

  • Windows (CMD/PowerShell):venv\Scripts\activate
  • macOS/Linux:source venv/bin/activate

激活后,你的命令行提示符前会出现(venv)字样,表示你正工作在这个独立环境中。之后所有通过pip install安装的库,都只会影响这个环境。

2.2 代码编辑器与集成开发环境(IDE)

对于编辑器,你有两个主流选择:轻量级的VS Code或者功能更全面的PyCharm。

VS Code以其轻快和强大的扩展生态著称。你需要安装“Python”和“Pylance”这两个扩展。它们能提供智能代码补全、语法高亮、调试等功能。对于初学者,VS Code的界面更简洁,学习曲线平缓。

PyCharm是JetBrains出品的专业Python IDE,分社区版(免费)和专业版。社区版的功能对于我们的游戏开发已经绰绰有余。它的优势在于开箱即用,对项目结构、虚拟环境、版本控制(Git)的集成做得非常好,调试器也非常强大。如果你打算长期进行Python开发,PyCharm能帮你省去很多配置时间。

我个人在开发这个跑酷游戏时使用的是PyCharm社区版,因为它能自动识别我的venv虚拟环境,并且其“运行/调试”配置非常直观。

2.3 核心游戏开发库:Pygame

我们的游戏将建立在Pygame库之上。它是一个基于SDL(Simple DirectMedia Layer)的Python模块,专门用于编写电子游戏和多媒体应用。它提供了对图像、声音、事件、甚至2D图形加速的简单访问。

在你的虚拟环境激活状态下,使用pip安装它:

pip install pygame

安装完成后,可以在Python交互环境中输入import pygame来验证是否成功。通常,Pygame还会附带一些示例和工具,安装过程非常顺畅。

注意:如果你在安装过程中遇到与Microsoft C++ Build Tools相关的错误,这在Windows上很常见。你需要安装Visual Studio Build Tools或单独安装Microsoft Visual C++ Redistributable。一个更简单的方法是访问一个知名的软件下载网站,搜索并安装“Microsoft Visual C++ Redistributable for Visual Studio 2015-2022”,通常能解决大部分依赖问题。

3. 游戏框架设计与核心模块拆解

在开始敲代码之前,我们先在脑子里把游戏的骨架搭起来。一个典型的2D跑酷游戏可以分解为几个核心模块,理解它们之间的关系是成功的关键。

3.1 游戏主循环:一切的核心

游戏的心脏是“游戏循环”(Game Loop)。它是一个无限循环,在每一帧(Frame)中按顺序做以下几件事:

  1. 处理事件:检查有没有键盘按下、鼠标点击、退出请求等。
  2. 更新游戏状态:根据输入和游戏逻辑,更新所有游戏对象的位置、状态(比如角色是否跳跃、障碍物是否移出屏幕)。
  3. 渲染(绘制):将更新后的所有游戏对象绘制到屏幕上。

这个循环以极高的频率运行(比如每秒60次,即60 FPS),从而在人眼中形成连贯的动画。在Pygame中,我们通过pygame.time.Clock()对象来控制循环的速度,确保游戏在不同性能的电脑上都能以基本一致的速度运行。

3.2 游戏对象(精灵)的抽象

游戏中的所有可见、可交互的元素,我们都可以抽象为“精灵”(Sprite)。在我们的跑酷游戏里,至少需要三类精灵:

  • 玩家角色:一个可以跳跃、下蹲的小人。
  • 障碍物:从屏幕右侧向左移动的柱子、坑洞或敌人,角色需要避开它们。
  • 背景与地面:营造移动感的滚动背景,以及作为参照物的静止地面线。

Pygame提供了pygame.sprite.Sprite基类。通过继承这个类,我们可以方便地管理每个精灵的图像(Surface)、位置(Rect)以及更新和绘制逻辑。更重要的是,Pygame的精灵组(pygame.sprite.Group)可以批量管理和绘制大量精灵,并提供了高效的碰撞检测方法,这为我们处理角色与障碍物的碰撞提供了极大便利。

3.3 游戏状态与资源管理

游戏还需要管理一些全局状态和资源:

  • 分数:随着时间或越过障碍物而增加。
  • 游戏速度:随着分数增加,背景滚动和障碍物移动的速度会逐渐加快,提升难度。
  • 游戏状态:是正在运行,还是已结束(Game Over)?
  • 资源加载:图片、声音字体等文件需要在游戏初始化时加载好,避免在游戏循环中反复读取磁盘影响性能。

一个清晰的架构是,我们将这些状态和资源管理封装在一个主游戏类(比如Game类)中,而游戏循环则作为这个类的一个方法。这样代码结构会更清晰,也便于后续扩展功能。

4. 从零开始:一步步实现跑酷游戏

理论说得再多,不如动手写一行代码。让我们打开编辑器,开始构建我们的游戏世界。

4.1 项目初始化与窗口创建

首先,创建一个新的Python文件,比如runner.py。然后,进行Pygame的初始化和创建游戏窗口。

import pygame import sys import random # 初始化pygame pygame.init() # 游戏窗口的尺寸 SCREEN_WIDTH = 800 SCREEN_HEIGHT = 400 # 定义一些颜色,方便后续使用 WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 50, 50) GREEN = (50, 205, 50) SKY_BLUE = (135, 206, 235) # 创建游戏窗口 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Python Runner - 我的第一个跑酷游戏") # 创建控制帧率的时钟对象 clock = pygame.time.Clock() FPS = 60 # 目标帧率,每秒60帧 # 游戏主循环的开关 running = True

这段代码做了几件事:导入必要的模块,定义了窗口大小和颜色常量,创建了显示窗口并设置了标题,最后创建了用于控制游戏速度的时钟对象。running变量将作为游戏主循环的条件。

4.2 创建玩家角色精灵

接下来,我们创建玩家角色。我们将定义一个Player类,继承自pygame.sprite.Sprite

class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() # 1. 创建角色的图像表面(Surface) # 为了简单,我们先用一个矩形代替,后续可以替换为图片 self.image = pygame.Surface((50, 80)) self.image.fill(GREEN) # 给矩形填充绿色 # 也可以画一个更复杂的形状,比如一个简单的“火柴人” # pygame.draw.rect(self.image, GREEN, (0,0,50,80)) # pygame.draw.circle(self.image, BLACK, (25, 20), 15) # 头 # 2. 获取图像的矩形区域,用于定位和碰撞检测 self.rect = self.image.get_rect() # 设置角色的初始位置:靠近屏幕左侧,站在“地面”上 self.rect.midbottom = (100, SCREEN_HEIGHT - 50) # 3. 角色的物理属性 self.velocity_y = 0 # Y轴速度(用于跳跃) self.gravity = 1 # 重力加速度 self.jump_power = -20 # 跳跃的初始速度(向上为负) self.on_ground = True # 是否在地面上 def update(self, keys): """每帧更新角色的状态""" # 处理跳跃 if keys[pygame.K_SPACE] or keys[pygame.K_UP]: if self.on_ground: # 只有在地面上才能起跳 self.velocity_y = self.jump_power self.on_ground = False # 应用重力 self.velocity_y += self.gravity self.rect.y += self.velocity_y # 地面碰撞检测(防止角色掉出屏幕底部) ground_level = SCREEN_HEIGHT - 50 if self.rect.bottom >= ground_level: self.rect.bottom = ground_level self.velocity_y = 0 self.on_ground = True def draw(self, surface): """将角色绘制到指定的表面上(这里就是我们的主屏幕)""" surface.blit(self.image, self.rect)

在这个类中,我们定义了角色的外观(一个绿色矩形)、位置和关键的物理属性。update方法根据按键(空格或上箭头)触发跳跃,并模拟重力和落地。draw方法负责将角色画到屏幕上。

4.3 创建障碍物精灵与生成逻辑

障碍物是游戏挑战的来源。我们同样创建一个Obstacle类。

class Obstacle(pygame.sprite.Sprite): def __init__(self, x, y, width, height, speed): super().__init__() self.image = pygame.Surface((width, height)) self.image.fill(RED) self.rect = self.image.get_rect(topleft=(x, y)) self.speed = speed # 障碍物向左移动的速度 def update(self): """每帧更新障碍物的位置""" self.rect.x -= self.speed # 如果障碍物完全移出屏幕左侧,则将其从精灵组中移除,以节省资源 if self.rect.right < 0: self.kill() # 从所有所属的精灵组中删除自己

障碍物会以固定的速度从右向左移动。我们需要一个机制来定时生成它们。我们可以在主游戏循环中,使用一个计时器或者基于游戏帧数来间隔生成。

# 在主循环外部初始化 obstacle_group = pygame.sprite.Group() # 用于管理所有障碍物的精灵组 obstacle_timer = 0 # 用于计时的变量 OBSTACLE_FREQUENCY = 90 # 每90帧尝试生成一个障碍物(约1.5秒@60FPS) # 在主循环内部,更新部分 obstacle_timer += 1 if obstacle_timer >= OBSTACLE_FREQUENCY: # 随机生成障碍物的高度和类型(例如高柱子或矮柱子) height = random.randint(30, 80) # 障碍物从屏幕右侧外生成 new_obstacle = Obstacle(SCREEN_WIDTH, SCREEN_HEIGHT - 50 - height, 30, height, 5) obstacle_group.add(new_obstacle) obstacle_timer = 0 # 重置计时器

4.4 整合:完善游戏主循环

现在,我们把所有部分整合到主循环中。

# 初始化玩家和障碍物组 player = Player() all_sprites = pygame.sprite.Group() # 一个管理所有精灵的组,方便统一更新和绘制 all_sprites.add(player) obstacle_group = pygame.sprite.Group() # 游戏状态变量 score = 0 game_over = False font = pygame.font.SysFont(None, 36) # 创建一个字体对象,用于显示分数 while running: # 1. 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 按R键在游戏结束后重新开始 if event.type == pygame.KEYDOWN: if event.key == pygame.K_r and game_over: # 重置游戏状态 player.rect.midbottom = (100, SCREEN_HEIGHT - 50) player.velocity_y = 0 player.on_ground = True obstacle_group.empty() all_sprites.empty() all_sprites.add(player) score = 0 game_over = False if not game_over: # 2. 更新游戏状态 # 获取当前所有按键状态 keys = pygame.key.get_pressed() player.update(keys) obstacle_group.update() # 障碍物生成逻辑(接上面的代码片段) obstacle_timer += 1 if obstacle_timer >= OBSTACLE_FREQUENCY: height = random.randint(30, 80) new_obstacle = Obstacle(SCREEN_WIDTH, SCREEN_HEIGHT - 50 - height, 30, height, 5) obstacle_group.add(new_obstacle) all_sprites.add(new_obstacle) # 也加入到总精灵组用于绘制 obstacle_timer = 0 # 3. 碰撞检测 if pygame.sprite.spritecollide(player, obstacle_group, False): game_over = True # 发生碰撞,游戏结束 # 4. 更新分数(例如,每帧加1分,或越过障碍物加分) score += 1 # 5. 渲染(绘制) # 清屏,填充背景色 screen.fill(SKY_BLUE) # 绘制地面 pygame.draw.rect(screen, (139, 69, 19), (0, SCREEN_HEIGHT - 50, SCREEN_WIDTH, 50)) # 绘制所有精灵 for sprite in all_sprites: screen.blit(sprite.image, sprite.rect) # 绘制分数 score_text = font.render(f'Score: {score}', True, BLACK) screen.blit(score_text, (10, 10)) # 如果游戏结束,显示Game Over文字 if game_over: go_text = font.render('GAME OVER! Press R to Restart', True, RED) screen.blit(go_text, (SCREEN_WIDTH // 2 - go_text.get_width() // 2, SCREEN_HEIGHT // 2)) # 6. 刷新屏幕显示 pygame.display.flip() # 7. 控制帧率 clock.tick(FPS) # 退出游戏 pygame.quit() sys.exit()

至此,一个最基础的、可运行的跑酷游戏就完成了!你运行代码后,会看到一个绿色方块(玩家)站在棕色地面上,红色的障碍物会不断从右侧生成并向左移动。按空格键或上箭头键跳跃躲避。碰到障碍物游戏结束,按R键重新开始。分数会随着时间增加。

5. 进阶优化与功能扩展

基础版本跑起来了,但看起来还很简陋。下面我们来给它“化妆”,并增加一些让游戏更好玩的机制。

5.1 使用图片和音效替换几何图形

用矩形和圆形做角色太抽象了。我们可以准备两张图片:一张是站立/奔跑的角色,另一张是跳跃的角色。同样,障碍物也可以换成仙人掌、石头等图片。

  1. 加载图片:将图片文件(如player.png,cactus.png)放在项目目录下。

    # 在Player类的__init__中替换self.image的创建 try: self.image = pygame.image.load('player.png').convert_alpha() # convert_alpha保留透明通道 # 可能需要缩放图片到合适大小 self.image = pygame.transform.scale(self.image, (50, 80)) except FileNotFoundError: # 如果图片加载失败,回退到矩形 self.image = pygame.Surface((50, 80)) self.image.fill(GREEN)

    Obstacle类做类似处理。使用图片后,游戏的视觉吸引力会大大提升。

  2. 添加音效:跳跃声、碰撞声、背景音乐能极大增强游戏体验。

    # 在初始化部分加载音效 jump_sound = pygame.mixer.Sound('jump.wav') crash_sound = pygame.mixer.Sound('crash.wav') # 在玩家跳跃时播放 if keys[pygame.K_SPACE] and self.on_ground: self.velocity_y = self.jump_power self.on_ground = False jump_sound.play() # 播放跳跃音效

    注意:Pygame对音频格式支持较好的是.wav.ogg.mp3支持可能有问题。背景音乐可以使用pygame.mixer.music.load('bgm.mp3')pygame.mixer.music.play(-1)循环播放。

5.2 实现视差滚动背景

让背景移动起来,能营造出强烈的速度感。视差滚动是指不同层次的背景以不同的速度移动,产生立体感。

  1. 准备背景图层:至少需要两层,比如远处的山(慢速移动)和近处的云(快速移动)。每层是一张可以水平无缝衔接的宽图。
  2. 实现滚动逻辑:每帧将背景图向左移动一定距离。当图的一部分移出屏幕左侧时,立即将其绘制在右侧接上,形成循环。
    class Background: def __init__(self, image_file, speed): self.image = pygame.image.load(image_file).convert() self.width = self.image.get_width() self.height = SCREEN_HEIGHT self.image = pygame.transform.scale(self.image, (self.width, self.height)) self.x1 = 0 # 第一张图的位置 self.x2 = self.width # 第二张图的位置(紧接在第一张右侧) self.speed = speed def update(self): self.x1 -= self.speed self.x2 -= self.speed # 如果任何一张图完全移出屏幕,就把它重置到右侧 if self.x1 <= -self.width: self.x1 = self.x2 + self.width if self.x2 <= -self.width: self.x2 = self.x1 + self.width def draw(self, screen): screen.blit(self.image, (self.x1, 0)) screen.blit(self.image, (self.x2, 0)) # 创建两个背景层 bg_far = Background('far_bg.png', speed=1) # 远处的山,移动慢 bg_near = Background('near_bg.png', speed=3) # 近处的云,移动快
    在主循环的更新和绘制阶段分别调用bg_near.update(),bg_far.update()和它们的draw方法。注意绘制顺序:先画远的,再画近的,最后画精灵。

5.3 增加游戏难度与多样性

  1. 动态速度:随着分数增加,逐步提高障碍物的移动速度(Obstacle.speed)和生成频率(OBSTACLE_FREQUENCY减小)。可以在主循环中根据score来调整这些值。
  2. 多样化的障碍物:创建不同的障碍物类,比如Bird(飞行障碍,需要下蹲躲避)、Pit(坑洞,需要跳跃跨越)。随机生成不同类型,增加游戏策略性。
  3. 角色动画:为玩家角色准备一个奔跑的动画帧序列(多张图片)。在Player.update中,根据角色是否在地面上,切换不同的图像或播放动画帧,让角色“动”起来。
  4. 粒子效果:在角色跳跃落地或碰撞时,生成一些简单的粒子(如小圆点)并向四周溅射,增加视觉反馈。这可以通过一个Particle精灵类和一个粒子组来实现。

6. 调试、打包与发布

游戏做得差不多了,最后一步是让它更健壮,并能分享给别人。

6.1 常见问题与调试技巧

  • 画面撕裂或卡顿:确保在主循环末尾调用了clock.tick(FPS)来稳定帧率。如果仍然卡顿,可能是每帧绘制的内容太多或更新逻辑太复杂。可以使用pygame.time.get_ticks()来打印每帧耗时,定位性能瓶颈。
  • 碰撞检测不精确:我们使用的是矩形碰撞(spritecollide),对于不规则形状的图片,矩形框可能太大。可以尝试:
    1. 使用更小的矩形(self.rect.inflate(-10, -10)缩小一圈)。
    2. 使用圆形碰撞(计算两个精灵中心点的距离)。
    3. 使用像素级精确碰撞(pygame.sprite.collide_mask),但性能开销较大,适合精灵数量少的场景。
  • 音效播放延迟或爆音:确保音效文件不要太长,格式正确。对于短促音效,使用Sound对象;对于背景音乐,使用mixer.music。如果同时播放多个短音效有爆音,可以尝试减少同时播放的音效数量或使用混音器设置。

6.2 将游戏打包成可执行文件

你不想让朋友为了玩你的游戏还得安装Python和一堆库吧?使用PyInstaller可以轻松地将Python脚本打包成独立的.exe(Windows)或.app(macOS)文件。

  1. 安装PyInstaller:在项目虚拟环境中,pip install pyinstaller
  2. 基本打包:在项目根目录打开命令行,运行:
    pyinstaller --onefile --windowed runner.py
    • --onefile:将所有依赖打包成一个单独的exe文件。
    • --windowed:运行时不显示控制台窗口(对于游戏是必须的)。
    • runner.py:你的主程序入口文件。
  3. 处理资源文件:打包后,exe文件找不到你项目里的图片、声音了。你需要告诉PyInstaller这些资源在哪。创建一个.spec文件是更专业的方法,但一个快速的方案是:将图片、声音文件夹复制到和生成的exe文件同一目录下,然后在代码中修改资源加载路径,使用相对于当前执行文件的路径(可以通过sys._MEIPASS在打包后获取临时资源路径,但更简单的方法是假设资源在exe同级目录)。
    import os # 获取当前脚本所在目录 if getattr(sys, 'frozen', False): base_path = sys._MEIPASS # PyInstaller创建的临时文件夹 else: base_path = os.path.dirname(__file__) image_path = os.path.join(base_path, 'images', 'player.png')
    更常见的做法是,在打包命令中通过--add-data选项指定资源。
    pyinstaller --onefile --windowed --add-data "images;images" --add-data "sounds;sounds" runner.py
    (在Windows上用分号;分隔,在macOS/Linux上用冒号:分隔,格式为源路径;目标路径

打包过程可能会遇到各种依赖问题,特别是与Pygame相关的二进制库。多查阅PyInstaller文档和社区解决方案,通常都能找到答案。

6.3 性能优化小贴士

  • 图像转换:加载图片后,立即调用.convert().convert_alpha()。这会将图片转换为与当前显示模式相同的格式,大幅提升后续blit(绘制)的速度。
  • 避免在循环中创建新对象:比如不要在每帧的游戏主循环里都pygame.font.Font()创建字体对象,应该在初始化时创建好并复用。
  • 使用精灵组pygame.sprite.Groupdraw()update()方法经过优化,比手动遍历列表效率更高。对于大量静态背景元素,可以考虑绘制到一个固定的Surface上,然后每帧只blit这个Surface,而不是重绘每个元素。

走到这一步,你已经拥有了一个功能完整、视觉效果和可玩性都相当不错的Python跑酷游戏。更重要的是,你掌握了2D游戏开发的核心循环、精灵系统、碰撞检测和状态管理。这套思维模式,是通往更宏大游戏项目世界的钥匙。试着给你的游戏增加更多创意,比如不同的角色皮肤、道具系统、关卡设计,或者尝试用同样的框架做一个飞行射击游戏。编程的乐趣,就在于将想法一步步变为现实。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/26 19:39:13

《源纹天书》第二百二十一章至第二百二十五章:负载告警的响起、单集群的极限、数据分片策略、一致性哈希的设计、多集群部署的完成!

&#x1f4cc; 作者介绍哈喽&#xff0c;各位道友&#xff0c;我是 CodeStats。一个在底层技术上"考古"了四年的硬核爱好者&#xff0c;也是 WWAIC&#xff08;全周项目AI编程&#xff09;范式的提出者和实践者。我曾手写过一个完整的Java Web框架&#xff08;从IoC容…

作者头像 李华
网站建设 2026/7/26 19:38:57

终极指南:3步解锁WeMod完整功能,免费享受专业版体验

终极指南&#xff1a;3步解锁WeMod完整功能&#xff0c;免费享受专业版体验 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer 还在为WeMod的专业版功…

作者头像 李华
网站建设 2026/7/26 19:38:28

SpringBoot实战:构建优雅的全局异常处理机制

在现代Java Web开发中&#xff0c;异常处理是保证系统健壮性和提升用户体验的关键环节。本文将带你从痛点出发&#xff0c;手把手构建一套优雅、统一的全局异常处理方案。 一、 为什么需要全局异常处理&#xff1f; 在传统的开发模式中&#xff0c;我们经常在Controller层充斥…

作者头像 李华
网站建设 2026/7/26 19:33:04

告别安卓模拟器!Windows上直接安装APK文件的终极解决方案

告别安卓模拟器&#xff01;Windows上直接安装APK文件的终极解决方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想过&#xff0c;能不能像安装普通Wind…

作者头像 李华
网站建设 2026/7/26 19:30:17

R • exercises

catalogue题目1&#xff1a;变量赋值和基本运算题目2&#xff1a;向量创建和元素访问题目3&#xff1a;使用内置函数计算统计量题目4&#xff1a;混合运算与优先级理解题目5&#xff1a;模运算与整数除法题目6&#xff1a;类型转换与比较运算题目7&#xff1a;因子&#xff08;…

作者头像 李华
网站建设 2026/7/26 19:29:11

PowerToys汉化终极指南:解锁Windows效率工具的完整中文体验

PowerToys汉化终极指南&#xff1a;解锁Windows效率工具的完整中文体验 【免费下载链接】PowerToys-CN PowerToys Simplified Chinese Translation 微软增强工具箱 自制汉化 项目地址: https://gitcode.com/gh_mirrors/po/PowerToys-CN 还在为PowerToys的英文界面发愁吗…

作者头像 李华