Documentation
¶
Overview ¶
Package interpolate 提供客户端渲染侧的状态插值与抖动缓冲。
解决的问题:服务器以固定 tick 下发 Delta(如 20Hz/50ms),但客户端渲染跑 60fps。 如果直接"收到就显示",表现为:网络好时 50ms 一跳,网络抖时更不规则。 玩家感知为"卡顿"或"瞬移"。
本包的方案:客户端始终渲染"过去 T 毫秒"的世界状态,在两个已知快照之间做 平滑插值。T 称为"渲染延迟"(render delay / interpolation window),通常 取 2~3 个 tick 间隔(如 100~150ms)。代价是多了固定延迟,但换来丝滑。
三大组件:
- Buffer: 接收服务器快照,按服务器时间戳排序存储;
- Interpolator: 给定"渲染时间",从 Buffer 中找前后两帧做线性插值;
- TimeLine: 客户端本地时钟 → 服务器时间轴的映射(含抖动吸收)。
并发:Buffer 并发安全(网络线程写、渲染线程读);Interpolator/TimeLine 为值或 单线程使用(渲染循环内)。
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Buffer ¶
type Buffer struct {
// contains filtered or unexported fields
}
Buffer 是带抖动吸收的快照缓冲。网络线程 Push,渲染线程 Sample。 并发安全。
type Snapshot ¶
type Snapshot struct {
ID string
X, Y float64
VX, VY float64 // 可选:速度(用于 Hermite 插值或外推)
Angle float64 // 可选:朝向角度
Payload any // 业务扩展字段(不参与插值)
}
Snapshot 表示一个可插值的实体状态快照。
func HermiteSnapshot ¶
HermiteSnapshot 三次 Hermite 插值(使用速度作为切线)。t∈[0,1]。 dt 为两帧时间间隔(秒),用于将速度转为位移量级。
func InterpolateFrame ¶
InterpolateFrame 对两帧做全实体线性插值。t∈[0,1]。 只对两帧中都存在的实体做插值;仅在 after 中出现的直接取 after;仅在 before 中的忽略。
func LerpSnapshot ¶
LerpSnapshot 对两个 Snapshot 做线性插值。t∈[0,1] 时为插值;t>1 时外推。
type TimeLine ¶
type TimeLine struct {
// contains filtered or unexported fields
}
TimeLine 维护客户端本地时钟到服务器时间轴的映射。 核心思路:服务器每个包附带 serverTime,客户端收到后校准偏移量。 渲染时间 = 本地时间 - 偏移量 - renderDelay。
func NewTimeLine ¶
func NewTimeLine(opts ...TimeLineOption) *TimeLine
NewTimeLine 创建时间轴。epoch 为本地起始时间(通常 time.Now())。
func (*TimeLine) OnServerFrame ¶
OnServerFrame 收到服务器帧时调用:用本地收到时间和帧的服务器时间校准偏移。
func (*TimeLine) RenderDelay ¶
RenderDelay 返回当前配置的渲染延迟。
func (*TimeLine) RenderTime ¶
RenderTime 返回当前应渲染的服务器时间(= 本地流逝 - offset - renderDelay)。
func (*TimeLine) SetRenderDelay ¶
SetRenderDelay 动态调整渲染延迟(如根据抖动自适应)。
type TimeLineOption ¶
type TimeLineOption func(*TimeLine)
TimeLineOption 配置 TimeLine。
func WithRenderDelay ¶
func WithRenderDelay(d time.Duration) TimeLineOption
WithRenderDelay 设置渲染延迟(默认 100ms)。