排查plist中offset字段导致的抖动问题

最近遇到一个bug,plist制作的动画,在creator中会抖动,排查定位了很久,最终确定是plist里面offset导致的,花了点时间详细了解了下。

offset的含义

offset的含义: trim透明像素前后,中心点的偏移。

在这篇文章中,有详细介绍offset的计算方式


<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> o f f s e t X = ( t r i m W i d t h / 2 + l e f t ) − o r i g i n W i d t h / 2 offsetX = ( trimWidth/2 + left ) - originWidth/2 </math>offsetX=(trimWidth/2+left)−originWidth/2

化简后:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> o f f s e t X = ( t r i m W i d t h − o r i g i n W i d t h ) / 2 + l e f t offsetX = (trimWidth- originWidth)/2 +left </math>offsetX=(trimWidth−originWidth)/2+left

所以问题的关键就在于trimWidth-originWidth的结果是否能被2整除

大胆假设

在c++里面,假设计算offset的代码如下

c++ 复制代码
int value = (50-1)/2;

因为类型为int,所以不能整除就会被丢弃掉小数,这也是导致出现0.5bug的原因。

制作测试例

基于以上假想设计测试例:图片宽100,从25-78有像素,也就是有53个实际像素 代入公式计算,是肯定会出现小数点的

js 复制代码
(53-100)/2 + 25
  -47   /2 + 25
    -23.5  + 25 = -1.5

TexturePacker的结果

xml 复制代码
<key>frame</key>
<string>{{2,2},{54,100}}</string> // 54
<key>offset</key>
<string>{1,0}</string>
<key>rotated</key>
<false/>
<key>sourceColorRect</key>
<string>{{24,0},{54,100}}</string>// 可以看到是从24开始的读取像素的
<key>sourceSize</key>
<string>{100,100}</string>

CocosStudio的结果

xml 复制代码
<key>frame</key>
<string>{{2,2},{53,100}}</string> // 53
<key>offset</key>
<string>{1,0}</string>
<key>rotated</key>
<false />
<key>sourceSize</key>
<string>{100,100}</string>

结论

我们发现2个不同的软件打包plist,宽度出现了1像素的偏差,这就是导致这个问题的原因,根本原因还是TrimDiff无法被2整除导致的

尽量使用TexturePacker来打包plist,少踩坑!

至于为什么texturePacker将53变为54,可能是为了照顾到offset如果为小数,在解析上会出现性能问题。

大胆猜测:texturePacker当发现trimDiff无法被2整除时,会自动调整尺寸。

cocos creator 会出现这个问题么

我尝试做了一个测试例,并配置了自动图集,构建好后找到合图的信息数据,如下:

json 复制代码
[[{ "name": "img_08", "rect": [111, 222, 87, 87], "offset": [0, 0], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_04", "rect": [3, 403, 48, 47], "offset": [-0.5, 0], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_17", "rect": [188, 76, 64, 64], "offset": [-0.5, 0.5], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_11", "rect": [3, 222, 102, 102], "offset": [-0.5, 0.5], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_14", "rect": [75, 388, 66, 66], "offset": [-0.5, -0.5], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_12", "rect": [113, 3, 67, 67], "offset": [0, 0], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_09", "rect": [3, 3, 104, 104], "offset": [-0.5, 0.5], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]],
[[{ "name": "img_06", "rect": [183, 315, 66, 67], "offset": [-0.5, 0], "originalSize": [231, 231], "capInsets": [0, 0, 0, 0] }], [0], 0, [0], [0], [0]]

发现offset0.5的情况,验证后和rect.width - originalSize.width不能被2整除的结论是正确的,很显然creator是能够正常处理好这种问题的。

相关推荐
奇迹_h14 分钟前
打造你的HTML5打地鼠游戏:零基础入门实践
前端
SuperEugene17 分钟前
Vue生态精选篇:Element Plus 的“企业后台常用组件”用法扫盲
前端·vue.js·面试
Neptune120 分钟前
JavaScript回归基本功之---类型判断--typeof篇
前端·javascript·面试
贾铭21 分钟前
如何实现一个网页版的剪映(三)使用fabric.js绘制时间轴
前端·后端
子兮曰2 小时前
后端字段又改了?我撸了一个 BFF 数据适配器,从此再也不怕接口“屎山”!
前端·javascript·架构
万少3 小时前
使用Trae轻松安装openclaw的教程-附带免费token
前端·openai·ai编程
浪浪山_大橙子4 小时前
OpenClaw 十分钟快速,安装与接入完全指南 - 推荐使用trae 官方 skills 安装
前端·人工智能
忆江南4 小时前
iOS 可视化埋点与无痕埋点详解
前端
离开地球表面_994 小时前
金三银四程序员跳槽指南:从简历到面试再到 Offer 的全流程准备
前端·后端·面试
_柳青杨4 小时前
跨域获取 iframe 选中文本?自己写个代理中间层,再也不求后端!
前端