下载 App

手机端点击位置和特效位置对不上?一个坐标系不匹配的坑

05/1038 浏览开发交流

现象

在做一个点击类游戏时,点击金币会在点击位置弹出 “+100” 的飘字和金币粒子特效。
在 PC 上一切正常,点哪儿特效就出现在哪儿。
但到了手机上,飘字和金币图标总是偏移一段距离——你点左边,特效跑到更左边去了。

排查过程

先理清数据流。
点击事件从 UI 组件的 onPointerDown 回调拿到 event.x, event.y,然后一路传递:
UI onPointerDown(event.x, event.y)
  → GameManager.OnCoinClick(x, y)
    → CoinParticle.Spawn(x, y)      -- NanoVG 绘制金币粒子
    → FloatingText.Show(text, x, y)  -- NanoVG 绘制飘字
中间没有任何坐标转换,直接把 UI 事件的坐标原样传给了 NanoVG 渲染。
看起来很直觉,但问题就出在这里——这两套系统用的不是同一个坐标系。

根因:两套坐标系的换算不一致

UI 系统的事件坐标使用的是基准像素(Base Pixels)。这个值等于:UI 坐标 = 物理像素 / UI.scale
而 NanoVG 渲染使用的是系统逻辑像素,在 nvgBeginFrame 中定义:
local dpr = graphics:GetDPR()
local logW = graphics:GetWidth() / dpr
local logH = graphics:GetHeight() / dpr
nvgBeginFrame(vg_, logW, logH, dpr)
所以 NanoVG 的坐标等于:NanoVG 坐标 = 物理像素 / dpr
关键在于 UI.scale 和 dpr 不一定相等。
项目使用了 UI.Scale.DEFAULT(即 DPR_DENSITY_ADAPTIVE 模式),它的计算逻辑是:
UI.scale = dpr * densityFactor
其中 densityFactor 是一个根据屏幕短边动态调节的系数,在大屏(PC)上等于 1.0,在小屏(手机)上会缩小到 0.625~0.9 左右,目的是让小屏幕上的 UI 元素不要占满整个屏幕。

为什么 PC 上没问题

PC 上 dpr 通常是 1.0,densityFactor 也是 1.0,所以 UI.scale = 1.0 * 1.0 = 1.0。
两个坐标系的除数都是 1.0,结果完全一致。

为什么手机上出问题

假设一台手机 dpr = 3.0,densityFactor = 0.8,那么 UI.scale = 3.0 * 0.8 = 2.4。
你点击了屏幕上物理坐标 (720, 1200) 的位置:
• UI 事件给出的坐标:720 / 2.4 = 300
• NanoVG 期望的坐标:720 / 3.0 = 240
你把 300 传给了期望 240 的渲染系统,特效自然往右下方偏移了。
偏移量就是 densityFactor 带来的差异。

修复

知道了原因,修复就很简单——在把坐标传给 NanoVG 之前,做一次坐标转换:
NanoVG坐标 = UI坐标 × (UI.scale / dpr)
代入上面的例子验证:300 × (2.4 / 3.0) = 300 × 0.8 = 240,完全正确。
实际代码改动只有几行,加在 OnCoinClick 函数开头:
function
GM.OnCoinClick(x, y)
    -- UI 基准像素 → NanoVG 逻辑像素
    local UI = require("urhox-libs/UI")
    local uiScale = UI.GetScale() or 1
    local dpr = graphics:GetDPR()
    local scaleFactor = uiScale / dpr
    if x then x = x * scaleFactor end
    if y then y = y * scaleFactor end
    -- 后续逻辑不变...
end

总结

这个 bug 的本质是:UI 事件系统和 NanoVG 渲染系统各自有一套从物理像素到逻辑像素的换算规则,当两者的缩放因子不同时,直接传递坐标就会产生偏移。
在只有一个 dpr 参与的简单场景(PC、或 scale 恰好等于 dpr)下,问题被掩盖了。
只有当引入了额外的密度适配因子(densityFactor),两个缩放因子产生差异时,偏移才会暴露出来。
记住一个原则:跨系统传递坐标时,永远要确认两边用的是同一个坐标系。
如果不是,就先转换,再传递。
猜你想搜
taptap 制造坐标系不匹配
别再烧积分了!从每次 2000 到每次 50 的血泪经验截图
别再烧积分了!从每次 2000 到每次 50 的血泪经验
适用场景:所有在用 TapTap Code 开发游戏的小白 难度:★☆☆☆☆ 背景最近群里总有人"炫耀"一次操作花了几千积分,说实话这不是值得高兴的事——这是在告诉所有人你的开发方式有根本性问题。我也走过这条弯路,所以来说说怎么改。 积分消耗的本质是什么积分 = AI 处理的 token 数量 = 你发给 AI 的内容 + AI 回给你的内容所以烧积分的本质只有两种: 你让 AI 做了大量无效/重
精华
68 赞
21 回复
01:27
《大二暑假,我用AI做了一款属于自己的游戏》截图
《大二暑假,我用AI做了一款属于自己的游戏》
本人自制游戏现已加入taptap封闭测试(仅适配安卓机型)欢迎大家前来尝试(八月十号可以正式开始游玩) 如果有建议或者bug反馈可以加入qq群928501443 #发现好游戏 #游戏日常 #浅评一下 #今天游戏圈发生了啥
3 赞
03:06
为了不被斩杀,我只能做到这些了截图
为了不被斩杀,我只能做到这些了
之前一直申请不到计划3,之前说太花哨,后面说体量完成度不足,在我一番小作文下,编辑终于给了我解答,什么原生质感,玩家开局体验啥的。 本来计划2也够用,准备以后再优化了,结果计划2赠送的积分要砍半了,学生党实在消费不起,于是只能再冲一波计划3了 从周六中午到现在一天半时间,优化了一遍角色卡,战斗卡,还有抽卡界面,优化了新手教程,该说不说确实比之前要舒服些。 前半部分为新版,后半部分为旧版。 明天再次
33 赞
6 回复
如何提升你游戏中的UI美术水平截图
如何提升你游戏中的UI美术水平
一、请为你的游戏挑选一款合适的字体 很多开发者没有注意到其实UI界面中最重要的元素是字体,一款合适的字体能给整个游戏的界面感官带来蜕变。 请看案例 那么如何挑选适合自己的字体呢? 我总结出了一些小经验可供参考: 黑体:通用 宋体:古风、武侠、修仙 楷体:古风、武侠、修仙 圆体:卡通、动漫、Q版 科技:科幻、未来、电子 顺手分享一个免费可商用字体网站: 当然 如果你不知道自己的游戏适合什么风格
精华
122 赞
44 回复
【游戏上新】商业帝国大亨截图
【游戏上新】商业帝国大亨
无名小卒还是名扬天下。 从临时工到称霸宇宙。 只需点击屏幕,就能获得财富,利用财富购置产业,获取更多财富。
6 赞
4 回复
开发心得-界面布局心得截图
开发心得-界面布局心得
大家好,我正在用 TapTap 制造制作一款2D 治愈林间徒步旅行游戏《徒步荒野》。 我分享一下我的开发心得,希望能有用,下面是一些界面布局的心得。 第一步:定版式、操作 先确定游戏是横版还是竖版、需要哪些操作按钮,敲定整体玩法思路。 我的玩法灵感参考《边境之旅》,主打散步看风景、沿途触发随机事件。 原版是 3D,考虑到自己是新手,选择2D 横版街机式来做,制作更简单、好上手。 第二步:敲定全局美
6 赞
3 回复
2D 等轴测视角:完整理论截图
2D 等轴测视角:完整理论
2D 等轴测视角:完整理论 一、视角的本质 什么是等轴测 人站在高处斜着往下看地面,地面上的方格子不再是正方形,而变成了菱形。这就是等轴测的视觉本质。 俯视(正上方看下去): 等轴测(斜上方看下去): ┌──┬──┬──┐ ◇ ├──┼──┼──┤ ◇ ◇ ├──┼──┼──┤ ◇ ◇ ◇ └──┴──┴──┘ ◇ ◇ ◇ 正方形网格经过旋转 + 压缩,变成了菱形网格。 为什么是 2:1
6 赞
永恒虚空持续开发日记1——关于游戏中的新名词:场频截图
永恒虚空持续开发日记1——关于游戏中的新名词:场频
写在前边:首先感谢TapTap制造版主大大@汪崽 对于作品潜力的肯定,给与了我积分计划二的权限[表情_不好意思]。这边也在加紧开发改进各种功能中,期望尽快给大家带来成熟的版本。[表情_猫咪举手] 大家好,我是永恒虚空的制作人黑猫不详,大家叫我黑猫就好。从今天开始我将以后置开发日记的形式给大家分享我在TapTap制造中制作的游戏永恒虚空的开发过程,新人希望大家多多关照! 今天先给大家介绍我作品中最重
投票
3 赞
「游戏上新」秦王的游戏截图
「游戏上新」秦王的游戏
你是秦王嬴政身边的廷臣。 方士徐福献上一匣【帝王卡牌】,四张凶牌封死命运: 屠戮|淫欲|奢华|征伐 七日死限,必须一一折断卡牌对应的欲望任务。 办不成? 秦王殿上长剑出鞘,君臣性命,顷刻倾覆。 ⚔游戏核心玩法 ▪回合卡牌策略,抉择牵动秦廷朝堂势力 ▪朝堂派系博弈:王权、法家、军功贵族、方士暗流角力 ▪多重结局:功成辅秦王一统,或是任务失败血染咸阳宫 ▪随机事件触发,每一局嬴政的猜忌程度截然
4 赞
2 回复
龙骨编辑器git自取截图
龙骨编辑器git自取
git clone -b 04-分享仓库 (内置公开声明txt务必阅读,内有联系方式) 解决问题如下:哒啦啦能不能正确识别龙骨,对龙骨动画的简单修改。 具体功能说明书可以git后问嗒啦啦,或者直接编辑。 这只是一个开始希望各位大佬可以在这个基础上开发出更实用的工具#游戏日常 #发现好游戏 #游戏杂谈 #
精华
15 赞
5 回复