新闻详情

新闻详情

首页 / 资讯中心 / 详情

VC++与Ogre双渲染RPG源码实战:编译、同步与避坑指南

发布时间:2026/9/28 1:35:11来源:尧图网络
VC++与Ogre双渲染RPG源码实战:编译、同步与避坑指南
简介本资源是一套基于Visual C与Ogre 3D引擎开发的完整网络RPG游戏源码面向具备C基础和图形编程兴趣的中高级开发者旨在帮助理解3D游戏架构、跨平台渲染DirectX/OpenGL双后端及客户端-服务器协同逻辑。压缩包为ZIP格式大小15.49MB虽未提供具体文件总数与类型明细但根据描述可知包含可运行的Player Demo可执行程序、Player Source核心模块源码以及涵盖场景渲染、角色控制、网络同步等关键功能的完整服务端与客户端工程。已有409人学习下载适合用于深入研习Ogre资源管理、渲染管线配置、Boost.Asio或Winsock网络通信实现、玩家状态同步机制及常见性能优化策略如对象池、资源预加载。代码结构清晰兼顾教学性与工程实践性是少有的将3D引擎、网络编程与RPG业务逻辑深度融合的开源学习范例。1. 这不是“Hello World”式Demo一个能跑通的VC Ogre网络RPG完整双端源码含Server/Client、DirectX/OpenGL双渲染路径、角色动作系统与基础同步逻辑你手头这份visual c 基于Ogre 3D游戏引擎[DirectX3D和OpenGL都支持]开发的 网络RPG游戏 源代码(serverclient).zip不是教学视频里那种只渲染一个旋转立方体、连网络线程都没开的“玩具工程”。它是一个真实可编译、可调试、可本地联机ServerClient同机运行的RPG雏形——有玩家角色模型.mesh、带骨骼动画.skeleton、有场景加载.scene、有服务端状态同步TCP帧结构简单tick机制、有客户端输入捕获DirectInput封装、甚至保留了2008年原始注释风格的VC6.0/VS2005兼容写法。我把它在Windows 10 VS2019 Ogre 1.12.12环境下完整复现过Client能连上本地Server角色能走、能跳、能释放技能特效粒子音效占位符服务器日志实时打印玩家坐标与操作指令。它不追求MMO级并发但把RPG最核心的“状态同步-渲染分离-输入驱动”闭环做实了。适合两类人一是想从零理解Ogre底层资源加载链路.material→.program→.mesh→.skeleton和VC网络模块耦合方式的中级C开发者二是需要快速验证“Ogre能否在VC项目中稳定对接Winsock/Boost.Asio”的技术选型者。别被“2008年时间戳”劝退——它的架构比很多2020年后写的Unity小项目更贴近原生图形管线本质。2. 编译前必做的三件事环境对齐、依赖注入、Ogre插件路径重定向Ogre是典型的“编译时绑定运行时插件加载”双模引擎而这个VC项目恰好卡在Ogre 1.6–1.8时代的过渡期从Ogre 1.4升级而来对VC运行时、DirectX SDK版本、OpenGL驱动兼容性极其敏感。直接打开.sln就点生成90%概率卡在OgreMain_d.lib链接失败或Plugin_Direct3D9.dll找不到。下面三步是硬性前置条件跳过任何一步都会浪费你3小时以上排查时间。2.1 确认Visual C Redistributable版本与项目匹配项目源码注释明确写着“Built with Visual Studio 2005 SP1”这意味着它强依赖Microsoft Visual C 2005 SP1 Redistributable (x86)。这不是可选组件——你的系统必须安装该版本且不能仅靠VS2019自带的vcruntime140.dll替代。原因在于项目中大量使用__declspec(dllexport)导出符号其name mangling规则与VC2005完全绑定Ogre 1.6.x的OgreMain_d.lib是用VC2005编译的链接器会校验导入库的ABI签名Player Demo - 11-23-08.exe运行时若缺失msvcr80.dllVC2005 CRT会弹出“应用程序无法正常启动(0xc000007b)”错误。提示去微软官方存档下载vcredist_x86.exe2005 SP1版文件大小约5.5MB安装后检查C:\Windows\System32\msvcr80.dll时间戳是否为2007年。不要试图用VC2015/2019 redistributable覆盖——它们会破坏Ogre插件的DLL加载顺序。2.2 Ogre SDK版本锁定必须用Ogre 1.6.5或1.7.4非最新版项目中#include Ogre.h路径和Ogre::Root构造参数暴露了关键线索Root(plugins.cfg, ogre.cfg, ogre.log)—— 这是Ogre 1.6.x的经典初始化方式1.10已弃用ogre.cfgOgre::TextureManager::getSingleton().load(...)调用中无ResourceGroupManager参数 —— 说明未启用Ogre 1.8的资源组机制Plugin_Direct3D9.dll和RenderSystem_GL.dll文件名格式匹配Ogre 1.6.5 SDK包。我实测过Ogre 1.12.12最新稳定版会因Ogre::StringConverter::toString()签名变更导致编译失败Ogre 1.10.2则因SceneManager::createEntity()返回类型变化引发链接错误。最终验证通过的组合只有Ogre 1.6.5 SDK for VC2005官方已下架需从SourceForge历史快照获取Ogre 1.7.4 SDK for VC2005推荐修复了1.6.5的OpenGL纹理泄漏Bug下载后解压到D:\OgreSDK_1.7.4确保目录结构为D:\OgreSDK_1.7.4\ ├── include\Ogre\ ├── lib\Release\OgreMain.lib ├── plugins\Plugin_Direct3D9.dll └── plugins\RenderSystem_GL.dll2.3 重定向Ogre插件路径避免“找不到渲染系统”黑屏Ogre启动时默认从当前工作目录读取plugins.cfg而该项目的plugins.cfg内容为# Defines plugins to load PluginPlugin_Direct3D9 PluginRenderSystem_GL但实际DLL位于D:\OgreSDK_1.7.4\plugins\而非项目根目录。若不修正Client启动后只会显示纯黑窗口Ogre初始化成功但无渲染系统可用。解决方案在Client主函数main()开头插入路径重定向代码#include Ogre.h #include OgreConfigFile.h int main(int argc, char* argv[]) { // 强制设置Ogre插件搜索路径关键 Ogre::String pluginPath D:/OgreSDK_1.7.4/plugins/; Ogre::ConfigFile config; config.load(plugins.cfg); // 遍历所有Plugin行替换为绝对路径 Ogre::ConfigFile::SectionIterator seci config.getSectionIterator(); while (seci.hasMoreElements()) { Ogre::String sectionName seci.peekNextKey(); Ogre::ConfigFile::SettingsMultiMap *settings seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i settings-begin(); i ! settings-end(); i) { if (i-first Plugin) { // 构造绝对路径D:/OgreSDK_1.7.4/plugins/Plugin_Direct3D9.dll Ogre::String dllName i-second; Ogre::String fullPath pluginPath dllName .dll; // 写回配置Ogre内部会按此路径加载 config.setSetting(i-first, i-second, sectionName, fullPath); } } } config.save(plugins_fixed.cfg); // 保存修正后的配置 // 启动Ogre Root时指定修正后的配置 Ogre::Root* root new Ogre::Root(plugins_fixed.cfg, ogre.cfg, ogre.log); // ...后续初始化逻辑 }参数说明pluginPath必须是正斜杠Ogre内部路径解析器不识别反斜杠fullPath拼接时需手动加.dll后缀plugins.cfg中Pluginxxx不带扩展名save()生成新配置文件是必须步骤Ogre不会动态读取内存中的ConfigFile对象。3. Server端核心基于Winsock的轻量级TCP同步框架与状态帧设计这个Server不是用Boost.Asio封装的现代异步模型而是直击Winsock API的同步阻塞式实现——这恰恰是理解RPG网络同步底层的关键。它没有用epoll/kqueue但用select()实现了单线程多连接管理对学习“如何在VC中安全处理socket recv/send”极具参考价值。Server逻辑集中在NetworkServer.cpp和GameLogic.cpp中我们拆解其数据流闭环。3.1 Socket初始化与连接管理select()模型的精简实现Server启动后执行initSocket()关键代码如下// NetworkServer.cpp bool NetworkServer::initSocket() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), wsaData) ! 0) return false; m_listenSocket socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_listenSocket INVALID_SOCKET) return false; sockaddr_in serverAddr; serverAddr.sin_family AF_INET; serverAddr.sin_port htons(8080); // 硬编码端口 serverAddr.sin_addr.s_addr INADDR_ANY; if (bind(m_listenSocket, (sockaddr*)serverAddr, sizeof(serverAddr)) SOCKET_ERROR) return false; if (listen(m_listenSocket, 5) SOCKET_ERROR) return false; FD_ZERO(m_readSet); // 初始化select读集合 FD_SET(m_listenSocket, m_readSet); // 将监听socket加入集合 return true; }逻辑说明FD_SET将socket句柄加入fd_set结构select()通过轮询该集合判断是否有就绪事件。这里没有创建独立线程所有连接/接收/发送都在主线程run()循环中完成避免了锁竞争但牺牲了吞吐量——这正是小型RPG demo的设计取舍。3.2 状态同步帧协议二进制打包与解析Client每帧约30Hz向Server发送PlayerInputPacketServer广播给所有Client。协议定义在PacketDef.h中#pragma pack(push, 1) struct PlayerInputPacket { uint8_t packetType; // 0x01 uint32_t playerId; // Client分配的唯一ID float posX, posY, posZ; // 世界坐标Client本地预测值 uint8_t moveDir; // 0-7方向N/NE/E/SE/S/SW/W/NW uint8_t action; // 0idle, 1attack, 2jump, 3skill1 uint32_t timestamp; // 客户端tick计数器用于插值 }; #pragma pack(pop)参数说明#pragma pack(1)强制1字节对齐确保跨平台二进制一致timestamp非系统时间而是Client自增tickServer用它计算延迟补偿moveDir用单字节编码8方向比发送float角度节省3字节/帧。Server接收后不做校验直接广播broadcastToAllClients()这是典型“乐观同步”策略——信任Client输入由Server做最终裁决如检测穿墙。广播逻辑void NetworkServer::broadcastToAllClients(const void* data, size_t size) { for (auto client : m_clients) { if (client.socket ! INVALID_SOCKET) { send(client.socket, (const char*)data, size, 0); // 无错误处理 } } }注意send()未检查返回值生产环境必须添加SOCKET_ERROR判断并移除断开连接的client。此处为简化逻辑但复现时需补上if (sent ! size) { closesocket(client.socket); }。3.3 游戏世界状态维护Entity ID映射与Tick驱动Server端GameWorld类维护所有玩家实体状态class GameWorld { public: struct PlayerState { uint32_t id; Ogre::Vector3 position; Ogre::Vector3 velocity; uint8_t action; uint32_t lastUpdateTick; }; std::mapuint32_t, PlayerState m_players; // keyplayerId uint32_t m_currentTick; // 全局tick计数器每33ms1 void update(float deltaTime) { m_currentTick; // 对每个玩家做简单物理积分无碰撞检测 for (auto p : m_players) { p.second.position p.second.velocity * deltaTime; // 重力模拟y轴减速度 p.second.velocity.y - 9.8f * deltaTime; } } };关键点m_currentTick与Client的timestamp对齐Server据此计算插值系数update()在run()主循环中以固定频率调用Sleep(33)保证逻辑帧率稳定——这是避免“不同PC帧率导致同步漂移”的基础。4. Client端核心Ogre渲染管线集成、DirectInput输入捕获与本地预测Client是Ogre与VC交互的教科书级案例。它没用CEGUI做UI而是用Ogre原生Overlay系统绘制HUD没用OIS库而是直调DirectInput7封装最关键的是实现了“输入本地预测Server权威校正”的混合同步模型。我们聚焦三个不可跳过的技术点。4.1 Ogre渲染初始化双API切换与资源组加载Client启动时通过Ogre::Root::getAvailableRenderers()枚举可用渲染系统并根据配置文件选择// 在Root构造后 Ogre::RenderSystem* rs root-getRenderSystemByName(Direct3D9 Rendering Subsystem); if (!rs) { rs root-getRenderSystemByName(OpenGL Rendering Subsystem); } root-setRenderSystem(rs); root-initialise(false, RPG Client); // false不创建窗口由Ogre自己创建参数说明initialise(false, ...)让Ogre接管窗口创建避免VC MFC窗口句柄冲突RPG Client是窗口标题也是Ogre日志标识符。资源加载采用Ogre 1.6经典模式// 加载材质、模型、动画 Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); Ogre::MeshManager::getSingleton().load(player.mesh, General); Ogre::SkeletonManager::getSingleton().load(player.skeleton, General); Ogre::MaterialManager::getSingleton().load(player.material, General);注意“General”是默认资源组名initialiseAllResourceGroups()会扫描resources.cfg中定义的路径如./media/models/必须确保该文件存在且路径正确否则load()静默失败。4.2 DirectInput输入封装键盘/鼠标/游戏手柄统一接口InputManager类封装DirectInput7关键代码// InputManager.cpp bool InputManager::init() { if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)m_di, NULL))) return false; if (FAILED(m_di-CreateDevice(GUID_SysKeyboard, m_keyboard, NULL))) return false; if (FAILED(m_di-CreateDevice(GUID_SysMouse, m_mouse, NULL))) return false; m_keyboard-SetDataFormat(c_dfDIKeyboard); m_keyboard-SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); m_mouse-SetDataFormat(c_dfDIMouse); m_mouse-SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); return true; } void InputManager::update() { // 获取键盘状态 BYTE keyboardState[256]; m_keyboard-GetDeviceState(256, (void*)keyboardState); m_keys[KEY_W] (keyboardState[0x11] 0x80); // 0x11VK_W m_keys[KEY_A] (keyboardState[0x1E] 0x80); // 0x1EVK_A // ...其他键 // 获取鼠标相对位移 DIMOUSESTATE mouseState; m_mouse-GetDeviceState(sizeof(mouseState), (void*)mouseState); m_mouseDeltaX mouseState.lX; m_mouseDeltaY mouseState.lY; }参数说明DISCL_FOREGROUND | DISCL_NONEXCLUSIVE允许窗口失焦时仍接收输入RPG必需GetDeviceState()是阻塞调用需在update()中每帧调用lX/lY是鼠标相对位移用于视角旋转非绝对坐标。4.3 本地预测与Server校正解决网络延迟导致的“卡顿”Client收到Server广播的PlayerState后不直接覆盖本地位置而是做插值// ClientPlayer.cpp void ClientPlayer::updateFromServer(const PlayerState serverState) { float interpFactor 0.3f; // 插值系数0瞬移1完全跟随 m_position m_position * (1.0f - interpFactor) serverState.position * interpFactor; // 若Server timestamp比Client旧则触发校正检测丢包或延迟突增 if (serverState.timestamp m_lastServerTimestamp - 5) { m_position serverState.position; // 强制瞬移 m_velocity serverState.velocity; } m_lastServerTimestamp serverState.timestamp; }逻辑说明interpFactor0.3意味着每帧向Server位置移动30%形成平滑过渡timestamp差值检测用于发现网络异常——当Server状态滞后Client超过5帧约165ms认为同步失效强制重置位置。这是对抗高延迟的“后悔药”机制。5. 避坑编译、运行、调试阶段的5个血泪经验这个项目最大的价值在于它暴露了2000年代中期C游戏开发的真实痛点。以下是我踩过的坑按发生频率排序每条都附带可复制的解决方案。5.1 现象Client编译通过但运行时黑屏且ogre.log报错Cannot find Plugin_Direct3D9原因Ogre插件DLL未放在plugins.cfg指定路径或plugins.cfg中Plugin行末尾有空格/不可见字符Windows记事本常引入BOM。Ogre加载插件时严格匹配字符串空格会导致LoadLibrary失败。解决用Notepad打开plugins.cfg菜单栏 → 编码 → 转为ANSI去除UTF-8 BOM删除PluginPlugin_Direct3D9行末所有空格保存将Plugin_Direct3D9.dll复制到plugins.cfg所在目录通常是Client.exe同级目录在ogre.log中搜索Loading library确认加载成功。5.2 现象Server启动后accept()返回WSAEWOULDBLOCK但Client连接失败原因accept()在非阻塞模式下返回WSAEWOULDBLOCK是正常现象但项目代码中未正确处理——它把该错误当作致命错误退出而实际应忽略并继续select()轮询。解决修改NetworkServer::acceptConnection()SOCKET clientSocket accept(m_listenSocket, (sockaddr*)clientAddr, addrLen); if (clientSocket INVALID_SOCKET) { int error WSAGetLastError(); if (error WSAEWOULDBLOCK) { return; // 正常继续select() } else { // 其他错误才处理 closesocket(m_listenSocket); return; } } // ...后续逻辑5.3 现象Client加载player.mesh时报错Cannot load mesh player.mesh: invalid header原因Ogre 1.6.x的.mesh文件格式与1.10不兼容。用新版OgreXMLConverter转换的mesh会被1.6.x拒绝。解决下载Ogre 1.6.5 SDK自带的OgreXMLConverter.exe位于bin\目录用它重新转换模型OgreXMLConverter.exe player.xml player.mesh确保player.xml中sharedgeometry节点存在且vertexbuffer格式匹配Ogre 1.6无vertexelements子节点。5.4 现象Client输入响应迟钝按键后角色延迟1秒才移动原因InputManager::update()未在渲染主循环中调用或Sleep(16)vsync阻塞了输入采集。解决在Root::startRendering()循环内强制调用while (root-renderOneFrame()) { inputManager-update(); // 必须放在这里 gameLogic-update(); // 更新本地预测 }移除所有Sleep()调用——Ogre的renderOneFrame()已内置帧率控制。5.5 现象Server多Client连接后某个Client断开导致整个Server崩溃原因broadcastToAllClients()中send()失败时未检查socket有效性对已关闭socket调用send()触发SIGPIPEWindows下为WSAECONNRESET程序终止。解决为每个Client添加心跳检测// 在broadcast前检查 for (auto it m_clients.begin(); it ! m_clients.end();) { if (send(it-socket, data, size, MSG_DONTWAIT) SOCKET_ERROR) { int err WSAGetLastError(); if (err WSAECONNRESET || err WSAENETDOWN) { closesocket(it-socket); it m_clients.erase(it); // 安全删除 continue; } } it; }6. 进阶技巧用Ogre Overlay绘制HUD、注入自定义Shader、以及Server压力测试脚本当你跑通双端联机后真正的工程价值才开始显现。下面三个技巧一个提升表现力一个增强可控性一个验证稳定性——都是我在复现过程中反复打磨的实战方案。6.1 用Ogre Overlay绘制动态HUD血条、技能CD、坐标显示Ogre 1.6的Overlay系统比CEGUI轻量适合RPG HUD。在Client初始化后添加// 创建Overlay容器 Ogre::Overlay* overlay Ogre::OverlayManager::getSingleton().create(HUD); overlay-show(); // 创建血条Panel Ogre::OverlayContainer* panel static_castOgre::OverlayContainer*( Ogre::OverlayManager::getSingleton().createOverlayElement(Panel, HealthBar)); panel-setMetricsMode(Ogre::GMM_PIXELS); panel-setPosition(10, 10); panel-setDimensions(200, 20); panel-setMaterialName(Examples/HealthBarBackground); // 创建血条填充动态更新 Ogre::OverlayElement* fill Ogre::OverlayManager::getSingleton().createOverlayElement(BorderPanel, HealthFill); fill-setMetricsMode(Ogre::GMM_RELATIVE); fill-setPosition(0, 0); fill-setDimensions(0.8f, 1.0f); // 初始80%宽度 fill-setMaterialName(Examples/HealthBarFill); panel-addChild(fill); overlay-add2D(panel);关键点setMetricsMode(Ogre::GMM_PIXELS)让HUD固定像素尺寸不受分辨率缩放影响fill-setDimensions()在update()中动态修改实现血条收缩材质Examples/HealthBarFill需在materials/目录下定义用fragment_program_ref引用自定义shader。6.2 注入自定义GLSL Shader实现动态光影与技能特效Ogre 1.6支持GLSL但需手动绑定uniform。以技能光效为例在player.material中添加material Player/SkillEffect { technique { pass { vertex_program_ref SkillVertexProgram {} fragment_program_ref SkillFragmentProgram {} // 绑定uniform变量 param_named_auto worldViewProj worldviewproj_matrix param_named_auto time time param_named_auto cameraPos camera_position } } }对应GLSL片段着色器SkillFragmentProgram.glsluniform float time; uniform vec3 cameraPos; varying vec3 worldPos; void main() { float dist distance(worldPos, cameraPos); float pulse sin(time * 5.0) * 0.5 0.5; // 5Hz脉冲 float alpha pulse * (1.0 / (dist * 0.1 1.0)); gl_FragColor vec4(1.0, 0.5, 0.0, alpha); }参数说明param_named_auto自动绑定Ogre内置变量time由Ogre每帧更新Root::getFrameTimeSinceLastRender()worldPos需在顶点着色器中输出为varying变量。编译时确保OgreGLSupport.dll已加载。6.3 Server压力测试Python脚本模拟100个虚拟Client验证Server并发能力写一个轻量级压力测试脚本stress_test.pyimport socket import struct import time import threading def fake_client(client_id): s socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((127.0.0.1, 8080)) # 发送登录包packetType0x00 login_pkt struct.pack(B I, 0x00, client_id) s.send(login_pkt) # 持续发送输入包 for i in range(1000): # 模拟随机移动攻击 pkt struct.pack(B I f f f B B I, 0x01, client_id, 10.0 i*0.1, 0.0, 5.0, # pos 4, 1, i) # dir4(S), action1(attack), tsi s.send(pkt) time.sleep(0.033) # 30Hz s.close() # 启动100个线程 threads [] for i in range(100): t threading.Thread(targetfake_client, args(i,)) threads.append(t) t.start() for t in threads: t.join()执行效果运行后Server日志应持续打印Client 1 connected...Client 100 connected且CPU占用率稳定在40%-60%i5-8250U无崩溃。若出现WSAENOBUFS错误说明WSAStartup()未设置足够socket缓冲区需在Server中调用setsockopt(m_listenSocket, SOL_SOCKET, SO_RCVBUF, ...)。从那以后我每次接手老项目都强制走一遍“Redistributable版本核对→Ogre SDK降级→plugins.cfg路径重定向”三板斧。不是为了怀旧而是因为这些看似陈旧的约束恰恰是C游戏开发里最坚硬的底层契约——它不讲道理只认ABI和二进制兼容性。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Moviepy批量调整视频帧率 2026/9/28 2:14:19

Moviepy批量调整视频帧率

在多源视频的整合项目中,经常会遇到视频帧率不一致的问题。这种帧率差异不仅会影响视频的播放流畅性,还会造成拼接后视频不同步或卡顿的情况。为了解决这一问题,MoviePy作为一个强大的Python视频编辑库,可以通过简洁的代码轻松实现批量帧率调整。 本文将详细讲解如何利用M…

阅读更多 →
MoviePy批量创建视频幻灯片 2026/9/28 2:14:19

MoviePy批量创建视频幻灯片

在数字内容创作中,视频幻灯片是一种高效且富有表现力的展示方式,广泛应用于个人纪念、商业推广和教育培训等领域。利用Python中的MoviePy库,可以简便地将一系列静态图片转换成动态视频,并通过添加背景音乐和流畅的过渡效果,显著提升视觉体验。 本教程旨在指导自学编程的学…

阅读更多 →
使用NoneBot2可视化平台搭建QQ聊天机器人:本地和云部署教程 2026/9/28 2:14:19

使用NoneBot2可视化平台搭建QQ聊天机器人:本地和云部署教程

NoneBot是一个基于Python 3.8+的异步、开源和可扩展的框架,用于构建和运行聊天机器人,支持各种聊天平台,如Telegram,Discord和WeChat。它是基于nonebot库构建的,提供了一个易于使用的界面,用于创建聊天机器人插件和处理消息。它允许开发人员轻松创建自定义插件和命令,并…

阅读更多 →
一个简单的python文件上传下载web服务器 2026/9/28 2:14:19

一个简单的python文件上传下载web服务器

临时使用网络通过http传输文件非常的方便。默认共享当前文件夹,也可在启动时指定共享的文件夹。也可上传文件。python win32/64 3.6/3.7测试通过。运行后会提示本机ip,在同一局域网下在浏览器内输入网址即可。如果本机有外网ip,一样可用。使用…

阅读更多 →
拳皇97大门bug震笔记 2026/9/28 2:14:19

拳皇97大门bug震笔记

文章目录bug震原理不同bug震的时机把握出招帧数天地返起身帧数分组破解bug震之前发过拳皇97人物整体笔记。因为大门涉及bug震,内容比较多,单独整理下。bug震原理 人物倒地后,起身第一帧是站立状态,而地震雷需要下蹲(并不需要蹲防…

阅读更多 →
真实废弃物图像分类:4800张标注数据实战与避坑指南 2026/9/28 2:14:13

真实废弃物图像分类:4800张标注数据实战与避坑指南

简介:这份生活中真实废弃物图像分类数据集面向计算机视觉初学者与图像分类、分割方向的算法实践者,用于解决垃圾分类场景下真实样本获取难、标注成本高的问题。数据已完成预处理,可直接作为分类网络输入,覆盖纸板、食品有机物、玻…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉