uni-app跨端图片保存全攻略:微信小程序与App端实现方案详解
1. 项目概述与核心场景解析最近在做一个社区类应用里面有个高频需求用户看到一张喜欢的图片想一键保存到自己的手机相册里。这个功能听起来简单不就是下载然后存一下吗但真做起来尤其是在uni-app这种跨端框架里你会发现这里面的水还挺深。H5、微信小程序、App每个平台都有自己的“脾气”权限申请、API调用、文件路径处理每一步都可能踩坑。特别是当你的应用里还嵌了web-view需要从网页里把图片“捞”出来保存时情况就更复杂了。我花了些时间把uni-app和H5即5 Appuni-app打包为App时使用的原生能力里实现下载保存图片的几种主流方案都摸了一遍也填平了不少坑。这篇文章就来聊聊怎么在不同场景下稳健地实现这个“下载并保存到相册”的功能让你少走弯路。简单来说这个功能的核心价值在于提升用户体验和内容传播。用户不用再长按图片、选择保存或者面对一堆操作步骤开发者也能通过这个功能促进应用内的UGC内容比如用户生成的图片、海报的二次传播。无论是电商的商品海报、内容社区的精美配图还是工具类应用生成的报告截图这个功能都是刚需。2. 技术方案选型与平台差异分析在动手写代码之前我们必须先搞清楚目标平台。uni-app号称“一套代码编译到多个平台”但涉及到系统级能力时平台差异是无法绕开的。对于“下载并保存到相册”这个需求我们主要面对三个战场H5浏览器环境、各家小程序以微信小程序为主、以及App使用H5 runtime。2.1 各平台能力与限制对比为了让你一目了然我把核心差异和方案整理成了下面这个表格平台/环境下载能力保存到相册能力核心方案关键注意事项H5 (浏览器)通过XMLHttpRequest/fetch或a标签下载受同源策略/CORS限制。无直接API。通常引导用户“长按保存”或调用浏览器下载。对于需要强引导的场景可尝试showSaveFilePickerAPI兼容性极差或将图片转为DataURL引导用户保存。1. 创建隐藏的a标签触发下载。2. 使用Canvas绘制并提示用户保存。3. 后端配合返回Content-Disposition: attachment头。用户体验差无法直接存相册。iOS Safari对Blob URL的支持有历史问题。CORS是最大拦路虎。微信小程序使用wx.downloadFileAPI下载文件到本地临时路径。使用wx.saveImageToPhotosAlbumAPI将临时文件保存到相册。需要用户授权。wx.downloadFile- 获取临时路径 -wx.saveImageToPhotosAlbum。必须处理用户拒绝授权的情况。iOS和Android的临时文件生命周期管理不同。App (H5)使用plus.downloader.createDownload创建下载任务。使用plus.gallery.save将文件保存到系统相册。plus.downloader下载 - 获取本地路径 -plus.gallery.save。需要配置应用权限如Android的存储权限。plus.gallery.save在部分Android机型上可能需要特定路径格式。混合场景 (web-view)web-view内为H5环境使用其自身的下载逻辑。需要通过uni.postMessage与父页面通信将图片数据或网络URL传出由父页面调用上述平台API处理。web-view内捕获图片地址 - 通过通信机制传给uni-app页面 - uni-app页面调用平台API完成下载保存。通信数据量不宜过大避免传Base64大图。需要处理好跨域和页面生命周期。注意上表是宏观方案。实际开发中H5方案基本无法实现“一键保存至相册”我们的重点应放在小程序和App上并妥善处理web-view这个特殊场景。2.2 为什么方案如此分裂这背后是平台安全模型的差异。浏览器沙盒环境限制应用直接访问文件系统以保护用户隐私和安全所以H5能力最弱。微信小程序在微信的沙盒内运行它通过一套申请-授权的机制在用户知情且同意的前提下开放了部分系统能力如相册访问。而App通过H5打包本质上是一个原生应用通过桥接JS Bridge调用操作系统提供的丰富API因此能力最强但同时也需要像所有原生应用一样在安装时或运行时申请对应的权限。理解了这个底层逻辑我们就能明白所谓的“跨端兼容”不是找到一条通用的代码路径而是针对不同平台编写相应的实现代码并通过uni-app的条件编译进行优雅的隔离。这是uni-app开发此类功能的核心思想。3. 核心实现细节与代码拆解接下来我们深入到代码层面看看在微信小程序和AppH5这两个主战场如何一步步实现功能。我会先给出最核心、最通用的代码模板然后逐一解释关键点。3.1 微信小程序端实现在微信小程序中这个过程是标准化的两步走下载到临时文件再从临时文件保存到相册。// 在uniapp页面或组件的methods中 export default { methods: { // 保存网络图片到相册 saveNetImageToAlbum(imageUrl) { // 1. 下载文件 uni.downloadFile({ url: imageUrl, // 网络图片地址 success: (downloadRes) { if (downloadRes.statusCode 200) { // 下载成功临时文件路径在 downloadRes.tempFilePath this.saveTempFileToAlbum(downloadRes.tempFilePath); } else { uni.showToast({ title: 下载失败, icon: none }); } }, fail: (err) { console.error(下载文件失败, err); uni.showToast({ title: 下载失败, icon: none }); } }); }, // 2. 将临时文件保存到相册 saveTempFileToAlbum(tempFilePath) { // 首先检查用户是否已授权 uni.getSetting({ success: (res) { // 检查‘scope.writePhotosAlbum’权限 if (!res.authSetting[scope.writePhotosAlbum]) { // 未授权发起授权请求 uni.authorize({ scope: scope.writePhotosAlbum, success: () { // 授权成功执行保存 this.doSave(tempFilePath); }, fail: (authErr) { // 用户拒绝了授权需要引导用户手动开启 uni.showModal({ title: 提示, content: 需要您授权保存图片到相册是否去设置开启, success: (modalRes) { if (modalRes.confirm) { // 引导用户打开设置页 uni.openSetting(); } } }); } }); } else { // 已授权直接保存 this.doSave(tempFilePath); } }, fail: (settingErr) { uni.showToast({ title: 权限检查失败, icon: none }); } }); }, // 实际执行保存操作 doSave(filePath) { uni.saveImageToPhotosAlbum({ filePath: filePath, success: () { uni.showToast({ title: 图片已保存到相册, icon: success }); }, fail: (saveErr) { console.error(保存到相册失败, saveErr); // 错误码处理 if (saveErr.errCode 2) { uni.showToast({ title: 图片文件不存在或已过期, icon: none }); } else { uni.showToast({ title: 保存失败请重试, icon: none }); } } }); } } }关键点解析与避坑指南临时文件的生命周期downloadFile得到的临时路径仅在当前次小程序启动期间有效。小程序一旦被销毁如长时间切到后台被系统回收这个临时文件就可能被清理。因此切忌存储这个路径供下次启动使用。正确的做法是“即用即下”。授权流程是重中之重用户拒绝授权后再次调用authorize会直接失败。必须使用uni.openSetting()引导用户到小程序设置页手动开启。这个交互流程必须完整否则功能就“死”了。错误处理要细致saveImageToPhotosAlbum的失败回调有errCode。常见错误码2文件不存在3保存失败。根据错误码给出友好提示能极大提升用户体验。图片URL与域名白名单下载的图片域名必须在小程序的downloadFile合法域名配置列表中。在微信开发者工具中可以勾选“不校验合法域名”进行开发调试但上线前必须配置。3.2 App端H5实现在5 App环境下我们使用plus.downloader和plus.gallery这两个核心模块。// 在App端页面中 export default { methods: { // 保存网络图片到相册 (App端) saveNetImageToAlbumInApp(imageUrl) { // 检查并申请存储权限对于Android尤其重要 this.checkAndRequestPermission(() { // 权限获取成功后开始下载 this.downloadFileWithPlus(imageUrl); }); }, // 检查并申请存储权限简化示例实际需按官方文档处理 checkAndRequestPermission(callback) { // 对于Android通常需要在manifest.json中配置权限运行时动态申请。 // 这里是一个简单的提示真实项目应使用plus.android.requestPermissions等API // 由于uni-app对权限封装较好通常直接调用下载保存系统会触发授权。 // 如果保存失败再检查是否是权限问题。 if (callback) callback(); }, // 使用plus.downloader下载 downloadFileWithPlus(url) { // 创建下载任务 const task plus.downloader.createDownload( url, { // 指定文件保存的目录这里用应用私有目录下的downloads文件夹 filename: _downloads/${Date.now()}.jpg // 加时间戳避免重名 }, (download, status) { // 下载完成回调 if (status 200) { // 下载成功download.filename 是保存后的本地路径 this.saveToGalleryWithPlus(download.filename); } else { uni.showToast({ title: 下载失败状态码${status}, icon: none }); } } ); // 开始下载 task.start(); }, // 使用plus.gallery保存到相册 saveToGalleryWithPlus(filePath) { plus.gallery.save( filePath, () { uni.showToast({ title: 图片已成功保存到相册, icon: success }); // 保存成功后可以考虑删除临时下载文件以节省空间可选 // plus.io.resolveLocalFileSystemURL(filePath, (entry) { entry.remove((){}); }); }, (err) { console.error(保存到相册失败, err); uni.showToast({ title: 保存失败 err.message, icon: none }); } ); } } }关键点解析与避坑指南文件保存路径plus.downloader的filename参数支持相对路径。_downloads是应用私有目录下的一个标准目录用于存放下载文件。你不需要关心它的绝对路径。使用时间戳或UUID命名文件可以防止覆盖。Android权限问题这是App端最大的坑。从Android 6.0开始需要动态申请存储权限WRITE_EXTERNAL_STORAGE。虽然plus.gallery.save在某些版本/机型上可能会自动触发系统授权弹窗但最稳妥的做法是在应用启动或使用功能前主动检查并申请权限。可以使用uni.authorize部分封装或直接调用plus.android.requestPermissions原生方法。iOS相册权限iOS同样需要访问相册的权限NSPhotoLibraryAddUsageDescription。必须在项目的manifest.json-App模块配置-Gallery(相册)中勾选此模块并配置对应的隐私描述。否则调用plus.gallery.save会静默失败。路径格式传递给plus.gallery.save的路径必须是本地文件路径如file://开头或_downloads/这样的相对路径。网络URL或Base64字符串是无效的。4. 处理web-view内图片保存的混合场景这是一个进阶但常见的需求你的uni-app页面里嵌入了一个web-view组件里面加载了一个H5页面。现在用户想保存这个H5页面里的某张图片到手机相册。由于web-view是一个隔离的环境uni-app的JS无法直接操作其中的DOM或监听其事件。解决方案是通过uni.postMessage进行父子页面通信。4.1 实现原理与步骤H5子页面当用户点击图片时H5页面通过window.parent.postMessage发送消息给uni-app父页面。消息内容可以包含图片的网络URL。uni-app父页面在web-view组件上绑定message事件监听。收到消息后解析出图片URL然后调用我们前面写好的平台相关方法saveNetImageToAlbum或saveNetImageToAlbumInApp来完成下载和保存。4.2 代码示例uni-app 父页面 (pages/webview-page.vue)template view !-- 监听来自web-view的消息 -- web-view :srch5Url messagehandleWebviewMessage/web-view /view /template script export default { data() { return { h5Url: https://your-h5-domain.com/page.html }; }, methods: { handleWebviewMessage(event) { // event.detail { data: [...] } const messageData event.detail.data[0]; // 获取H5传递的数据 if (messageData messageData.type saveImage) { const imageUrl messageData.url; if (!imageUrl) return; // 根据平台调用不同的保存方法 // #ifdef MP-WEIXIN this.saveNetImageToAlbum(imageUrl); // 调用小程序端方法 // #endif // #ifdef APP-PLUS this.saveNetImageToAlbumInApp(imageUrl); // 调用App端方法 // #endif // #ifdef H5 uni.showModal({ title: 提示, content: 在浏览器中无法直接保存到相册请长按图片选择“保存图像”。, showCancel: false }); // #endif } }, // ... 这里需要放入之前定义的小程序端 saveNetImageToAlbum 和 App端 saveNetImageToAlbumInApp 方法 } } /scriptH5 子页面 (your-h5-page.html 内嵌JS)!DOCTYPE html html body img idtargetImage srchttps://example.com/pic.jpg alt示例图片 stylewidth:300px; script document.getElementById(targetImage).addEventListener(click, function() { const imageUrl this.src; // 关键向uni-app父页面发送消息 if (window.uni window.uni.postMessage) { // 某些环境下可能需要这个API window.uni.postMessage({ type: saveImage, url: imageUrl }); } else if (window.parent window.parent.postMessage) { // 标准通信方式 window.parent.postMessage({ type: saveImage, url: imageUrl }, *); } else { alert(当前环境不支持保存功能); } }); /script /body /html关键点解析与避坑指南通信协议web-view的通信机制在不同平台底层实现不同。上述代码中两种判断window.uni.postMessage和window.parent.postMessage是为了提高兼容性。在微信小程序和App的web-view中通常使用前者。数据大小强烈建议传递图片的网络URL而不是Base64数据。Base64字符串体积巨大比原二进制文件大~33%在跨进程/跨线程通信时可能导致性能问题甚至传递失败。安全性postMessage的第二个参数‘*’表示目标origin可以是任意源。在生产环境中为了安全应该替换为uni-app页面的确切origin但这在web-view场景下较难动态获取需要根据实际情况权衡。H5页面的部署确保H5页面的图片链接支持跨域访问CORS。因为最终是由uni-app或小程序/App去下载这个图片如果图片服务器没有配置正确的CORS头下载会失败。5. 高级技巧、优化与问题排查掌握了基础实现后我们再来看看如何让这个功能更健壮、体验更好。5.1 通用封装与条件编译在实际项目中我们肯定不希望在每个页面都写一大段平台判断代码。最佳实践是将其封装成一个通用的工具函数并利用uni-app的条件编译。// utils/saveImage.js export const saveImageToPhotosAlbum (imageUrl) { return new Promise((resolve, reject) { // #ifdef MP-WEIXIN wxSaveImage(imageUrl).then(resolve).catch(reject); // #endif // #ifdef APP-PLUS appSaveImage(imageUrl).then(resolve).catch(reject); // #endif // #ifdef H5 h5SaveImage(imageUrl).then(resolve).catch(reject); // #endif }); }; // 微信小程序实现 const wxSaveImage (url) { return new Promise((resolve, reject) { uni.downloadFile({ url, success: (dRes) { uni.getSetting({ success: (sRes) { const auth sRes.authSetting; const doSave () { uni.saveImageToPhotosAlbum({ filePath: dRes.tempFilePath, success: resolve, fail: reject }); }; if (auth[scope.writePhotosAlbum]) { doSave(); } else { uni.authorize({ scope: scope.writePhotosAlbum, success: doSave, fail: () reject(new Error(用户未授权)) }); } }, fail: reject }); }, fail: reject }); }); }; // App实现 const appSaveImage (url) { return new Promise((resolve, reject) { // 简化的App端实现实际需加入权限检查 const task plus.downloader.createDownload(url, { filename: _downloads/${Date.now()}.jpg }, (d, status) { if (status 200) { plus.gallery.save(d.filename, resolve, reject); } else { reject(new Error(下载失败状态码${status})); } }); task.start(); }); }; // H5实现模拟实际无法保存到相册 const h5SaveImage (url) { return new Promise((resolve, reject) { // 创建一个隐藏的a标签触发浏览器下载这是H5下最好的体验 const a document.createElement(a); a.href url; a.download url.substring(url.lastIndexOf(/) 1) || download; document.body.appendChild(a); a.click(); document.body.removeChild(a); // 无法得知是否成功这里模拟成功或引导用户 resolve({ msg: 已触发浏览器下载 }); }); };然后在页面中你只需要一行清晰的调用import { saveImageToPhotosAlbum } from /utils/saveImage.js; // ... async onSaveButtonClick() { uni.showLoading({ title: 保存中 }); try { await saveImageToPhotosAlbum(this.imageUrl); uni.hideLoading(); uni.showToast({ title: 保存成功, icon: success }); } catch (error) { uni.hideLoading(); uni.showToast({ title: 保存失败: ${error.message}, icon: none }); } }5.2 常见问题排查清单当你遇到保存失败时可以按照这个清单从上到下逐一排查现象可能原因排查步骤与解决方案微信小程序保存按钮点击无反应或直接失败1. 图片URL域名未加入小程序后台的downloadFile合法域名列表。2. 用户首次使用授权弹窗被拦截或拒绝后未处理。3. 临时文件失效。1. 登录微信公众平台在“开发管理”-“开发设置”-“服务器域名”中配置downloadFile合法域名。2. 在开发者工具中勾选“不校验合法域名”进行调试。检查代码授权逻辑是否完整见3.1节。3. 确保下载和保存是连续操作不要存储tempFilePath。微信小程序保存成功但相册里找不到1. 保存到了手机特定的“小程序相册”或文件夹某些Android机型。2. 系统相册更新有延迟。1. 这是正常现象告知用户去“所有相册”或“微信专有文件夹”查找。2. 提示用户稍等片刻或刷新相册。App (Android)调用plus.gallery.save无任何反应1. 未申请存储权限Android 6.0。2.manifest.json中未正确配置Android权限。1. 在App首次启动或使用功能前动态申请android.permission.WRITE_EXTERNAL_STORAGE权限。2. 检查HBuilderX中项目的manifest.json确保已勾选所需权限。App (iOS)保存失败控制台无明确错误1. 未在manifest.json中配置相册权限描述。2. 未勾选Gallery(相册)模块。1. 打开manifest.json - “App模块配置” - 勾选“Gallery(相册)”。2. 在“App权限配置” - iOS隐私信息访问描述中配置NSPhotoLibraryAddUsageDescription描述语如“保存图片到您的相册”。App下载成功但保存时提示“文件不存在”传递给plus.gallery.save的文件路径不正确或文件已被移动/删除。1. 检查plus.downloader回调中download.filename的路径是否正确。2. 确保在下载完成后立即进行保存操作避免文件被系统清理。3. 打印出文件路径使用plus.ioAPI检查文件是否存在。web-view场景父页面收不到H5的消息1. H5页面使用的postMessageAPI不对。2.web-view的message事件未绑定或绑定时机不对。3. 跨域问题。1. 在H5页面中尝试同时使用window.uni.postMessage和window.parent.postMessage。2. 确保web-view组件在页面加载时就渲染并绑定了事件。3. 检查H5页面是否运行在web-view预期的源上。所有平台下载进度与用户体验网络图片过大下载过程无反馈用户可能误以为卡死。添加下载进度提示。小程序可用downloadFile的progress回调App端plus.downloader的Download对象有addEventListener可监听statechanged事件来获取进度。使用uni.showLoading或自定义进度条。5.3 性能与体验优化建议图片压缩与CDN在保存前如果图片原图过大可以考虑让服务端提供不同尺寸的图片或在前端使用Canvas进行有损压缩注意性能。将图片放在CDN上能显著提升下载速度。缓存策略对于可能被重复保存的图片如用户头像、固定海报可以在下载成功后将文件路径缓存在本地存储如uni.setStorageSync。下次保存时先检查缓存避免重复下载。但要注意小程序临时文件的生命周期缓存的路径可能失效所以缓存最好只作为短期优化。批量保存如果需要保存多张图片切勿使用for循环直接连续调用API。这可能导致权限弹窗重叠、网络请求过多等问题。应该设计队列一张一张顺序处理并给出明确的整体进度提示。备用方案在H5环境当直接保存不可行时可以提供“生成保存图片指引”的功能。例如用Canvas将图片和文字“长按保存”合成一张新图引导用户操作。实现一个健壮的“下载保存到相册”功能远不止调用几个API那么简单。它要求开发者深刻理解各平台的安全模型、权限体系和文件系统规则。从方案选型、代码封装到异常处理、用户体验优化每一步都需要仔细斟酌。希望这篇结合了原理、代码和大量实战经验的文章能帮你下次遇到这个需求时从容不迫一步到位。

相关新闻

HPM6750 GPIO中断实战:从轮询到中断的效率跃迁与配置详解

HPM6750 GPIO中断实战:从轮询到中断的效率跃迁与配置详解

1. 项目概述:从按键到中断,嵌入式开发的效率跃迁在嵌入式开发里,GPIO(通用输入输出)口是我们与物理世界交互最直接的桥梁。无论是读取一个按键的状态,还是控制一个LED的亮灭,都离不开它。然而&a…

2026/8/6 14:24:02 阅读更多 →
从器件物理到工程实践:构建半导体器件设计的核心知识体系

从器件物理到工程实践:构建半导体器件设计的核心知识体系

1. 从“提纲”到“地图”:为什么你需要一份自己的器件工程复习指南 又到了期末或者项目评审前的复习季,面对“器件工程设计及应用”这门课,你是不是感觉知识点又多又杂,从半导体物理到工艺集成,从版图设计到可靠性评估…

2026/8/6 14:23:01 阅读更多 →
告别Windows内存卡顿:用Mem Reduct实时清理系统内存的终极指南

告别Windows内存卡顿:用Mem Reduct实时清理系统内存的终极指南

告别Windows内存卡顿:用Mem Reduct实时清理系统内存的终极指南 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitcode.com/gh_mirrors/me/memreduct…

2026/8/6 14:23:01 阅读更多 →

最新新闻

微信小程序数据可视化终极指南:3分钟掌握ECharts图表开发

微信小程序数据可视化终极指南:3分钟掌握ECharts图表开发

微信小程序数据可视化终极指南:3分钟掌握ECharts图表开发 【免费下载链接】echarts-for-weixin 基于 Apache ECharts 的微信小程序图表库 项目地址: https://gitcode.com/gh_mirrors/ec/echarts-for-weixin 还在为微信小程序中的数据展示而烦恼吗&#xff1f…

2026/8/6 15:25:40 阅读更多 →
嵌入式开发中的定点数运算:Q格式解析与加法实战指南

嵌入式开发中的定点数运算:Q格式解析与加法实战指南

1. 项目概述:从浮点到定点的思维转换在嵌入式开发、数字信号处理(DSP)或者一些对计算效率要求极高的场景里,我们常常会听到“定点数”这个词。你可能已经习惯了在PC上用float或double进行各种数学运算,觉得这理所当然。…

2026/8/6 15:25:40 阅读更多 →
国产数据库能跑起来,还不等于企业能用好:从迁移适配到长期数据能力建设

国产数据库能跑起来,还不等于企业能用好:从迁移适配到长期数据能力建设

国产数据库能跑起来,还不等于企业能用好:从迁移适配到长期数据能力建设在企业数字化建设和国产化适配过程中,国产数据库正在成为越来越多企业数据系统建设中的重要选项。从系统安全、自主可控、长期稳定和技术体系演进角度看,数据…

2026/8/6 15:25:40 阅读更多 →
孤能子视角:观察符投射论——从“潜在”到“显在”的相变:观察符如何切割关系场

孤能子视角:观察符投射论——从“潜在”到“显在”的相变:观察符如何切割关系场

(在以下的与AI互动中,在EIS理论约束下,DeepSeek叫信兄,Kim叫酷兄,我呢叫水兄。一般流程:信兄(酷兄)起头 → 酷兄(信兄)校准 → ima外部审视 → 水兄终裁发布。姑且当科幻小说看) (已由信兄整理成文)孤能子视角:观察符投…

2026/8/6 15:25:40 阅读更多 →
2026年5个企业级AI助手平台开源软件测评:从能力与场景匹配度看选型

2026年5个企业级AI助手平台开源软件测评:从能力与场景匹配度看选型

企业将大模型用于内部问答、客服辅助和业务流程时,通常需要同时处理模型接入、知识沉淀、检索质量、权限与部署维护等问题。开源企业级 AI 助手平台的选型,不能只看对话界面或模型数量,还应结合知识库加工方式、工作流能力、既有系统集成方式…

2026/8/6 15:25:40 阅读更多 →
Notepad--:国产跨平台文本编辑器的终极实战指南

Notepad--:国产跨平台文本编辑器的终极实战指南

Notepad--:国产跨平台文本编辑器的终极实战指南 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器,目标是做中国人自己的编辑器,来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad-- 在代码编辑…

2026/8/6 15:24:39 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →