用Canvas原生API手写弹珠游戏:物理模拟与碰撞检测全解析
用Canvas写一个弹珠游戏是很多前端开发者入坑游戏开发的第一站。我去年在个人项目里也做了一版从最开始的画一个圆、让它动起来到最后加了弹簧蓄力、挡板碰撞、连击得分踩了不少坑。这篇就把整个实现思路和关键细节完整梳理一遍如果你正准备动手做类似的小游戏可以直接照着思路去写能少走不少弯路。先说清楚这篇在聊什么全程用原生Canvas API实现不用游戏引擎不碰那些现成物理库弹珠的运动、碰撞、反弹全由我们自己写的数学逻辑驱动。听起来很难实际上核心计算就三部分——重力、速度、碰撞后的方向修正。搞清楚这三件事一个能玩的弹珠台就已经完成了七八成。1. 弹珠游戏的Canvas实现目标与整体设计1.1 为什么选原生Canvas而不是游戏引擎我之前也试过用现成的物理引擎比如某个2D物理库去跑弹珠几行代码就能模拟重力、碰撞、摩擦效果确实逼真。但用在弹珠游戏上有几个绕不开的问题。第一通用物理引擎算的是完全刚体动力学弹珠台里大量使用的弧形轨道、圆形触发器、多段反弹边界在引擎里需要一个个拼碰撞体配置成本比手写高得多。第二引擎自带的物理步进和渲染循环有自己的节奏想要精确控制“球到某个区域触发计分”“球碰到挡板时赋予一个特定方向的力”要么得往引擎内部塞逻辑要么得反复查API远不如自己掌控循环来得顺手。弹珠游戏的物理特性非常固定一个简单的重力加速度、圆形碰撞体、几个矩形或圆弧边界、一个挡板碰撞时给球的冲量。这些内容手写一个轻量物理层工作量在两三百行以内而且每一步计算我们心里都有数出了问题直接在代码里定位不需要去查引擎文档。所以我最终的选型是纯Canvas API做渲染自己写一个极简物理模块游戏逻辑和渲染逻辑完全分开。这个分工在项目后期帮了大忙后面加连击加分、特效提示时基本上没影响到物理计算部分。1.2 弹珠台的玩法设定和循环结构弹珠台的核心玩法说起来并不复杂玩家按下弹簧蓄力松手发射弹珠弹珠在台面上靠重力下落撞击挡板、圈圈叉叉之类的得分点最后如果从底部漏出去这一局就算结束。我给自己定的需求有以下几条一台宽400、高700的竖向Canvas模拟弹珠台面板。左右两侧各一个挡板玩家按键控制挡板向上拍击弹珠。底部一个弹簧蓄力条按住蓄力、松开发射。台面上分布若干得分触发器弹珠碰一次得10分连续碰不同触发器有连击加成。弹珠漏出底边后重置等下一轮发射。这个结构其实是最简版本但已经能覆盖Canvas游戏开发中的绝大多数典型问题运动物体的连续更新、碰撞检测与响应、输入控制、状态切换、计分UI。把这些吃透了后面往里面加资产、加多关卡都是同一套思路的延伸。1.3 代码目录怎么组织不混乱我的项目文件结构是这样的src/ main.js —— 入口创建Canvas启动游戏循环 physics.js —— 弹珠的物理更新、碰撞检测与反弹计算 render.js —— 所有绘图逻辑按层绘制 input.js —— 键盘/触屏事件监听 game.js —— 状态机、计分逻辑、触发器管理不建议把所有代码堆在一个文件里尤其是物理计算和渲染绘制很容易越写越乱。我当时第一版就是把物理和绘制混在一起写指针数据、颜色、位置全在一个大循环里结果每次调参数都要小心翼翼后来痛下决心拆成独立模块代码清晰度立刻不一样了。2. 物理建模让弹珠的运动看起来“对味”2.1 坐标系、速度和重力的基础设置Canvas坐标系是左上角为原点、x向右、y向下。这意味着重力加速度是正值y方向增加和我们在数学课上学到的直角坐标系是反的。这个方向问题别看小写代码时不注意最后弹珠会往上飞。弹珠在每一帧的运动状态用四个基本量描述x、y圆心坐标vx、vy水平和垂直方向的速度分量半径 r碰撞检测用的圆形边界每帧的运动更新公式// 每帧执行一次deltaTime是距上一帧的时间差 ball.vy GRAVITY * deltaTime; ball.x ball.vx * deltaTime; ball.y ball.vy * deltaTime;这里的重力加速度我用了每平方秒600单位是像素。这个值不是从物理课本抄的而是反复调出来的——太小弹珠飘太大弹珠一下子冲到台底根本来不及反应。600这个数值在400x700的Canvas台面上下落节奏和真实弹珠台的视觉感受比较接近。deltaTime的存在非常关键它让游戏在不同刷新率的屏幕上表现一致。60Hz屏幕每帧约16.7毫秒144Hz屏幕每帧约7毫秒如果不乘这个时间差144Hz屏幕上弹珠速度会快一倍游戏直接失衡。2.2 弹珠和边界的碰撞检测圆与矩形的碰撞弹珠台上的边界比如侧墙、底沿、挡板全部抽象成矩形弹珠抽象成圆。圆和矩形的碰撞检测有一个非常简洁的做法把圆心往矩形内部投影找矩形的最近点然后算圆心到这个最近点的距离如果距离小于半径就说明碰到了。function collideCircleRect(circle, rect) { // 找到矩形上离圆心最近的点 let closestX Math.max(rect.x, Math.min(circle.x, rect.x rect.width)); let closestY Math.max(rect.y, Math.min(circle.y, rect.y rect.height)); let dx circle.x - closestX; let dy circle.y - closestY; let distance Math.sqrt(dx * dx dy * dy); if (distance circle.r) { // 碰撞了计算碰撞法线方向从最近点指向圆心 let nx dx / distance; let ny dy / distance; return { hit: true, nx, ny }; } return { hit: false }; }这个思路在大部分矩形碰撞场景里都够用关键优势是代码量少、逻辑直观。注意一个边界情况当圆心完全在矩形内部时distance会算成0这时直接除以0会得到NaN。我的处理办法是在返回前判断一下如果距离为0就随机取一个反弹方向这种情况在弹珠游戏里几乎不会出现弹珠足够小但防御性判断不写的话等它真出现一次就不好收拾了。2.3 碰撞响应反弹方向和能量损失碰撞后弹珠怎么弹出去是影响手感的决定性因素。我的做法是根据碰撞法线方向计算反弹速度同时乘一个恢复系数模拟碰撞过程中的能量损失。// 速度沿法线方向的投影 let dot ball.vx * nx ball.vy * ny; // 如果dot小于0说明弹珠正在朝碰撞面方向移动才需要反弹 if (dot 0) { ball.vx ball.vx - (1 restitution) * dot * nx; ball.vy ball.vy - (1 restitution) * dot * ny; }这里的restitution恢复系数我设置在0.7到0.85之间。越大弹珠弹得越高越接近理想弹性碰撞越小能量损失越多球的运动越“肉”。弹珠台的真实手感介于两者之间0.75左右更合适能让弹珠台面上的活动时间够长又不至于半天停不下来。摩擦力的模拟我没有单独做一套库仑摩擦模型而是用了最简单的方式每次碰撞后将弹珠的速度乘以一个小于1的系数比如0.995模拟滑动过程中的持续阻力。再叠加一个很小的线性阻尼速度越快阻力越大这样弹珠在台面上滚动的感觉更自然。弹珠真实感的关键其实不是碰撞有多精确而是碰撞后会不会出现“黏墙”现象。如果弹珠碰到边界后没有及时弹开或者反弹距离小于每帧的运动步进弹珠就会贴在墙上来回抖动。针对这个问题我的处理手段是碰撞响应之后直接把弹珠的位置推出到边界表面之外确保下一帧计算时它已经和边界分离。// 推出去把弹珠沿法线方向移动直到刚好不再重叠 ball.x closestX nx * (circle.r 0.1); ball.y closestY ny * (circle.r 0.1);这0.1像素的微小余量基本杜绝了下一帧因为浮点误差再次进入重叠状态的尴尬情况。3. 主循环与绘制流程让游戏跑起来的基本架子3.1 requestAnimationFrame的主循环怎么写小程序游戏、浏览器页面游戏主循环的骨架非常固定就是requestAnimationFrame重复回调自己。let lastTime 0; function gameLoop(timestamp) { let deltaTime (timestamp - lastTime) / 1000; if (deltaTime 0.05) { // 防止切后台后回来deltaTime过大导致位移暴走 deltaTime 0.05; } lastTime timestamp; update(deltaTime); render(); requestAnimationFrame(gameLoop); } requestAnimationFrame(gameLoop);对deltaTime做上限钳制这件事是坑过我才加的。曾经有一版没做这个处理切到别的页面一会儿再切回来弹珠直接以一个不可描述的速度飞出屏幕因为中间那几秒钟全部被当作一帧算了。现在每次超过50毫秒就按50毫秒算虽然意味着切后台那段时间在游戏里是“暂停”的但总比弹珠飞出地球要合理得多。3.2 绘制分层先画背景再画游戏元素绘制顺序直接叠加在同一个Canvas上先画的内容会被后画的覆盖。所以我的绘制顺序是台面底板深色背景加几条装饰线纹。得分触发器画成实心圆环或半透明圆弧触发后闪烁高亮。弹簧发射轨道底部竖着的蓄力条。弹珠本身带一圈高光模拟钢珠质感。左右挡板画成斜置的圆弧形短棒。分数等UI最上层保证不被游戏元素遮挡。弹珠的质感值得花点功夫。纯画一个实心圆会显得很扁平我的做法是画一个径向渐变圆亮部偏向左上方暗部在右下再画一个白色小半圆模拟高光。这样弹珠滚动起来会有轻微的光泽变化视觉上一下子从“测试代码”升级到“能拿得出手的Demo”。function drawBall(ctx, ball) { let gradient ctx.createRadialGradient( ball.x - ball.r * 0.3, ball.y - ball.r * 0.3, ball.r * 0.1, ball.x, ball.y, ball.r ); gradient.addColorStop(0, #f5f5f5); gradient.addColorStop(0.5, #c0c0c0); gradient.addColorStop(1, #666666); ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2); ctx.fillStyle gradient; ctx.fill(); }3.3 为什么渲染和物理更新要分开主循环里的update和render两个函数我强制自己写成互不访问内部状态的模块。update只负责修改模型数据弹珠的位置、速度、触发器状态等render只负责读取这些数据并绘制。好处是在排查bug时非常明显画面不对先想想是数据算错了还是绘制画错了。比如弹珠有时在墙上抖动我先去physics里加日志看位置数据如果数据正常无抖动那问题就在绘制层反之就是物理计算有问题。混在一起写的话每次排查都要同时考虑两边效率至少慢一半。4. 游戏机制的实现从能跑起来到“能玩”4.1 弹簧蓄力与发射一个简单却关键的交互底部弹簧的交互逻辑很清晰按住空格或触摸底部区域蓄力松开时根据蓄力的力度给弹珠一个向上的初速度。蓄力的力度我用一个progress变量来记录按着的时候持续增加上限设为一个百分数。蓄力力度和弹珠的初速度之间做一次简单的线性换算const MAX_CHARGE 1.0; const MAX_LAUNCH_SPEED 800; function launch() { let speed MAX_LAUNCH_SPEED * ball.charge; ball.vx 0; ball.vy -speed; // 负值是因为Canvas的y轴向下 }蓄力过程中的视觉反馈很重要我画了一个从底部向上伸长的弹簧矩形蓄力越足矩形越高颜色从绿色渐变到红色。这样玩家看到颜色变红就知道蓄力已满不用看代码也能明白交互意图。发射的瞬间要注意弹珠如果还停在底部给个负的垂直速度就对了但如果弹珠已经弹出去此时弹簧还在蓄力发射事件不应生效。我加了状态判断只有弹珠处于“待发射”状态时才响应发射。4.2 挡板控制最影响手感的部分挡板是弹珠台的灵魂。左右两个挡板位置在底部两侧初始状态是朝向斜上方的玩家按键后挡板向上拍一下松开后弹回原位。挡板本质上是一个矩形边框绕着它的底端中心点旋转。碰撞检测时直接把旋转后的矩形四个角算出来再走之前说过的圆与矩形碰撞逻辑。function rotateRectByAngle(cx, cy, width, height, angle) { // 返回旋转后的四个顶点坐标 let corners [ { x: -width / 2, y: -height / 2 }, { x: width / 2, y: -height / 2 }, { x: width / 2, y: height / 2 }, { x: -width / 2, y: height / 2 } ]; return corners.map(p ({ x: cx p.x * Math.cos(angle) - p.y * Math.sin(angle), y: cy p.x * Math.sin(angle) p.y * Math.cos(angle) })); }挡板拍击的瞬间给弹珠额外冲量是弹珠台“爽感”的重要来源。如果只靠碰撞反弹弹珠被挡板碰到后最多是原路轻弹完全无法形成向上猛打的效果。我给挡板设了一个“active”状态当挡板刚从初始角度向目标角度快速旋转时碰撞后再沿挡板法线方向叠加一个向上的额外速度这样弹珠被拍一下就会向高处飞。手感调节的经验挡板的旋转速度不要太快太快了一帧之间挡板可能穿过弹珠而没有触发碰撞。我用的是旋转角度每帧变化约3度在60Hz下正好能保持碰撞检测的连贯性。4.3 触发器与计分系统分值和连击逻辑得分触发器是台面上分布的圆形感应点。弹珠每次碰到就按触发器的编号加分。为了让计分有点层次不同位置的触发器分值不一样角落和难以撞击的区域给高分解比如50分开阔区域给低分10分。连击逻辑我设计成5秒内连续触发不同编号的触发器连击数递增额外加分连击数 * 10。如果5秒内没有新的触发器被触发连击数清零。let combo 0; let comboTimer 0; function hitTrigger(id, score) { // 如果当前连击目标不是这个触发器且不是同时重复触发视为有效连击 if (lastHitId ! id) { combo; lastHitId id; comboTimer 5; totalScore score combo * 10; } }注意重复触发同一个触发器要防止连续得分刷分。弹珠在触发器附近来回蹭的时候如果不加限制分数会瞬间爆炸。我的做法是给每个触发器一个冷却时间同一个触发器被触发后0.5秒内再次接触不产生分数。4.4 游戏状态机待发射、飞行中、结束状态机是整个游戏框架的中枢。我把游戏分为三个状态READY弹珠在弹簧上等待发射。PLAYING弹珠在台面上运动玩家操作挡板。GAME_OVER弹珠从底部漏出展示分数。状态转移的发生点在发射指令READY到PLAYING、弹珠y坐标超过底板高度PLAYING到GAME_OVER、玩家点击重开GAME_OVER到READY。状态机的好处是让逻辑不会互相干扰。比如在READY状态下挡板按了也不该响应在GAME_OVER状态下物理更新可以跳过。如果没有状态机所有逻辑都要靠if去判断当前能不能做代码会迅速变成一团乱麻。5. 常见问题与排查技巧实录5.1 弹珠穿墙步长与物体尺寸的博弈我遇到的第一个严重bug是弹珠高速移动时直接穿过挡板或台面边界。原因很好理解每帧弹珠移动了几十甚至上百像素而挡板厚度只有几个像素上一帧弹珠在墙的前面下一帧已经到了墙的后面碰撞检测自然抓不到。我当时的处理办法有两个层面。第一层是缩小每帧最大位移。做法是在update里把一次物理更新拆成几个小步骤执行每步最多移动弹珠半径的一半function updateBall(ball, deltaTime) { let remainingTime deltaTime; let stepTime 0.008; // 每步8毫秒 while (remainingTime 0) { let dt Math.min(stepTime, remainingTime); applyPhysics(ball, dt); checkCollisions(ball); remainingTime - dt; } }这个“子步进”方案几乎能解决所有高速穿透问题代价是多花一点CPU时间但对弹珠台这种元素数量很少的游戏来说完全可忽略。第二层是对挡板这类关键碰撞体做了特殊处理把挡板的有效碰撞厚度从视觉厚度扩了一圈。这样即使偶尔速度突发过高至少挡板能挡住弹珠不会出现弹珠直接穿过挡板飞出屏幕的致命问题。5.2 deltaTime计算不当造成的行为漂移之前提过切后台导致弹珠暴走的问题还有一个更隐蔽的坑如果你把deltaTime用在多个地方重复叠加位移会越算越大。举个例子在update里先做了ball.vy GRAVITY * deltaTime然后又写了一句ball.y ball.vy * deltaTime如果这两段逻辑被放在两个不同的函数里而其中一处又额外再乘了一次deltaTime那弹珠的加速度就会变成重力的两倍。这类bug排查起来特别难受因为弹珠的运动看起来只是“有点快”不仔细对比根本发现不了。我的经验教训是把deltaTime的统一处理放在主循环的update入口处后面的子函数一律只接收已经算好的位移量不再自行乘时间差。这样从源头上杜绝了重复累加。5.3 弹珠在角落里疯狂抖动弹珠撞进两个矩形边界的夹角处时经常会陷入一种“疯狂抖动”的状态——每一帧都在反复检测碰撞和反弹位置来回跳变肉眼看到的是弹珠在角落里抽搐。抖动根源是反弹后弹珠仍然处在重叠区域下一帧又触发方向相反的碰撞往复循环。我解决这个问题靠两层措施第一碰撞响应后把弹珠推到边界表面之外这个前面提过。第二在同一次碰撞检测循环里一个弹珠对同一个边界最多只处理一次碰撞响应不重复响应同一个碰撞对象。这两条一加抖动问题基本绝迹。如果偶尔还有轻微抖动多半是两块边界几乎平行但留下极小间隙这时候只要把间隙扩大一点就行。5.4 真机性能和Canvas渲染优化Canvas游戏在桌面浏览器里跑得很顺一放到手机端就开始掉帧这是老生常谈了。弹珠台这种场景简单的小游戏最容易出现的性能瓶颈有两个。第一个是每帧都调用了大量不必要的Canvas状态切换。比如绘制多个触发器时每次都重新设置fillStyle、strokeStyle甚至用了阴影效果。Canvas的阴影shadowBlur是性能杀手我在调试动画特效时一旦忘关帧率直接从60掉到30。第二个是Canvas的像素尺寸和设备像素比不匹配。手机屏幕的物理像素是CSS像素的好几倍如果不做适配Canvas默认会按CSS像素大小绘制在高密度屏上就会模糊。我用的是固定逻辑宽高不追求高清屏适配但会手动把Canvas画布尺寸乘以设备像素比并用ctx.scale做整体缩放const dpr window.devicePixelRatio || 1; canvas.width GAME_WIDTH * dpr; canvas.height GAME_HEIGHT * dpr; ctx.scale(dpr, dpr);这样绘制代码里用的还是原来的逻辑坐标但渲染精度已经跟上了屏幕画面锐利很多。代价是GPU负担变大但对弹珠台这种简单场景来说值得。5.5 挡板灵敏度调整不同设备的输入差异键盘按键和触屏点击在响应速度上有本质差异。键盘的keydown事件可以在按下瞬间触发触屏的touch事件理论上也很快但移动设备的浏览器会有轻微的触摸延迟。我在手机端加了touch-action: none样式阻止了浏览器默认的触摸滚动行为并且用pointerdown而不是touchstart来监听事件。pointerdown的好处是鼠标、触摸、手写笔都统一处理不需要为不同设备写两套逻辑。手感调优的另一处是挡板的起始反应不做延迟只要按下就立刻抬板但是拍击效果附加冲量加了一个30毫秒的小延迟这样视觉上挡板往上抬的瞬间弹珠感受到推力的时机更符合人们的预期。6. 还有一些值得升级的方向基础版完成后我留了几个后续想补的内容点如果你想把项目往上再做一步可以参考这些方向。弹珠台最吸引人的其实是灯光和声效。Canvas的绘图能力完全可以模拟舞台灯效果——触发器被点亮时做一圈向外扩散的渐变光环连击时整个台面背景色轻微变亮。还有弹珠滚动时的音效用Web Audio API合成一个低频的滚动噪声碰撞时播放一个短促的撞击声游戏体验会上一个档次。另外挡板和触发器可以加“奖励机制”比如连续触发同一侧三个触发器后台面中部的光圈变成金色弹珠碰到金色光圈获得三倍分数。这类内容从技术上来说并不复杂核心还是对碰撞和状态机的理解但能把游戏从“能玩”带向“有乐趣”。如果你正在做自己的弹珠台Demo最需要记住的建议就三条物理计算和渲染绘制彻底分开、碰撞响应后务必推出重叠区域、deltaTime的钳制和统一处理。把这三条执行到位你的弹珠游戏离一个能拿得出手的作品已经非常近了。

相关新闻

数学专业考证怎么选?BDA与FRM性价比对比全解析

数学专业考证怎么选?BDA与FRM性价比对比全解析

前两天有位读数学专业的学弟来找我,一坐下就问我:学长,身边同学都在考证,我到底该考哪个?他翻着手机给我看,屏幕上是各种考证机构的广告,从数据分析到金融投资,从会计到精算&#xf…

2026/10/17 21:17:25 阅读更多 →
PHP票务系统实战:锁座、下单与支付回调防超卖设计

PHP票务系统实战:锁座、下单与支付回调防超卖设计

简介:这份PHP票务管理系统源码面向有一定PHP基础的开发者与二次开发人员,用于快速搭建活动、赛事、演出等场景的在线售票平台,解决购票、选座、订单与后台管理等核心业务需求。压缩包共约2000个文件,整体25.59MB,以989…

2026/10/17 21:17:25 阅读更多 →
2026降AI工具实测:免费与付费效果差距全解析

2026降AI工具实测:免费与付费效果差距全解析

“降AI工具”这个词,最近在内容创作圈子里出现的频率越来越高了。起因也简单:主流AI检测器越做越强,很多人发现直接拿大模型生成的文章,被检测出AI痕迹的概率相当高。于是,怎么让机器判断“这内容像是人写的”&#xf…

2026/10/17 21:16:24 阅读更多 →

最新新闻

nanodet轻量级目标检测模型实战部署指南

nanodet轻量级目标检测模型实战部署指南

1. 项目概述:为什么一个轻量级目标检测模型值得单独开一模块讲?“第一模块:深度学习轻量级模型nanodet”——这个标题乍看像课程大纲里的普通一节,但如果你在嵌入式视觉、边缘AI部署、移动端算法落地或工业质检一线干过几年&#…

2026/10/17 21:57:58 阅读更多 →
Qt串口控制程控电源:RS232电平、握手与时序实战指南

Qt串口控制程控电源:RS232电平、握手与时序实战指南

简介:这是一份基于Qt框架开发的RS232串口电源控制程序,面向嵌入式系统初学者、电子工程实践者及自动化设备控制开发者,解决实验室/测试场景中对程控电源的远程开关与状态交互需求。项目采用C与Qt构建跨平台GUI应用,通过串口指令实…

2026/10/17 21:57:58 阅读更多 →
UE5 C++实战:CRPG战斗Buff的Duration、Period与Stacking机制

UE5 C++实战:CRPG战斗Buff的Duration、Period与Stacking机制

在CRPG项目的战斗系统里,Buff 是“看起来简单、做起来麻烦”的模块。你可能会想:不就是给角色挂一个状态、持续几秒、再修改变量吗?但真正把 Buff 做成能复用、能叠加、能刷新、能在存档和网络环境下都保持一致的机制时,各种边界问…

2026/10/17 21:57:58 阅读更多 →
Windows 部署 Kronos 金融模型:源码包与 ONNX 推理加速实战

Windows 部署 Kronos 金融模型:源码包与 ONNX 推理加速实战

简介:这份资源面向希望在Windows平台落地金融AI模型的开发者与量化研究者,提供清华团队开源Kronos金融K线基础模型的完整部署源码。Kronos是首个针对金融烛台图的开源基础模型,训练数据覆盖全球45个以上交易所,采用两阶段框架设计…

2026/10/17 21:57:58 阅读更多 →
iOS多平台二进制分发核心:xcframework构建原理与实战

iOS多平台二进制分发核心:xcframework构建原理与实战

1. 项目概述:为什么“构建 xcframework”成了 iOS 开发者绕不开的硬技能 最近在几个技术交流群里,频繁看到有人问:“Xcode 15 下打包 xcframework 总报错,是不是签名出问题了?”“Swift Package 里引用 xcframework 后…

2026/10/17 21:57:58 阅读更多 →
从零打造OpenClaw:18步智能体开发指南(TaoToken统一Key接入版)

从零打造OpenClaw:18步智能体开发指南(TaoToken统一Key接入版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 21:56:57 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →