当前位置: 首页 > news >正文

PyGame游戏开发(入门知识+组件拆分+历史存档/回放+人机策略)

前言:

     本章实现游戏组件的复用解耦,以及使用配置文件替代原有硬编码形式,进而只需要改动配置文件即可实现整个游戏的难度和地图变化,同时增加历史记录功能,在配置文件开启后即可保存每一局的记录为json形式作为后续强化学习的数据源,同时也可通过json复现渲染之前保存的游戏记录,并编写函数作为初期人机对抗策略。(之前写的pygame文档上了热榜,在此感谢各位的支持,也特此加更代码,更新本章,改成了更适合面向对象/java开发体质的代码,甚至导师那边的事情都放了放 bushi)PyGame游戏开发(含源码+演示视频+开结题报告+设计文档)-CSDN博客https://blog.csdn.net/wlf2030/article/details/147878665?spm=1001.2014.3001.5502源码链接如下(持续更新,欢迎star):

wlf728050719/BallGamehttps://github.com/wlf728050719/BallGame


入门知识:

        其实pygame作为早期的二维游戏开发库,上手比较简单,只需要掌握以下几点即可。

1.渲染和物理分离,

可以将一张图片看作游戏中的一个object,其surface对象负责渲染,其rect负责物理逻辑的判断。

获取两个对象一般使用下面的方式:

load加载路径图片获取surface,并用surface.get_rect获取rect对象,获取的rect大小默认和surface大小相同,且由于传入图片为矩形,所以rect对象也为矩形。

2.位置绑定

尽管surface对象和rect负责职责不同,但可以理解surface对象作为一个贴图始终跟随rect对象移动,所以只需要关注rect的位置即可。同时注意x,y轴增加的方向如下。

3.循环监听

游戏的渲染和逻辑一定是放在一个死循环中,非阻塞监听键盘事件并执行对应逻辑。

4.渲染覆盖

后渲染的图片会覆盖在先渲染的图片上,同时由于pygame不会自动清空已经渲染的画面,所以每一帧开始或结束需要重新使用背景图覆盖原有画面。


快速开始:

下载解压源码文件后,目录如下,其中history为创建的存储游玩记录的目录,origin为之前的代码,功能健全,(启动后,使用l,m,h三个按键选择难度,1,2,3选择地图,按enter进入游戏,双方使用ws和上下控制,空格暂停,esc退出。)但由于没有拆分组件几乎不能二次开发。

remake1目录下为改进后代码,入口pve,pvp,replay分别对应三种模式,pve,pvp只需要修改对应的json配置文件即可创建完全不同的游戏进程,同时replay也可加载不同的历史记录。

配置文件如下:(可选择组件图片,游戏模式,组件速度,分数上限,是否保存,保存路径,人机策略等)

{"background_image": "../resources/img/page/game.png","ball_images":["../resources/img/component/ball/ball_0.png","../resources/img/component/ball/ball_1.png","../resources/img/component/ball/ball_2.png","../resources/img/component/ball/ball_3.png","../resources/img/component/ball/ball_4.png"],"paddle_image": "../resources/img/component/paddle/paddle.png","fps": 30,"mode": "PVE","strategy_right": 5,"max_scores": 1,"ball_speed": 5,"paddle_speed": 5,"render": true,"save": true,"save_dir": "../history/pve"
}

组件:

将渲染和物理逻辑进行拆分方便后续不渲染画面快速获取游戏记录。并添加导出和加载状态的接口,从而实现记录保存和回放。

Ball:

import pygame.imageclass Ball:def __init__(self, images, x, y, speedx, speedy):self.origin_x = xself.origin_y = yself.origin_speedx = speedxself.origin_speedy = speedyself.surfaces = []for img_path in images:try:surface = pygame.image.load(img_path)self.surfaces.append(surface)except pygame.error as e:print(f"无法加载图片 {img_path}: {e}")self.rect = self.surfaces[0].get_rect()self.rect.x = xself.rect.y = yself.speedx = speedxself.speedy = speedydef move(self):self.rect.x += self.speedxself.rect.y += self.speedydef render(self, frame, screen):screen.blit(self.surfaces[(frame % len(self.surfaces))], self.rect)def is_hit(self, other_rect):return self.rect.colliderect(other_rect)def set_position(self, x, y):self.rect.x = xself.rect.y = ydef set_speed(self, speedx, speedy):self.speedx = speedxself.speedy = speedydef reset(self):self.set_position(self.origin_x, self.origin_y)self.set_speed(self.origin_speedx, self.origin_speedy)def get_state(self):return {'x': self.rect.x,'y': self.rect.y,'speedx': self.speedx,'speedy': self.speedy}def load_state(self, state):self.rect.x = state["x"]self.rect.y = state["y"]self.speedx = state["speedx"]self.speedy = state["speedy"]

Paddle:

import pygamefrom remake1.constant.enums import Directionclass Paddle:def __init__(self, image, x, y, speed,height):self.surface = pygame.image.load(image)self.rect = self.surface.get_rect()self.rect.x = xself.rect.y = yself.speed = speedself.height = heightdef move(self, direction):if direction == Direction.UP:self.rect.y -= self.speedelif direction == Direction.DOWN:self.rect.y += self.speedif self.rect.top < 0:self.rect.top = 0if self.rect.bottom > self.height:self.rect.bottom = self.heightdef render(self, screen):screen.blit(self.surface, self.rect)def set_position(self, y):self.rect.y = ydef set_speed(self, speed):self.speed = speeddef get_state(self):return {'x': self.rect.x,'y': self.rect.y,'speed': self.speed}def load_state(self, state):self.rect.x = state["x"]self.rect.y = state["y"]self.speed = state["speed"]

输入工具类:

规范允许输入按键,对长按和短按键进行区分。

class InputUtil:def __init__(self, allowed_keys):self.allowed_keys = set(allowed_keys)   #支持的输入按键self.pressed_keys = set()   #所有按下self.released_keys = set()  #所有释放self.just_pressed = set()   #最新按下self.just_released = set()  #最新释放def press(self, key):if key in self.allowed_keys:if key not in self.pressed_keys:self.pressed_keys.add(key)self.just_pressed.add(key)if key in self.released_keys:self.released_keys.remove(key)def release(self, key):if key in self.allowed_keys:if key in self.pressed_keys:self.pressed_keys.remove(key)self.just_released.add(key)self.released_keys.add(key)def is_pressed(self, key):return key in self.pressed_keysdef is_released(self, key):return key in self.released_keysdef was_just_pressed(self, key):return key in self.just_presseddef was_just_released(self, key):return key in self.just_releaseddef update(self):self.just_pressed.clear()self.just_released.clear()def get_pressed_keys(self):return self.pressed_keys.copy()

回放工具类:

import jsonimport pygamefrom remake1.component.ball import Ball
from remake1.component.paddle import Paddle
from remake1.config import Configclass Replay:def __init__(self, filepath):with open(filepath, 'r') as f:self.data = json.load(f)# 从保存的数据还原Configself.config = Config()self.config.__dict__ = self.data["config"]# 初始化游戏窗口self.width, self.height = pygame.image.load(self.config.background_image).get_size()self.screen = pygame.display.set_mode((self.width, self.height))self.fps = self.config.fps# 初始化游戏对象self.ball = Ball(self.config.ball_images, 0, 0, 0, 0)self.paddles = [Paddle(self.config.paddle_image, 0, 0, 0, self.height),Paddle(self.config.paddle_image, 0, 0, 0, self.height)]def load_frame(self, frame_data):self.ball.load_state(frame_data["ball"])self.paddles[0].load_state(frame_data["paddle1"])self.paddles[1].load_state(frame_data["paddle2"])def play(self):clock = pygame.time.Clock()for frame in self.data["frames"]:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()return# 渲染背景self.screen.blit(pygame.image.load(self.config.background_image), (0, 0))self.load_frame(frame)# 渲染对象self.ball.render(frame["frame"], self.screen)self.paddles[0].render(self.screen)self.paddles[1].render(self.screen)pygame.display.flip()clock.tick(self.fps)

游戏主类:

import json
import os
import sysfrom datetime import datetimeimport pygame.imagefrom remake1.component.ball import Ball
from remake1.component.paddle import Paddle
from remake1.constant.enums import Direction
from remake1.strategy.stragety import Strategy
from remake1.util.input_util import InputUtilclass Game:def __init__(self,config):self.config = configself.width,self.height = pygame.image.load(config.background_image).get_size()self.paddle_height,self.paddle_width = pygame.image.load(config.paddle_image).get_size()self.screen = pygame.display.set_mode((self.width, self.height))self.ball = Ball(config.ball_images,self.width//2,10,config.ball_speed,config.ball_speed)self.paddles = [Paddle(config.paddle_image,5,self.height//2,config.paddle_speed,self.height),Paddle(config.paddle_image,self.width-5,self.height//2,config.paddle_speed,self.height),]self.game_history = []self.left_score = 0self.right_score = 0def save_state(self,direction1,direction2,frame):state = {'frame': frame,'ball': self.ball.get_state(),'paddle1': self.paddles[0].get_state(),'paddle2': self.paddles[1].get_state(),'actions': {'paddle1': direction1.name,'paddle2': direction2.name}}self.game_history.append(state)def update(self,direction1,direction2,frame):#更新物理位置self.ball.move() #更新球的位置self.paddles[0].move(direction1)self.paddles[1].move(direction2)#碰撞逻辑#挡板碰撞if self.ball.is_hit(self.paddles[0].rect):self.ball.rect.left = self.paddles[0].rect.rightself.ball.speedx = -self.ball.speedxif self.ball.is_hit(self.paddles[1].rect):self.ball.rect.right = self.paddles[1].rect.leftself.ball.speedx = -self.ball.speedx#上下边界碰撞if self.ball.rect.top < 0 or self.ball.rect.bottom > self.height:self.ball.speedy = -self.ball.speedy#左右边界计分if self.ball.rect.right < 0:self.ball.reset()self.right_score += 1if self.ball.rect.left > self.width:self.ball.reset()self.left_score += 1#渲染if self.config.render:self.ball.render(frame,self.screen)self.paddles[0].render(self.screen)self.paddles[1].render(self.screen)def winer(self):if self.right_score >= self.config.max_scores:return 1    #右边玩家winelif self.left_score >= self.config.max_scores:return -1   #左边玩家winelse:return 0    #游戏继续def export_history(self):# 创建保存目录os.makedirs(self.config.save_dir, exist_ok=True)# 时间戳命名文件timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")filename = f"game_{timestamp}.json"filepath = os.path.join(self.config.save_dir, filename)save_data = {"config": self.config.__dict__,"frames": self.game_history,}# 保存为json格式try:with open(filepath, 'w') as f:json.dump(save_data, f, indent=2)return Trueexcept Exception as e:print(f"Error saving game data: {e}")return Falsedef start(self):pygame.init()clock = pygame.time.Clock()if self.config.mode == "PVE":input_listener = InputUtil([pygame.K_w, pygame.K_s])elif self.config.mode == "PVP":input_listener = InputUtil([pygame.K_w, pygame.K_s, pygame.K_UP, pygame.K_DOWN])else:input_listener = Noneframe = 0direction1 = Direction.IDLEdirection2 = Direction.IDLEwhile True:if self.config.render:self.screen.blit(pygame.image.load(self.config.background_image),(0,0))for event in pygame.event.get():#按键监听if event.type == pygame.QUIT:pygame.quit()sys.exit()if event.type == pygame.KEYDOWN:input_listener.press(event.key)if event.type == pygame.KEYUP:input_listener.release(event.key)if self.config.mode == "PVP":#player1if input_listener.is_pressed(pygame.K_w):  # 多键输入优先向上direction1 = Direction.UPelif input_listener.is_pressed(pygame.K_s):direction1 = Direction.DOWNelse:direction1 = Direction.IDLE#player2if input_listener.is_pressed(pygame.K_UP):  # 多键输入优先向上direction2 = Direction.UPelif input_listener.is_pressed(pygame.K_DOWN):direction2 = Direction.DOWNelse:direction2 = Direction.IDLEelif self.config.mode == "PVE":# player1if input_listener.is_pressed(pygame.K_w):  # 多键输入优先向上direction1 = Direction.UPelif input_listener.is_pressed(pygame.K_s):direction1 = Direction.DOWNelse:direction1 = Direction.IDLE# aiif self.config.strategy_right == 1:direction2 = Strategy.simple_ai(self.ball.get_state(), self.paddles[1].get_state())elif self.config.strategy_right == 2:direction2 = Strategy.medium_ai(self.ball.get_state(), self.paddles[1].get_state(),self.paddle_height)elif self.config.strategy_right == 3:direction2 = Strategy.advanced_ai(self.ball.get_state(), self.paddles[1].get_state(),self.width,self.paddle_height)elif self.config.strategy_right == 4:direction2 = Strategy.expert_ai(self.ball.get_state(), self.paddles[1].get_state(),self.width,self.paddle_height)elif self.config.strategy_right == 5:direction2 = Strategy.reactive_ai(self.ball.get_state(), self.paddles[1].get_state(),self.paddle_height)if self.config.save:self.save_state(direction1,direction2,frame)self.update(direction1,direction2,frame)if self.winer() != 0:if self.config.save:self.export_history()breakframe += 1pygame.display.update()clock.tick(self.config.fps)

人机策略类:

import jsonimport pygamefrom remake1.component.ball import Ball
from remake1.component.paddle import Paddle
from remake1.config import Configclass Replay:def __init__(self, filepath):with open(filepath, 'r') as f:self.data = json.load(f)# 从保存的数据还原Configself.config = Config()self.config.__dict__ = self.data["config"]# 初始化游戏窗口self.width, self.height = pygame.image.load(self.config.background_image).get_size()self.screen = pygame.display.set_mode((self.width, self.height))self.fps = self.config.fps# 初始化游戏对象self.ball = Ball(self.config.ball_images, 0, 0, 0, 0)self.paddles = [Paddle(self.config.paddle_image, 0, 0, 0, self.height),Paddle(self.config.paddle_image, 0, 0, 0, self.height)]def load_frame(self, frame_data):self.ball.load_state(frame_data["ball"])self.paddles[0].load_state(frame_data["paddle1"])self.paddles[1].load_state(frame_data["paddle2"])def play(self):clock = pygame.time.Clock()for frame in self.data["frames"]:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()return# 渲染背景self.screen.blit(pygame.image.load(self.config.background_image), (0, 0))self.load_frame(frame)# 渲染对象self.ball.render(frame["frame"], self.screen)self.paddles[0].render(self.screen)self.paddles[1].render(self.screen)pygame.display.flip()clock.tick(self.fps)

最后:

尽管目前看来相比最初版代码变多了但功能反而少了,但实际上组件的拆分会大大加快开发的效率,但目前暂时不打算做丰富游戏功能的工作,毕竟游戏开发有那么多引擎何必纠结于pygame,只能作为一个了解代码逻辑的工具,以及pygame更多确实是用于强化学习方面的训练,后续会往这方面改,毕竟时代潮流在此,但参考目前代码框架想要二开应该难度不大,各位小伙伴可以自行尝试。

相关文章:

PyGame游戏开发(入门知识+组件拆分+历史存档/回放+人机策略)

前言&#xff1a; 本章实现游戏组件的复用解耦&#xff0c;以及使用配置文件替代原有硬编码形式&#xff0c;进而只需要改动配置文件即可实现整个游戏的难度和地图变化&#xff0c;同时增加历史记录功能&#xff0c;在配置文件开启后即可保存每一局的记录为json形式作为后续强化…...

【上位机——WPF】Window标签常用属性

常用属性 常用属性程序退出 常用属性都是写在Window标签中的 <Window x:Class"WpfDemo1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"…...

K8S Gateway AB测试、蓝绿发布、金丝雀(灰度)发布

假设有如下三个节点的 K8S 集群&#xff1a; ​ k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、场景分析 阅读本文&#xff0c;默认您已经安装了 K8S Gateway。 关于 AB 测试、金丝雀发布&#xff0c;可以看这篇文章。 二、实验准…...

人大金仓数据库 与django结合

要在Django项目中连接人大金仓数据库&#xff08;Kingbase&#xff09;&#xff0c;你需要使用一个适合的数据库适配器。人大金仓数据库是基于PostgreSQL的&#xff0c;因此你可以使用psycopg2库来与Django连接。但是&#xff0c;由于人大金仓数据库有其特定的功能和配置&#…...

RK3588 桌面系统配置WiFi和蓝牙配置

桌面右上角点击&#xff0c;打开选项&#xff0c;找到WiFi的选择网络或者WiFi设置 在弹出的窗口中选择需要连接的WiFi&#xff0c;然后右下角选择连接&#xff0c;然后输入WiFi密码即可连接。 25.4. 命令行连接wifi路由器 命令行配置wifi的方法有很多&#xff0c;下面介绍几种…...

TLV格式

‌TLV格式&#xff08;Tag-Length-Value&#xff09;是一种常用的数据序列化格式&#xff0c;主要用于数据包或消息的有效载荷编码。‌TLV格式将数据划分为三个主要部分&#xff1a;Tag&#xff08;标签&#xff09;、Length&#xff08;长度&#xff09;和Value&#xff08;值…...

2024年9月电子学会等级考试五级第三题——整数分解

题目 3、整数分解 正整数 N 的 K-P 分解是指将 N 写成 K 个正整数的 P 次方的和。本题就请你对任意给定的正整数 N、K、P&#xff0c;写出 N 的 K-P 分解。 时间限制&#xff1a;8000 内存限制&#xff1a;262144 输入 输入在一行给出 3 个正整数 N (≤ 400)、K (≤ N)、P (1 …...

软考 系统架构设计师系列知识点之杂项集萃(60)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;59&#xff09; 第97题 在面向对象设计中&#xff0c;&#xff08;&#xff09;可以实现界面控制、外部接口和环境隔离。&#xff08;&#xff09;作为完成用例业务的责任承担者&#xff0c;协调…...

使用Python开发经典俄罗斯方块游戏

使用Python开发经典俄罗斯方块游戏 在这篇教程中&#xff0c;我们将学习如何使用Python和Pygame库开发一个经典的俄罗斯方块游戏。这个项目将帮助你理解游戏开发的基本概念&#xff0c;包括图形界面、用户输入处理、碰撞检测等重要内容。 项目概述 我们将实现以下功能&…...

C++:字符数组与字符串指针变量的大小

#include<iostream> #include<cstring> int main(int argc, char const *argv[]) {// 字符数组char str[128] "hello world";std::cout<<sizeof(str)<<std::endl;std::cout<<strlen(str)<<std::endl;// 字符串指针变量char *st…...

stm32使用freertos时延时时间间隔不对,可能是晶振频率没设置

freertos 获取频率的接口 在 FreeRTOSConfig.h 文件中声明一个函数作为freertos的接口 /// /// brief 获取 SysTick 的频率 /// /// note arm cortex-m 系列 CPU 有一个 systick &#xff0c;里面有一个 CTRL 寄存器&#xff0c;其中的 bit2 /// 可以用来控制 systick 的时钟…...

51c~C语言~合集5

我自己的原文哦~ https://blog.51cto.com/whaosoft/13913911 一、大厂C语言编程10大规范 1 代码总体原则 1、清晰第一 清晰性是易于维护、易于重构的程序必需具备的特征。代码首先是给人读的&#xff0c;好的代码应当可以像文章一样发声朗诵出来。 目前软件维护期成本…...

前端流行框架Vue3教程:17. _组件数据传递

_组件数据传递 我们之前讲解过了组件之间的数据传递&#xff0c;props 和自定义事件 两种方式 props&#xff1a;父传子 自定义事件&#xff1a;子传父 除了上述的方案&#xff0c;props也可以实现子传父 一、项目结构 src/ └── components/├── ComponentsA.vue # 父…...

Stack overflow

本文来源 &#xff1a;腾讯元宝 Stack Overflow - Where Developers Learn, Share, & Build Careers 开发者学习&#xff0c;分享 通过学习、工作和经验积累等方式&#xff0c;逐步建立和发展自己的职业生涯。 Find answers to your technical questions and help othe…...

SpringBoot 3.4.5版本导入Lomobok依赖后无法生效的问题

问题背景 最近&#xff0c;随着DeepSeek的爆火&#xff0c;小编也编写了一个前后端分离的“知库随考”系统&#xff0c;由于Spring AI官方提示想要使用Spring AI的话要求Spring Boot的版本在“3.4.x”以上&#xff0c;所以我在创建SpringBoot项目的时候选择了了Server URL:http…...

FPGA: UltraScale+ bitslip实现(ISERDESE3)

收获 一晃五年~ 五年前那个夏夜&#xff0c;我对着泛蓝的屏幕敲下《给十年后的自己》&#xff0c;在2020年的疫情迷雾中编织着对未来的想象。此刻回望&#xff0c;第四届集创赛的参赛编号仍清晰如昨&#xff0c;而那个在家熬夜焊电路板的"不眠者"&#xff0c;现在…...

Electron详解:原理与不足

Electron是一个集成项目&#xff0c;它通过定制Chromium和Node.js&#xff0c;并将它们集成在内部来实现其功能。具体来说&#xff0c;Electron做了以下几个重要的工作&#xff1a; 定制Chromium&#xff1a;并将定制版本的Chromium集成在Electron内部。定制Node.js&#xff1…...

Spring Boot多数据源配置的陷阱与终极解决方案

引言 在微服务架构和复杂业务场景中&#xff0c;一个Spring Boot应用连接多个数据库的需求日益普遍。许多开发者尝试通过简单复制单数据源配置来实现多数据源&#xff0c;结果却遭遇了Bean冲突、事务失效、连接泄漏等隐蔽问题。本文将深入剖析Spring Boot自动配置的底层逻辑&a…...

android display 笔记(十四)VAU 和GSP 分别代表什么

VAU 和 GSP 的解释 GSP (Graphics/GPU Subsystem Processor) 含义&#xff1a; 图形处理子系统&#xff0c;通常指 SoC&#xff08;系统级芯片&#xff09;中负责 2D/3D 图形渲染、显示合成、图像后处理&#xff08;如缩放、旋转、色彩管理&#xff09; 的硬件模块。 在部分芯…...

tomcat 400 The valid characters are defined in RFC 7230 and RFC 3986

在遇到 Tomcat 因 URL 非法字符返回 400 Bad Request 时,选择在 Nginx 还是 Tomcat 中配置错误处理,需根据实际场景和需求权衡。以下是两种方案的详细对比及配置方法: 一、选择建议 方案适用场景优点缺点Nginx 配置- 需要统一处理所有后端服务(如多个 Tomcat 实例)的 400 …...

nginx负载均衡及keepalive高可用

实验前期准备&#xff1a; 5台虚拟机&#xff1a;4台当做服务器&#xff0c;1台当做客户机&#xff08;当然&#xff0c;也可以使用主机的浏览器&#xff09;&#xff0c;4台服务器中&#xff0c;2台服务器当做后端真实访问服务器&#xff1b;另外2台服务器当做负载均衡服务器…...

漏洞修复:tomcat 升级版本 spring-boot-starter-tomcat 的依赖项

在Spring Boot项目中修复Tomcat漏洞(如CVE-2024-21733)时,通常需要升级内嵌Tomcat版本。以下是具体操作步骤和注意事项: 一、确认当前Tomcat版本 通过启动日志查看 启动项目时,控制台日志中会显示类似 Starting Servlet engine: [Apache Tomcat/9.0.43] 的信息,直接查看版…...

二、IGMP

目录 1. IGMPv1 1.1 IGMPv1 报⽂类型 1.2 IGMPv1 工作机制 1.3 成员加入 1.4 离组机制 2. IGMPv2 2.1 IGMPv2 报文 2.3 查询器选举 & 维护 2.4 成员加入 2.4 离组机制 3. IGMPv3 3.1 IGMPv3 vs. IGMPv2 3.2 IGMPv3 报文 3.3 IGMPv3 工作机制 4. IGMP Proxy …...

Redis--基础知识点--27--redis缓存分类树

在 Redis 中存储分类树&#xff0c;通常需要选择合适的数据结构来表现层级关系。以下是使用 字符串&#xff08;String&#xff09; 和 哈希&#xff08;Hash&#xff09; 两种常见方案的举例说明&#xff0c;结合电商分类场景&#xff08;如 电子产品 > 手机 > 智能手机…...

【2025最新】VSCode Cline插件配置教程:免费使用Claude 3.7提升编程效率

 2025年最新VSCode Cline插件安装配置教程&#xff0c;详解多种免费使用Claude 3.7的方法&#xff0c;集成DeepSeek-R1与5大实用功能&#xff0c;专业编程效率提升指南。 Cline是VSCode中功能最强大的AI编程助手插件之一&#xff0c;它能与Claude、OpenAI等多种大模型无缝集…...

SQL笔记一

SQL的分类 DDL&#xff08;数据定义语言&#xff09;&#xff1a;CREATE&#xff08;创建&#xff09; ALTER&#xff08;修改&#xff09; DROP&#xff08;删除结构&#xff09; RENAME&#xff08;重命名&#xff09; TRUNCATE&#xff08;清空&#xff09; DML&#xff0…...

高可靠低纹波国产4644电源芯片在工业设备的应用

摘要 随着工业自动化和智能化的飞速发展&#xff0c;工业设备对于电源芯片的性能和可靠性提出了前所未有的严格要求。电源芯片作为工业设备的核心供电组件&#xff0c;其性能直接影响到整个设备的运行效率和稳定性。本文以国科安芯的ASP4644四通道降压稳压器为例&#xff0c;通…...

MyBatis 的分页插件 c

前言 大型项目的数据体量很大&#xff0c;在前端界面展示时为保障展示效果&#xff0c;会要求接口快速返回&#xff0c;这时候后端会选择分页获取数据&#xff0c;只传递要查询的页码数据。这就避免了大多问题&#xff0c;达到快速返回的效果。 常用的分页有2种&#xff1a; …...

网络安全-等级保护(等保) 2-5 GB/T 25070—2019《信息安全技术 网络安全等级保护安全设计技术要求》-2019-05-10发布【现行】

################################################################################ GB/T 22239-2019 《信息安全技术 网络安全等级保护基础要求》包含安全物理环境、安全通信网络、安全区域边界、安全计算环境、安全管理中心、安全管理制度、安全管理机构、安全管理人员、安…...

嵌软面试每日一阅----FreeRTOS

一. FreeRTOS 创建任务的方法及区别 在 FreeRTOS 中&#xff0c;任务创建主要有两种方式&#xff1a;动态内存分配&#xff08;xTaskCreate()&#xff09;和静态内存分配&#xff08;xTaskCreateStatic()&#xff09;。以下是两者的核心区别及使用场景&#xff1a; 1. 动态创建…...

EasyExcel详解

文章目录 一、easyExcel1.什么是easyExcel2.easyExcel示例demo3.easyExcel read的底层逻辑~~4.easyExcel write的底层逻辑~~ 二、FastExcel1.为什么更换为fastExcel2.fastExcel新功能 一、easyExcel 1.什么是easyExcel 内容摘自官方&#xff1a;Java解析、生成Excel比较有名的…...

023-C语言预处理详解

C语言预处理详解 文章目录 C语言预处理详解1. 预定义符号2. #define定义常量3. #define定义宏4. 带有副作用的宏参数5. 宏替换的规则6. 宏函数的对比7. #和##7.1 #运算符7.2 ##运算符 8. 命名约定9. #undef10. 命令行定义11. 条件编译12. 头文件包含12.1 头文件被包含方式12.1.…...

C#自定义控件-实现了一个支持平移、缩放、双击重置的图像显示控件

1. 控件概述 这是一个继承自 Control 的自定义控件&#xff0c;主要用于图像的显示和交互操作&#xff0c;具有以下核心功能&#xff1a; 图像显示与缩放&#xff08;支持鼠标滚轮缩放&#xff09;图像平移&#xff08;支持鼠标拖拽&#xff09;视图重置&#xff08;双击重置…...

MarkitDown:AI时代的文档转换利器

在当今AI快速发展的时代,如何高效地将各种格式的文档转换为机器可读的格式,成为了一个迫切需要解决的问题。今天,我们来介绍一款由微软开发的强大工具——MarkitDown,它正是为解决这一问题而生的。 什么是MarkitDown? MarkitDown是一个用Python编写的轻量级工具,专门用…...

《数字分身进化论:React Native与Flutter如何打造沉浸式虚拟形象编辑》

React Native&#xff0c;依托JavaScript语言&#xff0c;借助其成熟的React生态系统&#xff0c;开发者能够快速上手&#xff0c;将前端开发的经验巧妙运用到移动应用开发中。它通过JavaScript桥接机制调用原生组件&#xff0c;实现与iOS和Android系统的深度交互&#xff0c;这…...

DeerFlow:字节新一代 DeepSearch 框架

项目地址&#xff1a;https://github.com/bytedance/deer-flow/ 【全新的 Multi-Agent 架构设计】独家设计的 Research Team 机制&#xff0c;支持多轮对话、多轮决策和多轮任务执行。与 LangChain 原版 Supervisor 相比&#xff0c;显著减少 Tokens 消耗和 API 调用次数&#…...

数字孪生工厂实战指南:基于Unreal Engine/Omniverse的虚实同步系统开发

引言&#xff1a;工业元宇宙的基石技术 在智能制造2025与工业元宇宙的交汇点&#xff0c;数字孪生技术正重塑传统制造业。本文将手把手指导您构建基于Unreal Engine 5.4与NVIDIA Omniverse的实时数字孪生工厂系统&#xff0c;集成Kafka实现毫秒级虚实同步&#xff0c;最终交付…...

牛客网NC22015:最大值和最小值

牛客网NC22015&#xff1a;最大值和最小值 题目描述 题目要求 输入&#xff1a;一行&#xff0c;包含三个整数 a, b, c &#xff08;1≤a,b,c≤1000000&#xff09; 输出&#xff1a;两行&#xff0c;第一行输出最大数&#xff0c;第二行输出最小数。 样例输入&#xff1a; …...

Uniapp中小程序调用腾讯地图(获取定位地址)

1、先配置权限&#xff1a; 这是上图的代码&#xff1a; "permission": { "scope.userLocation": { "desc": "你的位置信息将用于小程序位置接口的效果展示" } } 第二步&#xff1a;写代码&#xff1a; //下面是uniapp的模版代码 主…...

2025 后端自学UNIAPP【项目实战:旅游项目】5、个人中心页面:微信登录,同意授权,获取用户信息

一、框架以及准备工作 1、前端项目文件结构展示 2、后端项目文件结构展示 3、登录微信公众平台&#xff0c;注册一个个人的程序&#xff0c;获取大appid&#xff08;前端后端都需要&#xff09;和密钥&#xff08;后端需要&#xff09; 微信公众平台微信公众平台&…...

隆重推荐(Android 和 iOS)UI 自动化工具—Maestro

文章目录 前言一、为什么选择 Maestro&#xff1f;二、使用步骤1.安装&#xff08;Windows&#xff09;2.运行示例 三、Maestro Studio &#xff08;重点&#xff09;轻松编辑测试 四、价格总结 前言 当前移动 UI 自动化工具的实际效能与预期存在显著差距&#xff0c;团队推行…...

C#发送文件到蓝牙设备

测试环境&#xff1a; visual studio 2022 win11笔记本电脑&#xff0c;具有蓝牙功能 .net6控制台 测试步骤如下&#xff1a; 1 新增名为BluetoothDemo控制台项目 2 通过nuget安装InTheHand.Net.Bluetooth&#xff0c;版本选择4.2.1和安装InTheHand.Net.Obex&#xff0c;版…...

采用sherpa-onnx 实现 ios语音唤起的调研

背景 项目中需要实现一个语音唤起的功能&#xff0c;选择sherpa-onnx进行调研&#xff0c;要求各端都要验证没有问题。个人负责ios这部分的调研。查询官方发现没有直接针对ios语音唤起的稳定&#xff0c;主要技术平台也没有相关的可以借鉴。经过调研之后补充了一个。 一、下载…...

磁盘I/O瓶颈排查:面试通关“三部曲”心法

想象一下&#xff0c;你就是线上系统的“交通调度总指挥”&#xff0c;服务器的磁盘是所有数据进出的“核心枢纽港口”。当这个“港口”突然拥堵不堪&#xff0c;卡车&#xff08;数据请求&#xff09;排起长龙&#xff0c;进不去也出不来&#xff0c;整个系统的“物流”&#…...

磁盘性能测试与分析:结合fio和iostat的完整方案

磁盘性能测试与分析&#xff1a;结合fio和iostat的完整方案 磁盘性能是影响现代计算机系统整体运行效率的关键因素之一&#xff0c;特别是对于高I/O负载的应用如数据库、虚拟化环境等。本文将详细介绍如何利用fio和iostat工具全面评估磁盘性能&#xff0c;包括IOPS、带宽、延迟…...

随机森林(Random Forest)

随机森林&#xff08;Random Forest&#xff09;是一种基于决策树的集成学习算法&#xff0c;它通过构建多个决策树并将它们的预测结果进行综合&#xff0c;从而提高模型的准确性和稳定性。 1.基本原理 随机森林属于集成学习中的“Bagging”方法。其核心思想是通过构建多个决…...

C#数据类型

&#x1f9e9; 一、布尔值&#xff08;bool&#xff09; 表示逻辑值&#xff1a;true 或 false bool isTrue true; bool isFalse false;&#x1f4cc; 二、整数&#xff08;Integer Types&#xff09; C# 支持多种有符号和无符号整数类型&#xff1a; 类型大小范围sbyte8…...

FastAPI 实现 Express 框架的 p-limit(1) 防并发操作

背景 以下是将 Electron 主进程中的 CURD 逻辑&#xff08;Express 实现&#xff09;迁移到 FastAPI 的完整方案&#xff0c;包含技术选型、实现步骤和注意事项&#xff0c;确保主进程与子进程解耦且稳定运行&#xff1a; 关键点 注意用 conda 安装 python 版本时&#xff0c…...

STC8H系列单片机STC8H_H头文件功能注释

#ifndef __STC8H_H__ // 条件编译:如果未定义__STC8H_H__宏 #define __STC8H_H__ // 则定义该宏,防止头文件被重复包含 / //包含本头文件后,不用另外再包含"REG51.H" // 提示:本头文件已包含基本寄存器定义 sfr P0 = …...

C#中BackgroundWorker的概念与用法详解

一、BackgroundWorker 概念 BackgroundWorker 是 C# 中用于在后台线程中运行操作的组件&#xff0c;它允许你在不影响用户界面&#xff08;UI&#xff09;响应能力的情况下执行耗时操作。 它位于 System.ComponentModel 命名空间内&#xff0c;主要用于 Windows 窗体应用程序中…...